Version 2.17.0-182.1.beta

Merge '2.17.0-182.0.dev' into beta
diff --git a/.dart_tool/OWNERS b/.dart_tool/OWNERS
new file mode 100644
index 0000000..d52dde4
--- /dev/null
+++ b/.dart_tool/OWNERS
@@ -0,0 +1,2 @@
+# Generated file
+per-file package_config.json=*
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index e47664f..51bc8f5 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,6 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2022-01-12T18:16:46.198227",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -136,7 +135,7 @@
       "name": "boolean_selector",
       "rootUri": "../third_party/pkg/boolean_selector",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.12"
     },
     {
       "name": "browser_launcher",
@@ -172,7 +171,7 @@
       "name": "clock",
       "rootUri": "../third_party/pkg/clock",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.12"
     },
     {
       "name": "collection",
@@ -229,6 +228,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "dart2wasm",
+      "rootUri": "../pkg/dart2wasm",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "dart_internal",
       "rootUri": "../pkg/dart_internal",
       "packageUri": "lib/",
@@ -271,24 +276,12 @@
       "languageVersion": "2.15"
     },
     {
-      "name": "devtools_server",
-      "rootUri": "../third_party/devtools/devtools_server",
-      "packageUri": "lib/",
-      "languageVersion": "2.12"
-    },
-    {
       "name": "devtools_shared",
       "rootUri": "../third_party/devtools/devtools_shared",
       "packageUri": "lib/",
       "languageVersion": "2.12"
     },
     {
-      "name": "diagnostic",
-      "rootUri": "../pkg/diagnostic",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "expect",
       "rootUri": "../pkg/expect",
       "packageUri": "lib/",
@@ -310,7 +303,7 @@
       "name": "file_testing",
       "rootUri": "../third_party/pkg/file/packages/file_testing",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.12"
     },
     {
       "name": "fixnum",
@@ -345,7 +338,7 @@
       "name": "glob",
       "rootUri": "../third_party/pkg/glob",
       "packageUri": "lib/",
-      "languageVersion": "2.12"
+      "languageVersion": "2.15"
     },
     {
       "name": "html",
@@ -623,7 +616,7 @@
       "name": "source_map_stack_trace",
       "rootUri": "../third_party/pkg/source_map_stack_trace",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.12"
     },
     {
       "name": "source_maps",
@@ -671,7 +664,7 @@
       "name": "string_scanner",
       "rootUri": "../third_party/pkg/string_scanner",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.12"
     },
     {
       "name": "sync_http",
@@ -689,7 +682,7 @@
       "name": "term_glyph",
       "rootUri": "../third_party/pkg/term_glyph",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.12"
     },
     {
       "name": "test",
@@ -760,7 +753,7 @@
       "name": "vector_math",
       "rootUri": "../third_party/pkg/vector_math",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.14"
     },
     {
       "name": "vm",
@@ -781,6 +774,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "wasm_builder",
+      "rootUri": "../pkg/wasm_builder",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "watcher",
       "rootUri": "../third_party/pkg/watcher",
       "packageUri": "lib/",
diff --git a/.github/OWNERS b/.github/OWNERS
new file mode 100644
index 0000000..12997a6
--- /dev/null
+++ b/.github/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_PRODUCT
+file:/tools/OWNERS_INFRA
diff --git a/.packages b/.packages
index e8855d6..646a631 100644
--- a/.packages
+++ b/.packages
@@ -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.
 #
-# .package file containing links to all packages in /pkg, and checked out
-# by DEPS into /third_party/pkg and /third_party/pkg_tested.
-# Please update this file if you add a package to DEPS or /pkg
-#
+# This file is generated; do not edit. To re-generate, run:
+#   'dart tools/generate_package_config.dart'.
+
 _fe_analyzer_shared:pkg/_fe_analyzer_shared/lib
 _js_interop_checks:pkg/_js_interop_checks/lib
 analysis_server:pkg/analysis_server/lib
@@ -20,10 +19,12 @@
 bazel_worker:third_party/pkg/bazel_worker/lib
 benchmark_harness:third_party/pkg/benchmark_harness/lib
 boolean_selector:third_party/pkg/boolean_selector/lib
-build_integration:pkg/build_integration/lib
 browser_launcher:third_party/pkg/browser_launcher/lib
+build_integration:pkg/build_integration/lib
+characters:third_party/pkg/characters/lib
 charcode:third_party/pkg/charcode/lib
 cli_util:third_party/pkg/cli_util/lib
+clock:third_party/pkg/clock/lib
 collection:third_party/pkg/collection/lib
 compiler:pkg/compiler/lib
 convert:third_party/pkg/convert/lib
@@ -33,6 +34,7 @@
 dart2js_runtime_metrics:pkg/dart2js_runtime_metrics/lib
 dart2js_tools:pkg/dart2js_tools/lib
 dart2native:pkg/dart2native/lib
+dart2wasm:pkg/dart2wasm/lib
 dart_internal:pkg/dart_internal/lib
 dart_style:third_party/pkg_tested/dart_style/lib
 dartdev:pkg/dartdev/lib
@@ -40,14 +42,15 @@
 dds:pkg/dds/lib
 dds_service_extensions:pkg/dds_service_extensions/lib
 dev_compiler:pkg/dev_compiler/lib
-devtools_server:third_party/devtools/devtools_server/lib
 devtools_shared:third_party/devtools/devtools_shared/lib
-diagnostic:pkg/diagnostic/lib
 expect:pkg/expect/lib
 ffi:third_party/pkg/ffi/lib
+file:third_party/pkg/file/packages/file/lib
+file_testing:third_party/pkg/file/packages/file_testing/lib
 fixnum:third_party/pkg/fixnum/lib
-frontend_server:pkg/frontend_server/lib
 front_end:pkg/front_end/lib
+frontend_server:pkg/frontend_server/lib
+frontend_server_client:third_party/pkg/webdev/frontend_server_client/lib
 glob:third_party/pkg/glob/lib
 html:third_party/pkg/html/lib
 http:third_party/pkg/http/lib
@@ -73,7 +76,7 @@
 nnbd_migration:pkg/nnbd_migration/lib
 oauth2:third_party/pkg/oauth2/lib
 observatory:runtime/observatory/lib
-observatory_test_package:runtime/observatory/tests/service/observatory_test_package
+observatory_2:runtime/observatory_2/lib
 package_config:third_party/pkg_tested/package_config/lib
 path:third_party/pkg/path/lib
 pedantic:third_party/pkg/pedantic/lib
@@ -83,6 +86,7 @@
 protobuf:third_party/pkg/protobuf/protobuf/lib
 pub:third_party/pkg/pub/lib
 pub_semver:third_party/pkg/pub_semver/lib
+scrape:pkg/scrape/lib
 sdk_library_metadata:sdk/lib/_internal/sdk_library_metadata/lib
 shelf:third_party/pkg/shelf/lib
 shelf_packages_handler:third_party/pkg/shelf_packages_handler/lib
@@ -91,9 +95,9 @@
 shelf_web_socket:third_party/pkg/shelf_web_socket/lib
 smith:pkg/smith/lib
 source_map_stack_trace:third_party/pkg/source_map_stack_trace/lib
-sourcemap_testing:pkg/sourcemap_testing/lib
 source_maps:third_party/pkg/source_maps/lib
 source_span:third_party/pkg/source_span/lib
+sourcemap_testing:pkg/sourcemap_testing/lib
 sse:third_party/pkg/sse/lib
 stack_trace:third_party/pkg/stack_trace/lib
 status_file:pkg/status_file/lib
@@ -106,7 +110,6 @@
 test_api:third_party/pkg/test/pkgs/test_api/lib
 test_core:third_party/pkg/test/pkgs/test_core/lib
 test_descriptor:third_party/pkg/test_descriptor/lib
-test_package:pkg/vm_service/test/test_package
 test_process:third_party/pkg/test_process/lib
 test_reflective_loader:third_party/pkg/test_reflective_loader/lib
 test_runner:pkg/test_runner/lib
@@ -117,9 +120,11 @@
 vm:pkg/vm/lib
 vm_service:pkg/vm_service/lib
 vm_snapshot_analysis:pkg/vm_snapshot_analysis/lib
+wasm_builder:pkg/wasm_builder/lib
 watcher:third_party/pkg/watcher/lib
-webdriver:third_party/pkg/webdriver/lib
-webkit_inspection_protocol:third_party/pkg/webkit_inspection_protocol/lib
 web_components:third_party/pkg/web_components/lib
 web_socket_channel:third_party/pkg/web_socket_channel/lib
+webdriver:third_party/pkg/webdriver/lib
+webkit_inspection_protocol:third_party/pkg/webkit_inspection_protocol/lib
 yaml:third_party/pkg/yaml/lib
+yaml_edit:third_party/pkg/yaml_edit/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ddc529..4a99aaa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,12 +6,27 @@
 
 - Add `Finalizer` and `WeakReference` which can potentially detect when
   objects are "garbage collected".
+- Add `isMimeType` method to `UriData` class, to allow case-insensitive
+  checking of the MIME type.
+- Add `isCharset` and `isEncoding` methods to `UriData` class,
+  to allow case-insensitive and alternative-encoding-name aware checking
+  of the MIME type "charset" parameter.
+- Make `UriData.fromString` and `UriData.fromBytes` recognize and omit
+  a "text/plain" `mimeType` even if it is not all lower-case.
 
 #### `dart:ffi`
 
 - Add `ref=` and `[]=` methods to the `StructPointer` and `UnionPointer`
   extensions. They copy a compound instance into a native memory region.
 
+#### `dart:html`
+
+- Add `scrollIntoViewIfNeeded` to `Element`. Previously, this method was nested
+  within `scrollIntoView` based on the `ScrollAlignment` value. `scrollIntoView`
+  is unchanged for now, but users who intend to use the native
+  `Element.scrollIntoViewIfNeeded` should use the new `scrollIntoViewIfNeeded`
+  definition instead.
+
 #### `dart:indexed_db`
 
 - `IdbFactory.supportsDatabaseNames` has been deprecated. It will always return
@@ -19,36 +34,81 @@
 
 #### `dart:io`
 
-- **Breaking Change** [#45410](https://github.com/dart-lang/sdk/issues/45410):
-  `HttpClient` no longer transmits some headers (i.e. `authorization`,
-  `www-authenticate`, `cookie`, `cookie2`) when processing redirects to
-  a different domain.
+- **Breaking Change** [#47887](https://github.com/dart-lang/sdk/issues/47887):
+  `HttpClient` has a new `connectionFactory` property, which allows socket
+  creation to be customized. Classes that `implement HttpClient` may be broken
+  by this change. Add the following method to your classes to fix them:
+
+  ```dart
+  void set connectionFactory(
+      Future<ConnectionTask<Socket>> Function(
+              Uri url, String? proxyHost, int? proxyPort)?
+          f) =>
+      throw UnsupportedError("connectionFactory not implemented");
+  ```
+
+- **Breaking Change** [#48093](https://github.com/dart-lang/sdk/issues/48093):
+  `HttpClient` has a new `keyLog` property, which allows TLS keys to be logged
+  for debugging purposes. Classes that `implement HttpClient` may be broken by
+  this change. Add the following method to your classes to fix them:
+
+  ```dart
+  void set keyLog(Function(String line)? callback) =>
+      throw UnsupportedError("keyLog not implemented");
+  ```
+
+- Add a optional `keyLog` parameter to `SecureSocket.connect` and
+  `SecureSocket.startConnect`.
+
+- Deprecate `SecureSocket.renegotiate` and `RawSecureSocket.renegotiate`,
+  which were no-ops.
+
+#### `dart:isolate`
+
+- Add `Isolate.run` to run a function in a new isolate.
 
 ### Tools
 
 #### Dart command line
 
-- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
   The standalone `dart2js` tool has been
   marked deprecated as previously announced.
   Its replacement is the `dart compile js` command.
   Should you find any issues, or missing features, in the replacement
   command, kindly file [an issue](https://github.com/dart-lang/sdk/issues/new).
 
-- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
   The standalone `dartdevc` tool has been marked deprecated as previously
   announced and will be deleted in a future Dart stable relase.  This tool
   was intended for use only by build systems like bazel, `build_web_compilers`
   and `flutter_tools`. The functionality remains available for those systems,
   but it is no longer exposed as a command-line tool in the SDK.
-  Please share any concerns in the 
+  Please share any concerns in the
   [breaking change tracking issue](https://github.com/dart-lang/sdk/issues/46100).
 
-- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
   The standalone `dartdoc` tool has been removed as
   previously announced. Its replacement is the `dart doc` command.
 
-## 2.16.0
+- The template names used in the `dart create` command have been simplified,
+  and the current template names are now the set shown below. (Note: for
+  backwards compatibility the former template names can still be used.)
+```
+          [console] (default)    A command-line application.
+          [package]              A package containing shared Dart libraries.
+          [server-shelf]         A server app using package:shelf.
+          [web]                  A web app that uses only core Dart libraries.
+```
+
+## 2.16.1 - 2022-02-09
+
+This is a patch release that fixes an AOT precompiler crash when building some
+Flutter apps (issue [flutter/flutter#97301][]).
+
+[flutter/flutter#97301]: https://github.com/flutter/flutter/issues/97301
+
+## 2.16.0 - 2022-02-03
 
 ### Core libraries
 
@@ -60,13 +120,18 @@
 
 #### `dart:io`
 
-- **Breaking Change** [#47653](https://github.com/dart-lang/sdk/issues/47653):
-On Windows, `Directory.rename` will no longer delete a directory if
-`newPath` specifies one. Instead, a `FileSystemException` will be thrown.
-
-- **Breaking Change** [#47769](https://github.com/dart-lang/sdk/issues/47769):
-The `Platform.packageRoot` API has been removed. It had been marked deprecated
-in 2018, as it doesn't work with any Dart 2.x release.
+- **Security advisory**
+  [CVE-2022-0451](https://github.com/dart-lang/sdk/security/advisories/GHSA-c8mh-jj22-xg5h),
+  **breaking change** [#45410](https://github.com/dart-lang/sdk/issues/45410):
+  `HttpClient` no longer transmits some headers (i.e. `authorization`,
+  `www-authenticate`, `cookie`, `cookie2`) when processing redirects to a
+  different domain.
+- **Breaking change** [#47653](https://github.com/dart-lang/sdk/issues/47653):
+  On Windows, `Directory.rename` will no longer delete a directory if
+  `newPath` specifies one. Instead, a `FileSystemException` will be thrown.
+- **Breaking change** [#47769](https://github.com/dart-lang/sdk/issues/47769):
+  The `Platform.packageRoot` API has been removed. It had been marked deprecated
+  in 2018, as it doesn't work with any Dart 2.x release.
 - Add optional `sourcePort` parameter to `Socket.connect`, `Socket.startConnect`, `RawSocket.connect` and `RawSocket.startConnect`
 
 - **Breaking Change** [#45410](https://github.com/dart-lang/sdk/issues/45410):
@@ -76,7 +141,7 @@
 
 #### `dart:isolate`
 
-- **Breaking Change** [#47769](https://github.com/dart-lang/sdk/issues/47769):
+- **Breaking change** [#47769](https://github.com/dart-lang/sdk/issues/47769):
 The `Isolate.packageRoot` API has been removed. It had been marked deprecated
 in 2018, as it doesn't work with any Dart 2.x release.
 
@@ -84,7 +149,7 @@
 
 #### Dart command line
 
-- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
   The standalone `dartanalyzer` tool has been
   marked deprecated as previously announced.
   Its replacement is the `dart analyze` command.
@@ -93,7 +158,7 @@
 
 [an issue]: https://github.com/dart-lang/sdk/issues/new
 
-- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
   The standalone `dartdoc` tool has been
   marked deprecated as previously announced.
   Its replacement is the `dart doc` command.
@@ -118,7 +183,7 @@
 Updated the Linter to `1.18.0`, which includes changes that
 
 - extends `camel_case_types` to cover enums.
-- fixes `no_leading_underscores_for_local_identifiers` to not 
+- fixes `no_leading_underscores_for_local_identifiers` to not
   mis-flag field formal parameters with default values.
 - fixes `prefer_function_declarations_over_variables` to not
   mis-flag non-final fields.
@@ -153,6 +218,22 @@
 
 ## 2.15.0 - 2021-12-08
 
+- **Security advisory**
+  [CVE-2021-22567](https://github.com/dart-lang/sdk/security/advisories/GHSA-8pcp-6qc9-rqmv):
+  Bidirectional Unicode text can be interpreted and compiled differently than
+  how it appears in editors and code-review tools. Exploiting this an attacker
+  could embed source that is invisible to a code reviewer but that modifies the
+  behavior of a program in unexpected ways. Dart 2.15.0 introduces new analysis
+  warnings that flags the use of these.
+
+- **Security advisory**
+  [CVE-2021-22568](https://github.com/dart-lang/sdk/security/advisories/GHSA-r32f-vhjp-qhj7):
+  A malicious third-party package repository may impersonate a user on pub.dev
+  for up to one hour after the user has published a package to that third-party
+  package repository using `dart pub publish`. As of Dart SDK version 2.15.0
+  requests to third-party package repositories will no longer include an OAuth2
+  `access_token` intended for pub.dev.
+
 ### Language
 
 The following features are new in the Dart 2.15 [language version][]. To use
@@ -464,7 +545,7 @@
 
 #### `dart:io`
 
-- **Breaking Change** [#46875](https://github.com/dart-lang/sdk/issues/46875):
+- **Breaking change** [#46875](https://github.com/dart-lang/sdk/issues/46875):
   The `SecurityContext` class in `dart:io` has been updated to set the minimum
   TLS protocol version to TLS1_2_VERSION (1.2) instead of TLS1_VERSION.
 - Add `RawSocket.sendMessage`, `RawSocket.receiveMessage` that allow passing of
@@ -481,14 +562,14 @@
 
 #### `dart:web_sql`
 
-- **Breaking Change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
+- **Breaking change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
   The WebSQL standard was abandoned more than 10
   years ago and is not supported by many browsers. This release completely
   deletes the `dart:web_sql` library.
 
 #### `dart:html`
 
-- **Breaking Change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
+- **Breaking change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
   Related to the removal of `dart:web_sql` (see above), `window.openDatabase`
   has been removed.
 
@@ -496,12 +577,12 @@
 
 #### Dart command line
 
-- **Breaking Change** [#46100][]: The standalone `dart2native` tool has been
+- **Breaking change** [#46100][]: The standalone `dart2native` tool has been
   removed as previously announced. Its replacements are the
   `dart compile exe` and `dart compile aot-snapshot` commands, which offer the
   same functionality.
 
-- **Breaking Change**: The standalone `dartfmt` tool has been removed as
+- **Breaking change**: The standalone `dartfmt` tool has been removed as
   previously announced. Its replacement is the `dart format` command.
 
   Note that `dart format` has [a different set of options and
@@ -512,11 +593,11 @@
 
 #### Dart VM
 
-- **Breaking Change** [#45451](https://github.com/dart-lang/sdk/issues/45451):
+- **Breaking change** [#45451](https://github.com/dart-lang/sdk/issues/45451):
   Support for `dart-ext:`-style native extensions has been removed as previously
   announced. Use `dart:ffi` to bind to native libraries instead.
 
-- **Breaking Change** [#46754](https://github.com/dart-lang/sdk/issues/46754):
+- **Breaking change** [#46754](https://github.com/dart-lang/sdk/issues/46754):
   Isolates spawned via the `Isolate.spawn()` API are now grouped, operate on the
   same managed heap and can therefore share various VM-internal data structures.
 
@@ -805,7 +886,7 @@
 
 ### Dart VM
 
-- **Breaking Change** [#45071][]: `Dart_NewWeakPersistentHandle`'s and
+- **Breaking change** [#45071][]: `Dart_NewWeakPersistentHandle`'s and
   `Dart_NewFinalizableHandle`'s `object` parameter no longer accepts `Pointer`s
   and subtypes of `Struct`. Expandos no longer accept `Pointer`s and subtypes of
   `Struct`s.
@@ -816,13 +897,13 @@
 
 #### Dart command line
 
-- **Breaking Change** [#46100][]: The standalone `dart2native` tool has been
+- **Breaking change** [#46100][]: The standalone `dart2native` tool has been
   marked deprecated, and now prints a warning message. Its replacements are the
   `dart compile exe` and `dart compile aot-snapshot` commands, which offer the
   same functionality. The `dart2native` tool will be removed from the Dart SDK
   in Dart 2.15.
 
-- **Breaking Change**: The standalone `dartfmt` tool has been marked deprecated,
+- **Breaking change**: The standalone `dartfmt` tool has been marked deprecated,
   and now prints a warning message. Instead, use `dart format`. The `dartfmt`
   tool will be removed from the Dart SDK in Dart 2.15.
 
@@ -946,7 +1027,7 @@
 
 #### Dart2JS
 
-*   **Breaking Change** [#46545][]: Dart2JS emits ES6+ JavaScript by default,
+*   **Breaking change** [#46545][]: Dart2JS emits ES6+ JavaScript by default,
     thereby no longer supporting legacy browsers. Passing the
     `--legacy-javascript` flag will let you opt out of this update, but this
     flag will be removed in a future release. Modern browsers will not be
@@ -958,7 +1039,7 @@
 
 #### Dart Dev Compiler (DDC)
 
-- **Breaking Change** [#44154][]: Subtyping relations of `package:js` classes
+- **Breaking change** [#44154][]: Subtyping relations of `package:js` classes
   have been changed to be more correct and consistent with Dart2JS.
   Like `anonymous` classes, non-`anonymous` classes will no longer check the
   underlying type in DDC. The internal type representation of these objects have
@@ -1127,10 +1208,10 @@
 
 ## 2.12.3 - 2021-04-14
 
-This is a patch release that fixes a vulnerability in `dart:html` related to DOM
-clobbering. See the [vulnerability advisory][cve-2021-22540] for more details.
-Thanks again to **Vincenzo di Cicco** for finding and reporting this
-vulnerability.
+**Security advisory**: This is a patch release that fixes a vulnerability in
+`dart:html` related to DOM clobbering. See the security advisory
+[CVE-2021-22540][cve-2021-22540] for more details. Thanks again to **Vincenzo di
+Cicco** for finding and reporting this vulnerability.
 
 [cve-2021-22540]:
   https://github.com/dart-lang/sdk/security/advisories/GHSA-3rfv-4jvg-9522
@@ -1156,7 +1237,7 @@
 
 ### Language
 
-- **Breaking Change** [Null safety][] is now enabled by default in all code that
+- **Breaking change** [Null safety][] is now enabled by default in all code that
   has not opted out. With null safety, types in your code are non-nullable by
   default. Null can only flow into parts of your program where you want it. With
   null safety, your runtime null-dereference bugs turn into edit-time analysis
@@ -1176,7 +1257,7 @@
   - The postfix `!` null assertion operator
   - The `?..` and `?[]` null-aware operators
 
-- **Breaking Change** [#44660][]: Fixed an implementation bug where `this` would
+- **Breaking change** [#44660][]: Fixed an implementation bug where `this` would
   sometimes undergo type promotion in extensions.
 
 [null safety]: https://dart.dev/null-safety/understanding-null-safety
@@ -1228,12 +1309,12 @@
 
 ### Dart VM
 
-- **Breaking Change** [#42312][]: `Dart_WeakPersistentHandle`s no longer
+- **Breaking change** [#42312][]: `Dart_WeakPersistentHandle`s no longer
   auto-delete themselves when the referenced object is garbage collected to
   avoid race conditions, but they are still automatically deleted when the
   isolate group shuts down.
 
-- **Breaking Change** [#42312][]: `Dart_WeakPersistentHandleFinalizer` is
+- **Breaking change** [#42312][]: `Dart_WeakPersistentHandleFinalizer` is
   renamed to `Dart_HandleFinalizer` and had its `handle` argument removed. All
   API functions using that type have been updated.
 
@@ -1241,7 +1322,7 @@
 
 ### Foreign Function Interface (`dart:ffi`)
 
-- **Breaking Change** [#44621][]: Invocations with a generic `T` of `sizeOf<T>`,
+- **Breaking change** [#44621][]: Invocations with a generic `T` of `sizeOf<T>`,
   `Pointer<T>.elementAt()`, `Pointer<T extends Struct>.ref`, and
   `Pointer<T extends Struct>[]` are being deprecated in the current stable
   release (2.12), and are planned to be fully removed in the following stable
@@ -1251,7 +1332,7 @@
   constant `T` on invocations. For migration notes see the breaking change
   request.
 
-- **Breaking Change** [#44622][]: Subtypes of `Struct` without any native member
+- **Breaking change** [#44622][]: Subtypes of `Struct` without any native member
   are being deprecated in the current stable release (2.12), and are planned to
   be fully removed in the following stable release (2.13). Migrate opaque types
   to extend `Opaque` rather than `Struct`.
@@ -1533,7 +1614,7 @@
 
 ### Dart VM
 
-- **Breaking Change** [#42982][]: `dart_api_dl.cc` is renamed to `dart_api_dl.c`
+- **Breaking change** [#42982][]: `dart_api_dl.cc` is renamed to `dart_api_dl.c`
   and changed to a pure C file.
 - Introduces `Dart_FinalizableHandle`s. They do auto-delete, and the weakly
   referred object cannot be accessed through them.
@@ -1622,7 +1703,7 @@
 
 #### `dart:convert`
 
-- **Breaking Change** [#41100][]: When encoding a string containing unpaired
+- **Breaking change** [#41100][]: When encoding a string containing unpaired
   surrogates as UTF-8, the unpaired surrogates will be encoded as replacement
   characters (`U+FFFD`). When decoding UTF-8, encoded surrogates will be treated
   as malformed input. When decoding UTF-8 with `allowMalformed: true`, the
@@ -1654,7 +1735,7 @@
 
 #### `dart:html`
 
-- **Breaking Change**: `CssClassSet.add()` previously returned `null` if the
+- **Breaking change**: `CssClassSet.add()` previously returned `null` if the
   `CssClassSet` corresponded to multiple elements. In order to align with the
   null-safe changes in the `Set` interface, it will now return `false` instead.
   The same applies for `CssClassSet.toggle`.
@@ -1675,7 +1756,7 @@
 
 #### `dart:mirrors`
 
-- **Breaking Change** [#42714][]: web compilers (dart2js and DDC) now produce a
+- **Breaking change** [#42714][]: web compilers (dart2js and DDC) now produce a
   compile-time error if `dart:mirrors` is imported.
 
   Most projects should not be affected. Since 2.0.0 this library was unsupported
@@ -1726,7 +1807,7 @@
 
 ### Dart VM
 
-- **Breaking Change** [#41100][]: When printing a string using the `print`
+- **Breaking change** [#41100][]: When printing a string using the `print`
   function, the default implementation (used when not overridden by the embedder
   or the current zone) will print any unpaired surrogates in the string as
   replacement characters (`U+FFFD`). Similarly, the `Dart_StringToUTF8` function
@@ -1884,12 +1965,12 @@
 
 #### `dart:html`
 
-- **Breaking Change** [#39627][]: Changed the return type of several HTML native
+- **Breaking change** [#39627][]: Changed the return type of several HTML native
   methods involving futures. In return types that matched `Future<List<T>>`,
   `T was` changed to `dynamic`. These methods would have resulted in a runtime
   error if they were used.
 
-- **Breaking Change**: `Node.insertAllBefore()` erroneously had a return type of
+- **Breaking change**: `Node.insertAllBefore()` erroneously had a return type of
   `Node`, even though it was not returning anything. This has been corrected to
   `void`.
 
@@ -2023,7 +2104,7 @@
 
 ### Foreign Function Interface (`dart:ffi`)
 
-- **Breaking Change**: Changed `Pointer.asFunction()` and
+- **Breaking change**: Changed `Pointer.asFunction()` and
   `DynamicLibrary.lookupFunction()` to extension methods. Invoking them
   dynamically previously already threw an exception, so the runtime behavior
   stays the same. However, the extension methods are only visible if `dart:ffi`
@@ -2042,7 +2123,7 @@
 frequently encounter code that is accepted by one compiler but then fails in the
 other.
 
-- **Breaking Change**: Deleted the legacy (analyzer based) version of DDC. For
+- **Breaking change**: Deleted the legacy (analyzer based) version of DDC. For
   additional details see the [announcement][ddc].
 
   - The `--kernel` option is now ignored and defaults to true. There is no
@@ -2055,12 +2136,12 @@
     deleted from `dart-sdk/lib/dev_compiler` in favor of the versions located at
     `dart-sdk/lib/dev_compiler/kernel`.
 
-- **Breaking Change**: Functions passed to JavaScript using the recommended
+- **Breaking change**: Functions passed to JavaScript using the recommended
   `package:js` interop specification must now be wrapped with a call to
   `allowInterop`. This behavior was always enforced by Dart2JS, but was not
   enforced consistently by DDC. It is now enforced by both.
 
-- **Breaking Change**: Constructors in `@JS()` classes must be marked with
+- **Breaking change**: Constructors in `@JS()` classes must be marked with
   `external`. Previously the `external` could be omitted in some cases with DDC
   but doing so would cause incorrect behavior with Dart2JS.
 
@@ -2131,16 +2212,16 @@
 - JS interop classes with an index operator are now static errors instead of
   causing invalid code in Dart2JS.
 
-- **Breaking Change**: The subtyping rule for generic functions is now more
+- **Breaking change**: The subtyping rule for generic functions is now more
   forgiving. Corresponding type parameter bounds now only need to be mutual
   subtypes rather than structurally equal up to renaming of bound type variables
   and equating all top types.
 
-- **Breaking Change**: Types are now normalized. See [normalization][] for the
+- **Breaking change**: Types are now normalized. See [normalization][] for the
   full specification. Types will now be printed in their normal form, and mutual
   subtypes with the same normal form will now be considered equal.
 
-- **Breaking Change**: Constructors in `@JS()` classes must be marked with
+- **Breaking change**: Constructors in `@JS()` classes must be marked with
   `external`. Previously, the external could be omitted for unused constructors.
   Omitting `external` for a constructor which is used would cause incorrect
   behavior at runtime, now omitting it on any constructor is a static error.
@@ -2151,7 +2232,7 @@
 
 Other dart2js changes:
 
-- **Breaking Change**: The `--package-root` flag, which was hidden and disabled
+- **Breaking change**: The `--package-root` flag, which was hidden and disabled
   in Dart 2.0.0, has been completely removed. Passing this flag will now cause
   `dart2js` to fail.
 
@@ -2215,10 +2296,10 @@
 
 ## 2.7.2 - 2020-03-23
 
-This is a patch release that addresses a vulnerability in `dart:html`
-[NodeValidator][] related to DOM clobbering of `previousSibling`. See the
-[vulnerability advisory][cve-2020-8923] for more details. Thanks to **Vincenzo
-di Cicco** for finding and reporting this issue.
+**Security advisory**: This is a patch release that addresses a vulnerability in
+`dart:html` [NodeValidator][] related to DOM clobbering of `previousSibling`.
+See the security advisory [CVE-2020-8923][cve-2020-8923] for more details.
+Thanks to **Vincenzo di Cicco** for finding and reporting this issue.
 
 This release also improves compatibility with ARMv8 processors (issue [40001][])
 and dart:io stability (issue [40589][]).
@@ -2235,7 +2316,7 @@
 
 [40217]: https://github.com/dart-lang/sdk/issues/40217
 
-**Breaking Change**: The Dart SDK for macOS is now only available for x64 (issue
+**Breaking change**: The Dart SDK for macOS is now only available for x64 (issue
 [39810][]).
 
 [39810]: https://github.com/dart-lang/sdk/issues/39810
@@ -2250,7 +2331,7 @@
 
 ### Language
 
-- **Breaking Change**: [Static extension members][] are accessible when imported
+- **Breaking change**: [Static extension members][] are accessible when imported
   with a prefix (issue [671][]). In the extension method **preview** launch,
   importing a library with a prefix hid all extension members in addition to
   hiding the extension name, thereby making them inaccessible in the importing
@@ -3231,7 +3312,7 @@
 
 #### `dart:io`
 
-- **Breaking Change:** Adding to a closed `IOSink` now throws a `StateError`.
+- **Breaking change:** Adding to a closed `IOSink` now throws a `StateError`.
 - Added ability to get and set low level socket options.
 
 [29554]: https://github.com/dart-lang/sdk/issues/29554
@@ -3928,8 +4009,8 @@
 - **(Breaking)** "dart:isolate" and "dart:mirrors" are no longer supported when
   using Dart for the web. They are still supported in the command-line VM.
 
-- **(Breaking)** Pub's transformer-based build system has been [replaced by a
-  new build system][transformers].
+- **(Breaking)** Pub's transformer-based build system has been replaced by a
+  [new build system][build system].
 
 - The `new` keyword is optional and can be omitted. Likewise, `const` can be
   omitted inside a const context ([issue 30921][]).
@@ -3938,8 +4019,8 @@
 
 [issue 30345]: https://github.com/dart-lang/sdk/issues/30345
 [issue 30921]: https://github.com/dart-lang/sdk/issues/30921
-[strong mode]: https://www.dartlang.org/guides/language/sound-dart
-[transformers]: https://www.dartlang.org/tools/pub/obsolete
+[strong mode]: https://dart.dev/guides/language/type-system
+[build system]: https://github.com/dart-lang/build
 
 ### Language
 
@@ -4866,7 +4947,7 @@
 ```
 
 To opt back into the warnings, add the following to the
-[.analysis_options](https://www.dartlang.org/guides/language/analysis-options)
+[.analysis_options](https://dart.dev/guides/language/analysis-options)
 file for your project.
 
 ```
@@ -5301,7 +5382,7 @@
 
 - We have improved the way that the VM locates the native code library for a
   native extension (e.g. `dart-ext:` import). We have updated this
-  [article on native extensions](https://www.dartlang.org/articles/dart-vm/native-extensions)
+  [article on native extensions](https://dart.dev/server/c-interop-native-extensions)
   to reflect the VM's improved behavior.
 
 - Linux builds of the VM will now use the `tcmalloc` library for memory
@@ -6092,7 +6173,7 @@
 ### Tool changes
 
 - `dart2js` and Dartium now support improved Javascript Interoperability via the
-  [js package](https://pub.dartlang.org/packages/js).
+  [js package](https://pub.dev/packages/js).
 
 - `docgen` and `dartdocgen` no longer ship in the SDK. The `docgen` sources have
   been removed from the repository.
@@ -6208,7 +6289,7 @@
 - Documentation tools
 
   - `dartdoc` is now the default tool to generate static HTML for API docs.
-    [Learn more](https://pub.dartlang.org/packages/dartdoc).
+    [Learn more](https://pub.dev/packages/dartdoc).
 
   - `docgen` and `dartdocgen` have been deprecated. Currently plan is to remove
     them in 1.13.
@@ -6401,7 +6482,7 @@
 ### Tool changes
 
 - This is the first release that does not include the Eclipse-based **Dart
-  Editor**. See [dartlang.org/tools](https://www.dartlang.org/tools/) for
+  Editor**. See [dart.dev/tools](https://dart.dev/tools#ides-and-editors) for
   alternatives.
 - This is the last release that ships the (unsupported) dart2dart (aka
   `dart2js --output-type=dart`) utility as part of dart2js
@@ -6481,8 +6562,8 @@
 
 - Enum support is fully enabled. See [the language tour][enum] for more details.
 
-[async]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#asynchrony
-[enum]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#enums
+[async]: https://dart.dev/guides/language/language-tour#asynchrony
+[enum]: https://dart.dev/guides/language/language-tour#enums
 
 ### Tool changes
 
@@ -6496,7 +6577,7 @@
 - Analysis supports more and better hints, including unused variables and unused
   private members.
 
-[dartfmt]: https://www.dartlang.org/tools/dartfmt/
+[dartfmt]: https://dart.dev/tools/dart-format
 
 ### Core library changes
 
@@ -6514,7 +6595,7 @@
 #### Details
 
 For more information on any of these changes, see the corresponding
-documentation on the [Dart API site](http://api.dartlang.org).
+documentation on the [Dart API site](http://api.dart.dev).
 
 - `dart:async`:
 
@@ -6666,7 +6747,7 @@
   the same page.
 
 [pub global activate]:
-  https://www.dartlang.org/tools/pub/cmd/pub-global.html#running-a-script-from-your-path
+  https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path
 
 ### Core library changes
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6802814..cdfcdaf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,7 +11,7 @@
       click that icon to report a bug on the page.
     * To report an API doc bug,
       [create an SDK issue](https://github.com/dart-lang/sdk/issues/new?title=API%20doc%20issue:).
-  * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)) and [dart.dev/web](https://dart.dev/web) (repo: [dart-lang/site-www/src/web](https://github.com/dart-lang/site-www/tree/master/src/web)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/wiki/Writing-for-Dart-and-Flutter-websites).
+  * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/blob/master/doc/writing-for-dart-and-flutter-websites.md).
   * Improve the API reference docs at [api.dart.dev](https://api.dart.dev) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/main/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://dart.dev/guides/language/effective-dart/documentation).
 
 ## Before you contribute
@@ -20,9 +20,13 @@
 
 Before you start working on a larger contribution, you should get in touch with us first through the  [Dart Issue Tracker](https://dartbug.com) with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on.
 
-All submissions, including submissions by project members, require review.  We use the same code-review tools and process as the chromium project.  In order to submit a patch, you need to get the [depot\_tools](http://dev.chromium.org/developers/how-tos/depottools).
+All submissions, including submissions by project members, require review.  We use the same code-review tools and process as the chromium project.
 
-We occasionally take pull requests, e.g., for comment changes, but the main flow is to use the Rietveld review system as explained below.
+We occasionally take pull requests, e.g., for comment changes, but the main flow is to use the Gerrit review system as explained below.
+
+## Setting up Environment
+
+In order to submit a patch, you need to get the [depot\_tools](http://dev.chromium.org/developers/how-tos/depottools).
 
 ## Getting the code
 
@@ -69,7 +73,9 @@
 git cl upload -s
 ```
 
-The above command returns a URL for the review. Attach this review to your issue in https://dartbug.com
+The above command returns a URL for the review. Attach this review to your issue in https://dartbug.com.
+
+To update the cl, just commit your changes and run `git cl upload -s` for your branch.
 
 If you have commit access, when the review is done and the patch is good to go, submit the patch on https://dart-review.googlesource.com:
 
diff --git a/DEPS b/DEPS
index 56ed123..dc14ff7 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "1247f4096b835f31465e8f71dece427e95b51534",
+  "co19_rev": "a38d7c5685e64499cfbdbfe6548fbd5b63b57f15",
   # This line prevents conflicts when both packages are rolled simultaneously.
   "co19_2_rev": "995745937abffe9fc3a6441f9f0db27b2d706e4c",
 
@@ -59,15 +59,15 @@
   # Checkout extra javascript engines for testing or benchmarking.
   # d8, the V8 shell, is always checked out.
   "checkout_javascript_engines": False,
-  "d8_tag": "version:9.9.3",
+  "d8_tag": "version:10.0.40",
   "jsshell_tag": "version:95.0",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
   # The list of revisions for these tools comes from Fuchsia, here:
-  # https://fuchsia.googlesource.com/integration/+/HEAD/prebuilts
+  # https://fuchsia.googlesource.com/integration/+/HEAD/toolchain
   # If there are problems with the toolchain, contact fuchsia-toolchain@.
-  "clang_revision": "e3a7f0e2f9ab566bd9b71fb54fe77e947b061a12",
+  "clang_revision": "1aa59ff2f789776ebfa2d4b315fd3ea589652b4a",
   "gn_revision": "b79031308cc878488202beb99883ec1f2efd9a6d",
 
   # Scripts that make 'git cl format' work.
@@ -80,7 +80,7 @@
   "async_rev": "80886150a5e6c58006c8ae5a6c2aa7108638e2a9",
   "bazel_worker_rev": "ceeba0982d4ff40d32371c9d35f3d2dc1868de20",
   "benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
-  "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
+  "boolean_selector_rev": "437e7f06c7e416bed91e16ae1df453555897e945",
   "boringssl_gen_rev": "ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f",
   "boringssl_rev" : "87f316d7748268eb56f2dc147bd593254ae93198",
   "browser-compat-data_tag": "v1.0.22",
@@ -89,11 +89,11 @@
   "charcode_rev": "84ea427711e24abf3b832923959caa7dd9a8514b",
   "chrome_rev" : "19997",
   "cli_util_rev" : "b0adbba89442b2ea6fef39c7a82fe79cb31e1168",
-  "clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
-  "collection_rev": "a4c941ab94044d118b2086a3f261c30377604127",
+  "clock_rev" : "5631a0612f4ac7e1b32f7c9a00fc7c00a41615e1",
+  "collection_rev": "e1407da23b9f17400b3a905aafe2b8fa10db3d86",
   "convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
   "crypto_rev": "b5024e4de2b1c474dd558bef593ddbf0bfade152",
-  "csslib_rev": "158bfa94eed08c12c07a8ee0a3fded0ebdcd1fcb",
+  "csslib_rev": "518761b166974537f334dbf264e7f56cb157a96a",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
   # team so that the internal formatter `tools/sdks/dart-sdk/bin/dart format`
@@ -107,17 +107,17 @@
   #     and land the review.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-  "dart_style_rev": "6f894c0ca33686122be9085f06e5b9bf6ad55262",
+  "dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea",
 
-  "dartdoc_rev" : "f9cfab1b84176873c80b89e7c8b54c669344f9ed",
-  "devtools_rev" : "f265c3028d5ed9a454762532bed144fa36b2e4d5",
+  "dartdoc_rev" : "a39f378f8100b907e6285ac825967d764fd664ad",
+  "devtools_rev" : "b9f2039239cc72ac8b26f8a5fe46123f34d53ce1",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
   "fixnum_rev": "848341f061359ef7ddc0cad472c2ecbb036b28ac",
-  "file_rev": "0e09370f581ab6388d46fda4cdab66638c0171a1",
-  "glob_rev": "a62acf590598f458d3198d9f2930c1c9dd4b1379",
-  "html_rev": "00cd3c22dac0e68e6ed9e7e4945101aedb1b3109",
+  "file_rev": "1ebc38852ffed24b564910317982298b56c2cedd",
+  "glob_rev": "da1f4595ee2f87982cbcc663d4cac244822d9227",
+  "html_rev": "f108bce59d136c584969fd24a5006914796cf213",
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
-  "http_multi_server_rev": "de1b312164c24a1690b46c6e97bd47eff40c4649",
+  "http_multi_server_rev": "34bf7f04b61cce561f47f7f275c2cc811534a05a",
   "http_parser_rev": "202391286ddc13c4c3c284ac5b511f04697250ed",
   "http_rev": "1e42ffa181b263f7790f276a5465832bff7ce615",
   "icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
@@ -126,11 +126,11 @@
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
   "linter_tag": "1.18.0",
   "lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
-  "logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
+  "logging_rev": "dfbe88b890c3b4f7bc06da5a7b3b43e9e263b688",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_rev": "7479783f0493f6717e1d7ae31cb37d39a91026b2",
   "matcher_rev": "07595a7739d47a8315caba5a8e58fb9ae3d81261",
-  "mime_rev": "c931f4bed87221beaece356494b43731445ce7b8",
+  "mime_rev": "7f4252d469de032aa4df9f90e827dbac4b8efa48",
   "mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
   "oauth2_rev": "7cd3284049fe5badbec9f2bea2afc41d14c01057",
   "package_config_rev": "8731bf10b5375542792a32a0f7c8a6f370583d96",
@@ -142,7 +142,7 @@
   "process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
   "protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
   "pub_rev": "8f5ab7b1aba3b9f66b56246d77e167990339d317",
-  "pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
+  "pub_semver_rev": "ea6c54019948dc03042c595ce9413e17aaf7aa38",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
   "shelf_static_rev": "202ec1a53c9a830c17cf3b718d089cf7eba568ad",
@@ -150,27 +150,27 @@
   "shelf_proxy_tag": "v1.0.0",
   "shelf_rev": "46483f896cc4308ee3d8e997030ae799b72aa16a",
   "shelf_web_socket_rev": "24fb8a04befa75a94ac63a27047b231d1a22aab4",
-  "source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
+  "source_map_stack_trace_rev": "80709f2d2fe5086ab50d744a28a2d26ea4384a1b",
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "6499ee3adac8d469e2953e2e8ba4bdb4c2fbef90",
   "source_span_rev": "dc189b455d823e2919667f6c5dcb41ab7483bce0",
   "sse_rev": "9084339389eb441d0c0518cddac211a097e78657",
   "stack_trace_rev": "5220580872625ddee41e9ca9a5f3364789b2f0f6",
   "stream_channel_rev": "3fa3e40c75c210d617b8b943b9b8f580e9866a89",
-  "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
+  "string_scanner_rev": "0e53bf9059e8e22a3b346aac7ec755a0f8314eb6",
   "sync_http_rev": "b59c134f2e34d12acac110d4f17f83e5a7db4330",
   "test_descriptor_rev": "ead23c1e7df079ac0f6457a35f7a71432892e527",
   "test_process_rev": "7c73ec8a8a6e0e63d0ec27d70c21ca4323fb5e8f",
-  "term_glyph_rev": "6a0f9b6fb645ba75e7a00a4e20072678327a0347",
+  "term_glyph_rev": "4885b7f8af6931e23d3aa6d1767ee3f9a626923d",
   "test_reflective_loader_rev": "fcfce37666672edac849d2af6dffc0f8df236a94",
   "test_rev": "099dcc4d052a30c6921489cfbefa1c8531d12975",
   "typed_data_rev": "29ce5a92b03326d0b8035916ac04f528874994bd",
   "usage_rev": "f0cb8f7cce8b675255c81488dbab8cf9f2f56404",
-  "vector_math_rev": "0c9f5d68c047813a6dcdeb88ba7a42daddf25025",
+  "vector_math_rev": "0cbed0914d49a6a44555e6d5444c438a4a4c3fc1",
   "watcher_rev": "f76997ab0c857dc5537ac0975a9ada92b54ef949",
   "webdriver_rev": "ff5ccb1522edf4bed578ead4d65e0cbc1f2c4f02",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
-  "web_socket_channel_rev": "6448ce532445a8a458fa191d9346df071ae0acad",
+  "web_socket_channel_rev": "99dbdc5769e19b9eeaf69449a59079153c6a8b1f",
   "WebCore_rev": "bcb10901266c884e7b3740abc597ab95373ab55c",
   "webdev_rev": "832b096c0c24798d3df46faa7b7661fe930573c2",
   "webkit_inspection_protocol_rev": "dd6fb5d8b536e19cedb384d0bbf1f5631923f1e8",
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..911f0bb
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,23 @@
+# Global approvers - only to be used as a last resort.
+asiva@google.com #{LAST_RESORT_SUGGESTION}
+athom@google.com #{LAST_RESORT_SUGGESTION}
+kustermann@google.com #{LAST_RESORT_SUGGESTION}
+leafp@google.com #{LAST_RESORT_SUGGESTION}
+sigmund@google.com #{LAST_RESORT_SUGGESTION}
+vegorov@google.com #{LAST_RESORT_SUGGESTION}
+vsm@google.com #{LAST_RESORT_SUGGESTION}
+
+# DEPS
+per-file DEPS=file:/tools/OWNERS_ENG
+
+# Changelog, AUTHORS, and .git* do not require approval.
+per-file CHANGELOG.md,AUTHORS,.gitattributes,.gitconfig,.gitignore=*
+
+# Product documentation
+per-file CONTRIBUTING.md,LICENSE,PATENT_GRANT,README.*,SECURITY.md=file:/tools/OWNERS_PRODUCT
+
+# Top level build files
+per-file .clang-format,BUILD.gn,sdk_args.gni=file:/tools/OWNERS_VM
+
+# Generated file
+per-file .packages=*
diff --git a/SECURITY.md b/SECURITY.md
index a341d38..573f212 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,3 +1,8 @@
 ## Reporting vulnerabilities
 To report potential vulnerabilities, please see our security policy on
 [https://dart.dev/security](https://dart.dev/security).
+
+## Published security advisories
+
+For advisories published for the Dart SDK, see
+[security advisories](https://github.com/dart-lang/sdk/security/advisories?state=published).
diff --git a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
index b3d40c0..3451cc3 100644
--- a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
@@ -4,6 +4,8 @@
 
 // ignore_for_file: avoid_function_literals_in_foreach_calls
 
+import 'dart:math' show Random;
+
 import 'package:benchmark_harness/benchmark_harness.dart';
 import 'package:fixnum/fixnum.dart';
 
@@ -240,7 +242,9 @@
 class DummyBenchmark extends BenchmarkBase {
   DummyBenchmark(String name) : super(name);
   @override
-  double measure() => 2000 * 1000 * 1.0; // A rate of one run per 2s.
+  // A rate of one run per 2s, with a millisecond of noise.  Some variation is
+  // needed for Golem's noise-based filtering and regression detection.
+  double measure() => (2000 + Random().nextDouble() - 0.5) * 1000;
 }
 
 /// Create [ParseJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
diff --git a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
index db19b68..2ff130d 100644
--- a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
@@ -6,6 +6,8 @@
 
 // @dart=2.9
 
+import 'dart:math' show Random;
+
 import 'package:benchmark_harness/benchmark_harness.dart';
 import 'package:fixnum/fixnum.dart';
 
@@ -242,7 +244,9 @@
 class DummyBenchmark extends BenchmarkBase {
   DummyBenchmark(String name) : super(name);
   @override
-  double measure() => 2000 * 1000 * 1.0; // A rate of one run per 2s.
+  // A rate of one run per 2s, with a millisecond of noise.  Some variation is
+  // needed for Golem's noise-based filtering and regression detection.
+  double measure() => (2000 + Random().nextDouble() - 0.5) * 1000;
 }
 
 /// Create [ParseJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
diff --git a/benchmarks/Iterators/dart/Iterators.dart b/benchmarks/Iterators/dart/Iterators.dart
new file mode 100644
index 0000000..d4ff6c4
--- /dev/null
+++ b/benchmarks/Iterators/dart/Iterators.dart
@@ -0,0 +1,651 @@
+// 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 iterators of common collections.
+///
+/// The purpose of this benchmark is to detect performance changes in the
+/// iterators for common collections (system Lists, Maps, etc).
+///
+/// ## Polymorphic benchmarks
+///
+/// Benchmark names beginning with `Iterators.poly.`.
+///
+/// These benchmark use the iterators from a common polymorphic for-in loop, so
+/// none of the methods involved in iterating are inlined. This gives an
+/// indication of worst-case performance.
+///
+/// Iterables of different sizes (small (N=1) and large (N=100)) are used to
+/// give insight into the fixed vs per-element costs.
+///
+/// Results are normalized by iterating 1000 elements and reporting the time per
+/// element. There is an outer loop that calls the iterator loop in `sinkAll`.
+///
+/// The dispatched (polymorphic) calls are to `get:iterator`, `moveNext` and
+/// `get:current`.
+///
+///  |    N | outer | `get:iterator` | `moveNext` | `get:current` |
+///  | ---: | ----: | -------------: | ---------: | ------------: |
+///  |   0* |  1000 |           1000 |       1000 |             0 |
+///  |   1  |  1000 |           1000 |       2000 |          1000 |
+///  |   2* |   500 |            500 |       1500 |          1000 |
+///  | 100  |    10 |             10 |       1010 |          1000 |
+///
+/// * By default only the N=1 and N=100 benchmarks arer run. The N=0 and N=2
+/// series are available running manually with `--0` and `--2` command-line
+/// arguments.
+///
+/// Generic Iterables have benchmarks for different element types. There are
+/// benchmarks for `int` type arguments, which have a fast type test, and for
+/// `Thing<Iterable<Comparable>>`, which is harder to test quickly. These tests
+/// are distingished by `int` and `Hard` in the name.
+///
+/// ## Monomorphic benchmarks
+///
+/// Benchmark names beginning with `Iterators.mono.`.
+///
+/// A subset of the polymorphic benchmarks are also implemented with a
+/// per-benchmark for-in loop directly iterating a collection of known
+/// representation. This gives the compiler the opportunity to inline the
+/// methods into the loop and represents the best-case performance.
+///
+/// ## Example benchmarks
+///
+/// The name has 4-7 words separated by periods. The first word is always
+/// 'Iterators', and the second is either 'mono' for monomorphic loops, or
+/// 'poly' for benchmarks using a shared polymorphic loop. The last word is a
+/// number which is the size (length) of the Iterable.
+///
+/// ### Iterators.mono.const.Map.int.values.100
+///
+/// A for-in loop over the values iterable of a known constant Map with value
+/// type `int` and 100 entries.
+///
+/// ### Iterators.poly.Runes.1
+///
+/// An interation over the String.runes iterable of a single character String
+/// using the shared polymorphic loop.
+///
+/// ### Iterators.poly.HashMap.Hard.keys.100
+///
+/// An iteration of over the keys iterable of a HashMap with key type
+/// `Thing<Iterable<Comparable>>` and 100 entries.
+///
+/// ### Iterators.*.UpTo.*
+///
+/// The UpTo iterable is a minimal iterable that provides successive
+/// numbers. The `moveNext` and `get:current` methods are small. Comparing
+/// Iterators.poly.UpTo.*.100 to Iterators.poly.*.100 gives an indication of how
+/// much work is done by `moveNext` (and sometimes `get:current`).
+///
+/// ### Iterators.mono.Nothing.*
+///
+/// The Nothing benchmark has no iteration over an iterable and is used to get a
+/// baseline time for running the benchmark loop for monomorphic
+/// benchmarks. This can be a substantial fraction of
+///
+/// Consider the times
+///
+///     Iterators.mono.CodeUnits.1   = 7.0ns
+///     Iterators.mono.Nothing.1     = 3.1ns
+///
+/// Because the trip count (i.e. 1) of the for-in loop is so small, there is a
+/// lot of overhead attributable to the outer loop in `MonoBenchmark.run`. The
+/// 1000/1 = 1000 trips of outer loops takes 3.1us (3.1ns * 1000 trips), so
+/// CodeUnits is spending only 7.0-3.1 = 3.9ns per character in the for-in
+/// loop over the `.codeUnits` of the single-character String.
+///
+///     Iterators.mono.CodeUnits.100 = 1.83ns
+///     Iterators.mono.Nothing.100   = 0.05ns
+///
+/// Now the outer loop runs only 1000/100 = 10 times, for 0.05us. If we subtract
+/// this from 1.83, we get 1.78ns per character for long strings.
+///
+library iterators_benchmark;
+
+// TODO(48277): Update when fixed:
+// ignore_for_file: unnecessary_lambdas
+
+import 'dart:collection';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+import 'data.dart';
+
+const targetSize = 1000;
+
+class Emitter implements ScoreEmitter {
+  @override
+  void emit(String testName, double value) {
+    // [value] is microseconds per ten calls to `run()`.
+    final nanoSeconds = value * 1000;
+    final singleElementTimeNs = nanoSeconds / 10 / targetSize;
+    print('$testName(RunTimeRaw): $singleElementTimeNs ns.');
+  }
+}
+
+abstract class Benchmark extends BenchmarkBase {
+  final int size;
+  bool selected = false;
+  Benchmark._(String name, this.size)
+      : super('Iterators.$name.$size', emitter: Emitter());
+
+  factory Benchmark(String name, int size, Iterable Function(int) generate) =
+      PolyBenchmark;
+}
+
+abstract class MonoBenchmark extends Benchmark {
+  final int _repeats;
+  MonoBenchmark(String name, int size)
+      : _repeats = size == 0 ? targetSize : targetSize ~/ size,
+        super._('mono.$name', size);
+
+  @override
+  void run() {
+    for (int i = 0; i < _repeats; i++) {
+      sinkMono();
+    }
+  }
+
+  void sinkMono();
+}
+
+class PolyBenchmark extends Benchmark {
+  final Iterable Function(int) generate;
+  final List<Iterable> inputs = [];
+
+  PolyBenchmark(String name, int size, this.generate)
+      : super._('poly.$name', size);
+
+  @override
+  void setup() {
+    if (inputs.isNotEmpty) return; // Ensure setup() is idempotent.
+
+    int totalSize = 0;
+    while (totalSize < targetSize) {
+      final sample = generate(size);
+      inputs.add(sample);
+      totalSize += size == 0 ? 1 : size;
+    }
+  }
+
+  @override
+  void run() {
+    for (int i = 0; i < inputs.length; i++) {
+      sinkAll(inputs[i]);
+    }
+  }
+}
+
+/// This function is the inner loop of the benchmark.
+@pragma('dart2js:noInline')
+@pragma('vm:never-inline')
+void sinkAll(Iterable iterable) {
+  for (final value in iterable) {
+    sink = value;
+  }
+}
+
+Object? sink;
+
+class BenchmarkConstMapIntKeys1 extends MonoBenchmark {
+  BenchmarkConstMapIntKeys1() : super('const.Map.int.keys', 1);
+
+  static const _map = constMapIntInt1;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.keys) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkConstMapIntKeys2 extends MonoBenchmark {
+  BenchmarkConstMapIntKeys2() : super('const.Map.int.keys', 2);
+
+  static const _map = constMapIntInt2;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.keys) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkConstMapIntKeys100 extends MonoBenchmark {
+  BenchmarkConstMapIntKeys100() : super('const.Map.int.keys', 100);
+
+  static const _map = constMapIntInt100;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.keys) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkConstMapIntValues1 extends MonoBenchmark {
+  BenchmarkConstMapIntValues1() : super('const.Map.int.values', 1);
+
+  static const _map = constMapIntInt1;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.values) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkConstMapIntValues2 extends MonoBenchmark {
+  BenchmarkConstMapIntValues2() : super('const.Map.int.values', 2);
+
+  static const _map = constMapIntInt2;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.values) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkConstMapIntValues100 extends MonoBenchmark {
+  BenchmarkConstMapIntValues100() : super('const.Map.int.values', 100);
+
+  static const _map = constMapIntInt100;
+
+  @override
+  void sinkMono() {
+    for (final value in _map.values) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkMapIntKeys extends MonoBenchmark {
+  BenchmarkMapIntKeys(int size) : super('Map.int.keys', size) {
+    _map.addAll(generateMapIntInt(size));
+  }
+
+  final Map<int, int> _map = {};
+
+  @override
+  void sinkMono() {
+    for (final value in _map.keys) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkUpTo extends MonoBenchmark {
+  BenchmarkUpTo(int size) : super('UpTo', size);
+
+  @override
+  void sinkMono() {
+    for (final value in UpTo(size)) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkNothing extends MonoBenchmark {
+  BenchmarkNothing(int size) : super('Nothing', size);
+
+  @override
+  void sinkMono() {
+    sink = size;
+  }
+}
+
+class BenchmarkCodeUnits extends MonoBenchmark {
+  BenchmarkCodeUnits(int size)
+      : string = generateString(size),
+        super('CodeUnits', size);
+
+  final String string;
+
+  @override
+  void sinkMono() {
+    for (final value in string.codeUnits) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkListIntGrowable extends MonoBenchmark {
+  BenchmarkListIntGrowable(int size)
+      : _list = List.generate(size, (i) => i),
+        super('List.int.growable', size);
+
+  final List<int> _list;
+
+  @override
+  void sinkMono() {
+    for (final value in _list) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkListIntSystem1 extends MonoBenchmark {
+  // The List type here is not quite monomorphic. It is the choice between two
+  // 'system' Lists: a const List and a growable List. It is quite common to
+  // have growable and const lists at the same use-site (e.g. the const coming
+  // from a default argument).
+  //
+  // Ideally some combination of the class heirarchy or compiler tricks would
+  // ensure there is little cost of having this gentle polymorphism.
+  BenchmarkListIntSystem1(int size)
+      : _list1 = List.generate(size, (i) => i),
+        _list2 = generateConstListOfInt(size),
+        super('List.int.growable.and.const', size);
+
+  final List<int> _list1;
+  final List<int> _list2;
+  bool _flip = false;
+
+  @override
+  void sinkMono() {
+    _flip = !_flip;
+    final list = _flip ? _list1 : _list2;
+    for (final value in list) {
+      sink = value;
+    }
+  }
+}
+
+class BenchmarkListIntSystem2 extends MonoBenchmark {
+  // The List type here is not quite monomorphic. It is the choice between two
+  // 'system' Lists: a const List and a fixed-length List. It is quite common to
+  // have fixed-length and const lists at the same use-site (e.g. the const
+  // coming from a default argument).
+  //
+  // Ideally some combination of the class heirarchy or compiler tricks would
+  // ensure there is little cost of having this gentle polymorphism.
+  BenchmarkListIntSystem2(int size)
+      : _list1 = List.generate(size, (i) => i, growable: false),
+        _list2 = generateConstListOfInt(size),
+        super('List.int.fixed.and.const', size);
+
+  final List<int> _list1;
+  final List<int> _list2;
+  bool _flip = false;
+
+  @override
+  void sinkMono() {
+    _flip = !_flip;
+    final list = _flip ? _list1 : _list2;
+    for (final value in list) {
+      sink = value;
+    }
+  }
+}
+
+/// A simple Iterable that yields the integers 0 through `length`.
+///
+/// This Iterable serves as the minimal interesting example to serve as a
+/// baseline, and is useful in constructing other benchmark inputs.
+class UpTo extends IterableBase<int> {
+  final int _length;
+  UpTo(this._length);
+
+  @override
+  Iterator<int> get iterator => UpToIterator(_length);
+}
+
+class UpToIterator implements Iterator<int> {
+  final int _length;
+  int _position = 0;
+  int? _current;
+
+  UpToIterator(this._length);
+
+  @override
+  int get current => _current!;
+
+  @override
+  bool moveNext() {
+    if (_position < _length) {
+      _current = _position++;
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+}
+
+/// A `Thing` has a type parameter which makes type tests in the Iterators
+/// potentially harder, and equality uses the type parameter, making Iterables
+/// that do lookups slower.
+class Thing<T> {
+  static int _nextIndex = 0;
+  final int _index;
+  Thing() : _index = _nextIndex++;
+
+  @override
+  int get hashCode => _index;
+
+  @override
+  bool operator ==(Object other) => other is Thing<T> && other._index == _index;
+}
+
+final thingGenerators = [
+  // TODO(48277): Use instantiated constructor tear-offs when fixed:
+  () => Thing<Set<String>>(),
+  () => Thing<Set<Duration>>(),
+  () => Thing<Set<BigInt>>(),
+  () => Thing<Queue<String>>(),
+  () => Thing<Queue<Duration>>(),
+  () => Thing<Queue<BigInt>>(),
+  () => Thing<List<String>>(),
+  () => Thing<List<Duration>>(),
+  () => Thing<List<BigInt>>(),
+];
+
+int _generateThingListState = 0;
+List<Thing<Iterable<Comparable>>> generateThingList(int n) {
+  Thing nextThing(_) {
+    final next = (_generateThingListState++).remainder(thingGenerators.length);
+    return thingGenerators[next]();
+  }
+
+  return List.from(UpTo(n).map(nextThing));
+}
+
+Map<Thing<Iterable<Comparable>>, Thing<Iterable<Comparable>>> generateThingMap(
+    int n) {
+  return Map.fromIterables(generateThingList(n), generateThingList(n));
+}
+
+Map<Thing<Iterable<Comparable>>, Thing<Iterable<Comparable>>>
+    generateThingHashMap(int n) {
+  return HashMap.fromIterables(generateThingList(n), generateThingList(n));
+}
+
+int _generateStringState = 0;
+String generateString(int n) {
+  return ((_generateStringState++).isEven ? 'x' : '\u2192') * n;
+}
+
+Map<int, int> generateMapIntInt(int n) =>
+    Map<int, int>.fromIterables(UpTo(n), UpTo(n));
+
+Map<int, int> generateIdentityMapIntInt(int n) {
+  return Map<int, int>.identity()..addAll(generateMapIntInt(n));
+}
+
+/// Run the benchmark loop on various inputs to pollute type inference and JIT
+/// caches.
+void pollute() {
+  // This iterable reads `sink` mid-loop, making it infeasible for the compiler
+  // to move the write to `sink` out of the loop.
+  sinkAll(UpTo(100).map((i) {
+    if (i > 0 && sink != i - 1) throw StateError('sink');
+    return i;
+  }));
+
+  // TODO(sra): Do we need to add anything here? There are a lot of benchmarks,
+  // so that is probably sufficient to make the necessary places polymorphic.
+}
+
+/// Command-line arguments:
+///
+/// `--0`: Run benchmarks for empty iterables.
+/// `--1`: Run benchmarks for singleton iterables.
+/// `--2`: Run benchmarks for two-element iterables.
+/// `--100`: Run benchmarks for 100-element iterables.
+///
+///    Default sizes are 1 and 100.
+///
+/// `--all`: Run all benchmark variants and sizes.
+///
+/// `foo`, `foo.bar`: a Selector.
+///
+///    Run benchmarks with name containing all the dot-separated words in the
+///    selector, so `--Set.const` will run benchmark
+///    'Iterators.const.Set.int.N`, and `--2.UpTo` will select
+///    `Iterators.UpTo.2`.  Each selector is matched independently, and if
+///    selectors are used, only benchmarks matching some selector are run.
+///
+void main(List<String> commandLineArguments) {
+  final arguments = [...commandLineArguments];
+
+  const allSizes = {0, 1, 2, 100};
+  const defaultSizes = {1, 100};
+  final allSizeWords = Set.unmodifiable(allSizes.map((size) => '$size'));
+
+  final Set<int> sizes = {};
+  final Set<String> selectors = {};
+
+  if (arguments.remove('--0')) sizes.add(0);
+  if (arguments.remove('--1')) sizes.add(1);
+  if (arguments.remove('--2')) sizes.add(2);
+  if (arguments.remove('--100')) sizes.add(100);
+
+  if (arguments.remove('--all')) {
+    sizes.addAll(allSizes);
+  }
+
+  selectors.addAll(arguments);
+
+  if (sizes.isEmpty) sizes.addAll(defaultSizes);
+  if (selectors.isEmpty) selectors.add('Iterators');
+
+  List<Benchmark> makeBenchmarksForSize(int size) {
+    return [
+      // Simple
+      BenchmarkNothing(size),
+      BenchmarkUpTo(size),
+      BenchmarkCodeUnits(size),
+      Benchmark('UpTo', size, (n) => UpTo(n)),
+      Benchmark('CodeUnits', size, (n) => generateString(n).codeUnits),
+      Benchmark('Runes', size, (n) => generateString(n).runes),
+      // ---
+      BenchmarkListIntGrowable(size),
+      BenchmarkListIntSystem1(size),
+      BenchmarkListIntSystem2(size),
+      Benchmark('List.int.growable', size,
+          (n) => List<int>.of(UpTo(n), growable: true)),
+      Benchmark('List.int.fixed', size,
+          (n) => List<int>.of(UpTo(n), growable: false)),
+      Benchmark('List.int.unmodifiable', size,
+          (n) => List<int>.unmodifiable(UpTo(n))),
+      // ---
+      Benchmark('List.Hard.growable', size, generateThingList),
+      // ---
+      Benchmark('Set.int', size, (n) => Set<int>.of(UpTo(n))),
+      Benchmark('const.Set.int', size, generateConstSetOfInt),
+      // ---
+      BenchmarkMapIntKeys(size),
+      Benchmark('Map.int.keys', size, (n) => generateMapIntInt(n).keys),
+      Benchmark('Map.int.values', size, (n) => generateMapIntInt(n).values),
+      Benchmark('Map.int.entries', size, (n) => generateMapIntInt(n).entries),
+      // ---
+      Benchmark('Map.identity.int.keys', size,
+          (n) => generateIdentityMapIntInt(n).keys),
+      Benchmark('Map.identity.int.values', size,
+          (n) => generateIdentityMapIntInt(n).values),
+      Benchmark('Map.identity.int.entries', size,
+          (n) => generateIdentityMapIntInt(n).entries),
+      // ---
+      Benchmark(
+          'const.Map.int.keys', size, (n) => generateConstMapIntInt(n).keys),
+      Benchmark('const.Map.int.values', size,
+          (n) => generateConstMapIntInt(n).values),
+      Benchmark('const.Map.int.entries', size,
+          (n) => generateConstMapIntInt(n).entries),
+      // ---
+      Benchmark('Map.Hard.keys', size, (n) => generateThingMap(n).keys),
+      Benchmark('Map.Hard.values', size, (n) => generateThingMap(n).values),
+      // ---
+      Benchmark('HashMap.int.keys', size,
+          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).keys),
+      Benchmark('HashMap.int.values', size,
+          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).values),
+      Benchmark('HashMap.int.entries', size,
+          (n) => HashMap<int, int>.fromIterables(UpTo(n), UpTo(n)).entries),
+      // ---
+      Benchmark('HashMap.Hard.keys', size, (n) => generateThingHashMap(n).keys),
+      Benchmark(
+          'HashMap.Hard.values', size, (n) => generateThingHashMap(n).values),
+    ];
+  }
+
+  final benchmarks = [
+    BenchmarkConstMapIntKeys1(),
+    BenchmarkConstMapIntKeys2(),
+    BenchmarkConstMapIntKeys100(),
+    BenchmarkConstMapIntValues1(),
+    BenchmarkConstMapIntValues2(),
+    BenchmarkConstMapIntValues100(),
+    for (final size in allSizes) ...makeBenchmarksForSize(size),
+  ];
+
+  // Select benchmarks
+  final unusedSelectors = {...selectors};
+  for (final benchmark in benchmarks) {
+    final nameWords = benchmark.name.split('.').toSet();
+    for (final selector in selectors) {
+      final selectorWords = selector.split('.').toSet();
+      if (nameWords.containsAll(selectorWords)) {
+        unusedSelectors.remove(selector);
+        if (selectorWords.any(allSizeWords.contains) ||
+            sizes.contains(benchmark.size)) {
+          benchmark.selected = true;
+        }
+        // continue matching to remove other matching selectors.
+      }
+    }
+  }
+  if (unusedSelectors.isNotEmpty) {
+    throw ArgumentError(unusedSelectors, 'selectors match no benchmark');
+  }
+
+  // Warmup all benchmarks to ensure JIT compilers see full polymorphism.
+  for (var benchmark in benchmarks) {
+    pollute();
+    benchmark.setup();
+  }
+
+  // Warm up all the benchmarks, including the non-selected ones.
+  for (int i = 0; i < 10; i++) {
+    for (var benchmark in benchmarks) {
+      pollute();
+      final marker = Object();
+      sink = marker;
+      benchmark.warmup();
+      if (benchmark.size > 0 && identical(sink, marker)) throw 'unexpected';
+    }
+  }
+
+  for (var benchmark in benchmarks) {
+    // `report` calls `setup`, but `setup` is idempotent.
+    if (benchmark.selected) {
+      benchmark.report();
+    }
+  }
+}
diff --git a/benchmarks/Iterators/dart/data.dart b/benchmarks/Iterators/dart/data.dart
new file mode 100644
index 0000000..f59c26f
--- /dev/null
+++ b/benchmarks/Iterators/dart/data.dart
@@ -0,0 +1,177 @@
+// 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.
+
+Map<int, int> generateConstMapIntInt(int n) {
+  return constMapIntIntTable[n] ??
+      (throw ArgumentError.value(n, 'n', 'size not supported'));
+}
+
+Set<int> generateConstSetOfInt(int n) {
+  return constSetOfIntTable[n] ??
+      (throw ArgumentError.value(n, 'n', 'size not supported'));
+}
+
+List<int> generateConstListOfInt(int n) {
+  return constListOfIntTable[n] ??
+      (throw ArgumentError.value(n, 'n', 'size not supported'));
+}
+
+const Map<int, Map<int, int>> constMapIntIntTable = {
+  0: constMapIntInt0,
+  1: constMapIntInt1,
+  2: constMapIntInt2,
+  100: constMapIntInt100
+};
+
+const Map<int, int> constMapIntInt0 = {};
+const Map<int, int> constMapIntInt1 = {0: 0};
+const Map<int, int> constMapIntInt2 = {0: 0, 1: 1};
+const Map<int, int> constMapIntInt100 = {
+  0: 0,
+  1: 1,
+  2: 2,
+  3: 3,
+  4: 4,
+  5: 5,
+  6: 6,
+  7: 7,
+  8: 8,
+  9: 9,
+  10: 10,
+  11: 11,
+  12: 12,
+  13: 13,
+  14: 14,
+  15: 15,
+  16: 16,
+  17: 17,
+  18: 18,
+  19: 19,
+  20: 20,
+  21: 21,
+  22: 22,
+  23: 23,
+  24: 24,
+  25: 25,
+  26: 26,
+  27: 27,
+  28: 28,
+  29: 29,
+  30: 30,
+  31: 31,
+  32: 32,
+  33: 33,
+  34: 34,
+  35: 35,
+  36: 36,
+  37: 37,
+  38: 38,
+  39: 39,
+  40: 40,
+  41: 41,
+  42: 42,
+  43: 43,
+  44: 44,
+  45: 45,
+  46: 46,
+  47: 47,
+  48: 48,
+  49: 49,
+  50: 50,
+  51: 51,
+  52: 52,
+  53: 53,
+  54: 54,
+  55: 55,
+  56: 56,
+  57: 57,
+  58: 58,
+  59: 59,
+  60: 60,
+  61: 61,
+  62: 62,
+  63: 63,
+  64: 64,
+  65: 65,
+  66: 66,
+  67: 67,
+  68: 68,
+  69: 69,
+  70: 70,
+  71: 71,
+  72: 72,
+  73: 73,
+  74: 74,
+  75: 75,
+  76: 76,
+  77: 77,
+  78: 78,
+  79: 79,
+  80: 80,
+  81: 81,
+  82: 82,
+  83: 83,
+  84: 84,
+  85: 85,
+  86: 86,
+  87: 87,
+  88: 88,
+  89: 89,
+  90: 90,
+  91: 91,
+  92: 92,
+  93: 93,
+  94: 94,
+  95: 95,
+  96: 96,
+  97: 97,
+  98: 98,
+  99: 99
+};
+
+const Map<int, Set<int>> constSetOfIntTable = {
+  0: constSetOfInt0,
+  1: constSetOfInt1,
+  2: constSetOfInt2,
+  100: constSetOfInt100
+};
+
+const Set<int> constSetOfInt0 = {};
+const Set<int> constSetOfInt1 = {0};
+const Set<int> constSetOfInt2 = {0, 1};
+const Set<int> constSetOfInt100 = {
+  ...{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+  ...{10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
+  ...{20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
+  ...{30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
+  ...{40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
+  ...{50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
+  ...{60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
+  ...{70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
+  ...{80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
+  ...{90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
+};
+
+const Map<int, List<int>> constListOfIntTable = {
+  0: constListOfInt0,
+  1: constListOfInt1,
+  2: constListOfInt2,
+  100: constListOfInt100
+};
+
+const List<int> constListOfInt0 = [];
+const List<int> constListOfInt1 = [0];
+const List<int> constListOfInt2 = [0, 1];
+const List<int> constListOfInt100 = [
+  ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+  ...[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
+  ...[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
+  ...[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
+  ...[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
+  ...[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
+  ...[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
+  ...[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
+  ...[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
+  ...[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
+];
diff --git a/benchmarks/Iterators/dart2/Iterators.dart b/benchmarks/Iterators/dart2/Iterators.dart
new file mode 100644
index 0000000..cc03515
--- /dev/null
+++ b/benchmarks/Iterators/dart2/Iterators.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.
+
+// @dart=2.9
+
+import '../dart/Iterators.dart' as benchmark;
+
+void main(List<String> arguments) {
+  benchmark.main(arguments);
+}
diff --git a/benchmarks/OWNERS b/benchmarks/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/benchmarks/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/benchmarks/SDKArtifactSizes/dart/SDKArtifactSizes.dart b/benchmarks/SDKArtifactSizes/dart/SDKArtifactSizes.dart
index 733b711..13583e9 100644
--- a/benchmarks/SDKArtifactSizes/dart/SDKArtifactSizes.dart
+++ b/benchmarks/SDKArtifactSizes/dart/SDKArtifactSizes.dart
@@ -19,7 +19,6 @@
 const snapshots = <String>[
   'analysis_server',
   'dart2js',
-  'dart2native',
   'dartanalyzer',
   'dartdev',
   'dartdevc',
@@ -28,7 +27,6 @@
   'gen_kernel',
   'kernel-service',
   'kernel_worker',
-  'pub',
 ];
 
 void reportFileSize(String path, String name) {
diff --git a/benchmarks/SDKArtifactSizes/dart2/SDKArtifactSizes.dart b/benchmarks/SDKArtifactSizes/dart2/SDKArtifactSizes.dart
index f207e3a..ade286d 100644
--- a/benchmarks/SDKArtifactSizes/dart2/SDKArtifactSizes.dart
+++ b/benchmarks/SDKArtifactSizes/dart2/SDKArtifactSizes.dart
@@ -21,17 +21,14 @@
 const snapshots = <String>[
   'analysis_server',
   'dart2js',
-  'dart2native',
   'dartanalyzer',
   'dartdev',
   'dartdevc',
-  'dartdoc',
   'dds',
   'frontend_server',
   'gen_kernel',
   'kernel-service',
   'kernel_worker',
-  'pub',
 ];
 
 void reportFileSize(String path, String name) {
diff --git a/build/OWNERS b/build/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/build/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/build/config/OWNERS b/build/config/OWNERS
deleted file mode 100644
index bd53091..0000000
--- a/build/config/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-brettw@chromium.org
-dpranke@chromium.org
-scottmg@chromium.org
-
-per-file BUILDCONFIG.gn=brettw@chromium.org
-per-file BUILDCONFIG.gn=set noparent
diff --git a/build/mac/OWNERS b/build/mac/OWNERS
deleted file mode 100644
index c56e89d..0000000
--- a/build/mac/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-mark@chromium.org
-thomasvl@chromium.org
diff --git a/build/sanitizers/OWNERS b/build/sanitizers/OWNERS
deleted file mode 100644
index 0be2be8..0000000
--- a/build/sanitizers/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-glider@chromium.org
-earthdok@chromium.org
-per-file tsan_suppressions.cc=*
-per-file lsan_suppressions.cc=*
diff --git a/build/toolchain/OWNERS b/build/toolchain/OWNERS
deleted file mode 100644
index c6cda3f..0000000
--- a/build/toolchain/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-brettw@chromium.org
-dpranke@chromium.org
-scottmg@chromium.org
diff --git a/docs/OWNERS b/docs/OWNERS
new file mode 100644
index 0000000..22a2e82
--- /dev/null
+++ b/docs/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION
+file:/tools/OWNERS_PRODUCT
diff --git a/docs/process/breaking-changes.md b/docs/process/breaking-changes.md
index 4ea8bda..65d85f7 100644
--- a/docs/process/breaking-changes.md
+++ b/docs/process/breaking-changes.md
@@ -29,7 +29,7 @@
 
 * Must contain no static analysis **errors**.
 
-* Must not rely on a certain runtime **error** being thrown (in other words, 
+* Must not rely on a certain runtime **error** being thrown (in other words,
   a new SDK might throw fewer errors than an old SDK).
 
 * Must access libraries via the public API (for example, must not reach into
@@ -45,6 +45,13 @@
 Compatibility is only considered between stable releases (i.e. releases from the
 [Dart stable channel](https://dart.dev/tools/sdk/archive#stable-channel)).
 
+## Breaking change implementation timing
+
+To avoid shipping features that have not been thoroughly vetted, we implement a
+policy of not including breaking changes in the final beta before a release.
+Breaking changes must be included in the beta before the final beta to be
+considered for the next stable release.
+
 ## Breaking change notification
 
 Anyone wishing to make a breaking change to Dart is expected to perform the
@@ -76,7 +83,7 @@
   * A request that developers may leave comments in the linked issue, if this
     breaking change poses a severe problem.
 
-Once you have sent the announce email, please let devoncarew@ know in order
+Once you have sent the announce email, please let kevinjchisholm@ know in order
 to start the review and approval process.
 
 ### Step 2: Approval
diff --git a/pkg/OWNERS b/pkg/OWNERS
new file mode 100644
index 0000000..c3abcf9
--- /dev/null
+++ b/pkg/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION #{LAST_RESORT_SUGGESTION}
+file:/tools/OWNERS_INFRA #{LAST_RESORT_SUGGESTION}
diff --git a/pkg/_fe_analyzer_shared/OWNERS b/pkg/_fe_analyzer_shared/OWNERS
new file mode 100644
index 0000000..6fd2278
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_CFE
diff --git a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
index 24c5c54..310a360 100644
--- a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
@@ -19,3 +19,4 @@
     - test/inference/inferred_type_arguments/data/**
     - test/inference/inferred_variable_types/data/**
     - test/inheritance/data/**
+    - test/macros/api/**
diff --git a/pkg/_fe_analyzer_shared/benchmark/macros/serialization_benchmark.dart b/pkg/_fe_analyzer_shared/benchmark/macros/serialization_benchmark.dart
new file mode 100644
index 0000000..01cc969
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/benchmark/macros/serialization_benchmark.dart
@@ -0,0 +1,311 @@
+// 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 'dart:convert';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:typed_data';
+
+import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
+
+void main() async {
+  for (var serializationMode in [
+    SerializationMode.jsonClient,
+    SerializationMode.byteDataClient
+  ]) {
+    await withSerializationMode(serializationMode, () async {
+      await _isolateSpawnBenchmarks();
+      await _isolateSpawnUriBenchmarks();
+      await _separateProcessBenchmarks();
+    });
+  }
+}
+
+Future<void> _isolateSpawnBenchmarks() async {
+  void Function(SendPort) childIsolateFn(SerializationMode mode) =>
+      (SendPort sendPort) => withSerializationMode(mode, () {
+            var isolateReceivePort = ReceivePort();
+            isolateReceivePort.listen((data) {
+              deserialize(data);
+              var result = serialize();
+              result = result is Uint8List
+                  ? TransferableTypedData.fromList([result])
+                  : result;
+              sendPort.send(result);
+            });
+            sendPort.send(isolateReceivePort.sendPort);
+          });
+
+  Completer? responseCompleter;
+  late SendPort sendPort;
+
+  var receivePort = ReceivePort();
+
+  var isolate = await Isolate.spawn(
+      childIsolateFn(serializationMode), receivePort.sendPort);
+
+  final sendPortCompleter = Completer<SendPort>();
+  receivePort.listen((data) {
+    if (!sendPortCompleter.isCompleted) {
+      sendPortCompleter.complete(data);
+    } else {
+      responseCompleter!.complete(data);
+    }
+  });
+  sendPort = await sendPortCompleter.future;
+
+  // warmup
+  for (var i = 0; i < 100; i++) {
+    responseCompleter = Completer();
+    var result = serialize();
+    result =
+        result is Uint8List ? TransferableTypedData.fromList([result]) : result;
+    sendPort.send(result);
+    deserialize(await responseCompleter.future);
+  }
+  // measure
+  var watch = Stopwatch()..start();
+  for (var i = 0; i < 100; i++) {
+    responseCompleter = Completer();
+    var result = serialize();
+    result =
+        result is Uint8List ? TransferableTypedData.fromList([result]) : result;
+    sendPort.send(result);
+    deserialize(await responseCompleter.future);
+  }
+  print('Isolate.spawn + $serializationMode: ${watch.elapsed}');
+
+  receivePort.close();
+  isolate.kill();
+}
+
+Future<void> _isolateSpawnUriBenchmarks() async {
+  Completer? responseCompleter;
+  late SendPort sendPort;
+
+  var receivePort = ReceivePort();
+
+  var isolate = await Isolate.spawnUri(
+      Uri.dataFromString(childProgram(serializationMode)),
+      [],
+      receivePort.sendPort);
+
+  final sendPortCompleter = Completer<SendPort>();
+  receivePort.listen((data) {
+    if (!sendPortCompleter.isCompleted) {
+      sendPortCompleter.complete(data);
+    } else {
+      responseCompleter!.complete(data);
+    }
+  });
+  sendPort = await sendPortCompleter.future;
+
+  // warmup
+  for (var i = 0; i < 100; i++) {
+    responseCompleter = Completer();
+    var result = serialize();
+    result =
+        result is Uint8List ? TransferableTypedData.fromList([result]) : result;
+    sendPort.send(result);
+    deserialize(await responseCompleter.future);
+  }
+  // measure
+  var watch = Stopwatch()..start();
+  for (var i = 0; i < 100; i++) {
+    responseCompleter = Completer();
+    var result = serialize();
+    result =
+        result is Uint8List ? TransferableTypedData.fromList([result]) : result;
+    sendPort.send(result);
+    deserialize(await responseCompleter.future);
+  }
+  print('Isolate.spawnUri + $serializationMode: ${watch.elapsed}');
+
+  receivePort.close();
+  isolate.kill();
+}
+
+Future<void> _separateProcessBenchmarks() async {
+  Completer? responseCompleter;
+
+  var tmpDir = Directory.systemTemp.createTempSync('serialize_bench');
+  try {
+    var file = File(tmpDir.uri.resolve('main.dart').toFilePath());
+    file.writeAsStringSync(childProgram(serializationMode));
+    var process = await Process.start(Platform.resolvedExecutable, [
+      '--packages=' + (await Isolate.packageConfig)!.toFilePath(),
+      file.path,
+    ]);
+
+    var listeners = <StreamSubscription>[
+      process.stderr.listen((event) {
+        print('stderr: ${utf8.decode(event)}');
+      }),
+      process.stdout.listen((data) {
+        responseCompleter!.complete(data);
+      }),
+    ];
+
+    // warmup
+    for (var i = 0; i < 100; i++) {
+      responseCompleter = Completer();
+      var result = serialize();
+      if (result is List<int>) {
+        process.stdin.add(result);
+      } else {
+        process.stdin.writeln(jsonEncode(result));
+      }
+      deserialize(await responseCompleter.future);
+    }
+    // measure
+    var watch = Stopwatch()..start();
+    for (var i = 0; i < 100; i++) {
+      responseCompleter = Completer();
+      var result = serialize();
+      if (result is List<int>) {
+        process.stdin.add(result);
+      } else {
+        process.stdin.writeln(jsonEncode(result));
+      }
+      deserialize(await responseCompleter.future);
+    }
+    print('Separate process + $serializationMode: ${watch.elapsed}');
+
+    listeners.forEach((l) => l.cancel());
+    process.kill();
+  } catch (e, s) {
+    print('Error running benchmark \n$e\n\n$s');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
+
+String childProgram(SerializationMode mode) => '''
+      import 'dart:convert';
+      import 'dart:io';
+      import 'dart:isolate';
+      import 'dart:typed_data';
+
+      import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
+
+      void main(_, [SendPort? sendPort]) {
+        var mode = $mode;
+        withSerializationMode(mode, () {
+          if (sendPort != null) {
+              var isolateReceivePort = ReceivePort();
+              isolateReceivePort.listen((data) {
+                deserialize(data);
+                var result = serialize();
+                result = result is Uint8List
+                    ? TransferableTypedData.fromList([result])
+                    : result;
+                sendPort.send(result);
+              });
+              sendPort.send(isolateReceivePort.sendPort);
+          } else {
+            // We allow one empty line to work around some weird data.
+            var allowEmpty = true;
+            stdin.listen((data) {
+              if (mode == SerializationMode.jsonClient || mode == SerializationMode.jsonServer) {
+                var json = utf8.decode(data).trimRight();
+                // On exit we tend to get extra empty lines sometimes?
+                if (json.isEmpty && allowEmpty) {
+                  allowEmpty = false;
+                  return;
+                }
+                deserialize(jsonDecode(json));
+                stdout.write(jsonEncode(serialize()));
+              } else {
+                deserialize(data);
+                stdout.add(serialize() as List<int>);
+              }
+            });
+          }
+        });
+      }
+
+      Object? serialize() {
+        var serializer = serializerFactory();
+        for (var i = 0; i < 100; i++) {
+          serializer.addInt(i * 100);
+          serializer.addString('foo' * i);
+          serializer.addBool(i % 2 == 0);
+          serializer.startList();
+          for (var j = 0; j < 10; j++) {
+            serializer.addDouble(i * 5);
+          }
+          serializer.endList();
+          serializer.addNull();
+        }
+        return serializer.result;
+      }
+
+      void deserialize(Object? result) {
+        result = result is TransferableTypedData
+            ? result.materialize().asUint8List()
+            : result;
+        var deserializer = deserializerFactory(result);
+        while (deserializer.moveNext()) {
+          deserializer
+            ..expectInt()
+            ..moveNext()
+            ..expectString()
+            ..moveNext()
+            ..expectBool()
+            ..moveNext()
+            ..expectList();
+          while (deserializer.moveNext()) {
+            deserializer.expectDouble();
+          }
+          deserializer
+            ..moveNext()
+            ..checkNull();
+        }
+      }''';
+
+Object? serialize() {
+  var serializer = serializerFactory();
+  for (var i = -50; i < 50; i++) {
+    serializer.addInt(i % 2 * 100);
+    serializer.addString('foo' * i);
+    serializer.addBool(i < 0);
+    serializer.startList();
+    for (var j = 0.0; j < 10; j++) {
+      serializer.addDouble(i * j);
+    }
+    serializer.endList();
+    serializer.addNull();
+  }
+  return serializer.result;
+}
+
+void deserialize(Object? result) {
+  result = result is TransferableTypedData
+      ? result.materialize().asUint8List()
+      : result;
+  if (serializationMode == SerializationMode.jsonClient ||
+      serializationMode == SerializationMode.jsonServer) {
+    if (result is List<int>) {
+      result = jsonDecode(utf8.decode(result));
+    }
+  }
+  var deserializer = deserializerFactory(result);
+  while (deserializer.moveNext()) {
+    deserializer
+      ..expectInt()
+      ..moveNext()
+      ..expectString()
+      ..moveNext()
+      ..expectBool()
+      ..moveNext()
+      ..expectList();
+    while (deserializer.moveNext()) {
+      deserializer.expectDouble();
+    }
+    deserializer
+      ..moveNext()
+      ..checkNull();
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
index f10269c..03669ef 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -8,11 +8,28 @@
 /// as augment existing ones.
 abstract class Builder {}
 
+/// Allows you to resolve arbitrary [Identifier]s.
+///
+/// This class will likely disappear entirely once we have a different
+/// mechanism.
+abstract class IdentifierResolver {
+  /// Returns an [Identifier] for a top level [name] in [library].
+  ///
+  /// You should only do this for libraries that are definitely in the
+  /// transitive import graph of the library you are generating code into.
+  @Deprecated(
+      'This api should eventually be replaced with a different, safer API.')
+  Future<Identifier> resolveIdentifier(Uri library, String name);
+}
+
 /// The api used by [Macro]s to contribute new type declarations to the
 /// current library, and get [TypeAnnotation]s from runtime [Type] objects.
-abstract class TypeBuilder implements Builder {
+abstract class TypeBuilder implements Builder, IdentifierResolver {
   /// Adds a new type declaration to the surrounding library.
-  void declareType(DeclarationCode typeDeclaration);
+  ///
+  /// The [name] must match the name of the new [typeDeclaration] (this does
+  /// not include any type parameters, just the name).
+  void declareType(String name, DeclarationCode typeDeclaration);
 }
 
 /// The interface used to create [StaticType] instances, which are used to
@@ -21,21 +38,14 @@
 /// This api is only available to the declaration and definition phases of
 /// macro expansion.
 abstract class TypeResolver {
-  /// Resolves [typeAnnotation] to a [StaticType].
+  /// Instantiates a new [StaticType] for a given [type] annotation.
   ///
-  /// Throws an error if the type annotation cannot be resolved. This should
-  /// only happen in the case of incomplete or invalid programs, but macros
-  /// may be asked to run in this state during the development cycle. It is
-  /// helpful for users if macros provide a best effort implementation in that
-  /// case or handle the error in a useful way.
-  Future<StaticType> instantiateType(covariant TypeAnnotation typeAnnotation);
-
-  /// Instantiates a new [StaticType] for a given [code] expression, which must
-  /// be a type expression.
-  ///
-  /// All type identifiers in [code] must be instances of [Identifier] and not
-  /// bare strings.
-  Future<StaticType> instantiateCode(ExpressionCode code);
+  /// Throws an error if the [type] object contains [Identifier]s which cannot
+  /// be resolved. This should only happen in the case of incomplete or invalid
+  /// programs, but macros may be asked to run in this state during the
+  /// development cycle. It may be helpful for users if macros provide a best
+  /// effort implementation in that case or handle the error in a useful way.
+  Future<StaticType> resolve(TypeAnnotationCode type);
 }
 
 /// The api used to introspect on a [ClassDeclaration].
@@ -79,7 +89,7 @@
 ///
 /// Can also be used to do subtype checks on types.
 abstract class DeclarationBuilder
-    implements Builder, TypeResolver, ClassIntrospector {
+    implements Builder, IdentifierResolver, TypeResolver, ClassIntrospector {
   /// Adds a new regular declaration to the surrounding library.
   ///
   /// Note that type declarations are not supported.
@@ -110,6 +120,7 @@
 abstract class DefinitionBuilder
     implements
         Builder,
+        IdentifierResolver,
         TypeResolver,
         ClassIntrospector,
         TypeDeclarationResolver {}
@@ -117,19 +128,19 @@
 /// The apis used by [Macro]s that run on classes, to fill in the definitions
 /// of any external declarations within that class.
 abstract class ClassDefinitionBuilder implements DefinitionBuilder {
-  /// Retrieve a [VariableDefinitionBuilder] for a field by [identifier].
+  /// Retrieve a [VariableDefinitionBuilder] for a field with [identifier].
   ///
   /// Throws an [ArgumentError] if [identifier] does not refer to a field in
   /// this class.
   Future<VariableDefinitionBuilder> buildField(Identifier identifier);
 
-  /// Retrieve a [FunctionDefinitionBuilder] for a method by [identifier].
+  /// Retrieve a [FunctionDefinitionBuilder] for a method with [identifier].
   ///
   /// Throws an [ArgumentError] if [identifier] does not refer to a method in
   /// this class.
   Future<FunctionDefinitionBuilder> buildMethod(Identifier identifier);
 
-  /// Retrieve a [ConstructorDefinitionBuilder] for a constructor by
+  /// Retrieve a [ConstructorDefinitionBuilder] for a constructor with
   /// [identifier].
   ///
   /// Throws an [ArgumentError] if [identifier] does not refer to a constructor
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart
index e7af1bd..6563aef 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart
@@ -32,18 +32,6 @@
   DeclarationCode.fromParts(List<Object> parts) : super.fromParts(parts);
 }
 
-/// A piece of code representing a syntactically valid element.
-///
-/// Should not include any trailing commas,
-class ElementCode extends Code {
-  @override
-  CodeKind get kind => CodeKind.element;
-
-  ElementCode.fromString(String code) : super.fromString(code);
-
-  ElementCode.fromParts(List<Object> parts) : super.fromParts(parts);
-}
-
 /// A piece of code representing a syntactically valid expression.
 class ExpressionCode extends Code {
   @override
@@ -69,67 +57,200 @@
   FunctionBodyCode.fromParts(List<Object> parts) : super.fromParts(parts);
 }
 
-/// A piece of code identifying a named argument.
-///
-/// This should not include any trailing commas.
-class NamedArgumentCode extends Code {
-  @override
-  CodeKind get kind => CodeKind.namedArgument;
-
-  NamedArgumentCode.fromString(String code) : super.fromString(code);
-
-  NamedArgumentCode.fromParts(List<Object> parts) : super.fromParts(parts);
-}
-
 /// A piece of code identifying a syntactically valid function parameter.
 ///
-/// This should not include any trailing commas, but may include modifiers
-/// such as `required`, and default values.
+/// There is no distinction here made between named and positional parameters.
 ///
-/// There is no distinction here made between named and positional parameters,
-/// nor between optional or required parameters. It is the job of the user to
-/// construct and combine these together in a way that creates valid parameter
-/// lists.
-class ParameterCode extends Code {
+/// It is the job of the user to construct and combine these together in a way
+/// that creates valid parameter lists.
+class ParameterCode implements Code {
+  final Code? defaultValue;
+  final List<String> keywords;
+  final String name;
+  final TypeAnnotationCode? type;
+
   @override
   CodeKind get kind => CodeKind.parameter;
 
-  ParameterCode.fromString(String code) : super.fromString(code);
-
-  ParameterCode.fromParts(List<Object> parts) : super.fromParts(parts);
-}
-
-/// A piece of code representing a syntactically valid statement.
-///
-/// Should always end with a semicolon.
-class StatementCode extends Code {
   @override
-  CodeKind get kind => CodeKind.statement;
+  List<Object> get parts => [
+        if (keywords.isNotEmpty) ...[
+          ...keywords.joinAsCode(' '),
+          ' ',
+        ],
+        if (type != null) ...[
+          type!,
+          ' ',
+        ],
+        name,
+        if (defaultValue != null) ...[
+          ' = ',
+          defaultValue!,
+        ]
+      ];
 
-  StatementCode.fromString(String code) : super.fromString(code);
-
-  StatementCode.fromParts(List<Object> parts) : super.fromParts(parts);
+  ParameterCode({
+    this.defaultValue,
+    this.keywords = const [],
+    required this.name,
+    this.type,
+  });
 }
 
-extension Join<T extends Code> on List<T> {
+/// A piece of code representing a type annotation.
+abstract class TypeAnnotationCode implements Code {
+  /// Returns a [TypeAnnotationCode] object which is a non-nullable version
+  /// of this one.
+  ///
+  /// Returns the current instance if it is already non-nullable.
+  TypeAnnotationCode get asNonNullable => this;
+
+  /// Returns a [TypeAnnotationCode] object which is a non-nullable version
+  /// of this one.
+  ///
+  /// Returns the current instance if it is already nullable.
+  NullableTypeAnnotationCode get asNullable =>
+      new NullableTypeAnnotationCode(this);
+
+  /// Whether or not this type is nullable.
+  bool get isNullable => false;
+}
+
+/// The nullable version of an underlying type annotation.
+class NullableTypeAnnotationCode implements TypeAnnotationCode {
+  /// The underlying type that is being made nullable.
+  TypeAnnotationCode underlyingType;
+
+  @override
+  CodeKind get kind => CodeKind.nullableTypeAnnotation;
+
+  @override
+  List<Object> get parts => [...underlyingType.parts, '?'];
+
+  /// Creates a nullable [underlyingType] annotation.
+  ///
+  /// If [underlyingType] is a NullableTypeAnnotationCode, returns that
+  /// same type.
+  NullableTypeAnnotationCode(this.underlyingType);
+
+  @override
+  TypeAnnotationCode get asNonNullable => underlyingType;
+
+  @override
+  NullableTypeAnnotationCode get asNullable => this;
+
+  @override
+  bool get isNullable => true;
+}
+
+/// A piece of code representing a reference to a named type.
+class NamedTypeAnnotationCode extends TypeAnnotationCode {
+  final Identifier name;
+
+  final List<TypeAnnotationCode> typeArguments;
+
+  @override
+  CodeKind get kind => CodeKind.namedTypeAnnotation;
+
+  @override
+  List<Object> get parts => [
+        name,
+        if (typeArguments.isNotEmpty) ...[
+          '<',
+          ...typeArguments.joinAsCode(', '),
+          '>',
+        ],
+      ];
+
+  NamedTypeAnnotationCode({required this.name, this.typeArguments = const []});
+}
+
+/// A piece of code representing a function type annotation.
+class FunctionTypeAnnotationCode extends TypeAnnotationCode {
+  final List<ParameterCode> namedParameters;
+
+  final List<ParameterCode> positionalParameters;
+
+  final TypeAnnotationCode? returnType;
+
+  final List<TypeParameterCode> typeParameters;
+
+  @override
+  CodeKind get kind => CodeKind.functionTypeAnnotation;
+
+  @override
+  List<Object> get parts => [
+        if (returnType != null) returnType!,
+        ' Function',
+        if (typeParameters.isNotEmpty) ...[
+          '<',
+          ...typeParameters.joinAsCode(', '),
+          '>',
+        ],
+        '(',
+        for (ParameterCode positional in positionalParameters) ...[
+          positional,
+          ', ',
+        ],
+        if (namedParameters.isNotEmpty) ...[
+          '{',
+          for (ParameterCode named in namedParameters) ...[
+            named,
+            ', ',
+          ],
+          '}',
+        ],
+        ')',
+      ];
+
+  FunctionTypeAnnotationCode({
+    this.namedParameters = const [],
+    this.positionalParameters = const [],
+    this.returnType,
+    this.typeParameters = const [],
+  });
+}
+
+/// A piece of code representing a valid named type parameter.
+class TypeParameterCode implements Code {
+  final TypeAnnotationCode? bound;
+  final String name;
+
+  @override
+  CodeKind get kind => CodeKind.typeParameter;
+
+  @override
+  List<Object> get parts => [
+        name,
+        if (bound != null) ...[
+          ' extends ',
+          bound!,
+        ]
+      ];
+
+  TypeParameterCode({this.bound, required this.name});
+}
+
+extension Join<T extends Object> on List<T> {
   /// Joins all the items in [this] with [separator], and returns
   /// a new list.
-  List<Code> joinAsCode(String separator) => [
+  List<Object> joinAsCode(String separator) => [
         for (int i = 0; i < length - 1; i++) ...[
           this[i],
-          new Code.fromString(separator),
+          separator,
         ],
         last,
       ];
 }
 
 enum CodeKind {
-  raw,
   declaration,
-  element,
   expression,
   functionBody,
-  namedArgument,
+  functionTypeAnnotation,
+  namedTypeAnnotation,
+  nullableTypeAnnotation,
   parameter,
-  statement,
+  raw,
+  typeParameter,
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
index 11fd6c3..c24cd91 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -24,10 +24,9 @@
   /// trailing `?`)
   bool get isNullable;
 
-  /// A convenience method to get a [Code] object representation of this full
-  /// type annotation, including support for generic type arguments as well as
-  /// function types.
-  Code get code;
+  /// A convenience method to get a [Code] object equivalent to this type
+  /// annotation.
+  TypeAnnotationCode get code;
 }
 
 /// The base class for function type declarations.
@@ -83,6 +82,9 @@
 abstract class ClassMemberDeclaration implements Declaration {
   /// The class that defines this method.
   Identifier get definingClass;
+
+  /// Whether or not this is a static member.
+  bool get isStatic;
 }
 
 /// A declaration that defines a new type in the program.
@@ -131,6 +133,9 @@
   /// Whether this function has an `external` modifier.
   bool get isExternal;
 
+  /// Whether this function is an operator.
+  bool get isOperator;
+
   /// Whether this function is actually a getter.
   bool get isGetter;
 
@@ -173,10 +178,6 @@
 
   /// The type of this field.
   TypeAnnotation get type;
-
-  /// A [ExpressionCode] object representing the initializer for this field, if
-  /// present.
-  ExpressionCode? get initializer;
 }
 
 /// Field introspection information.
@@ -195,13 +196,19 @@
   /// parameter or an optional parameter with the `required` keyword.
   bool get isRequired;
 
-  /// A [Code] object representing the default value for this parameter, if
-  /// present. Can be used to copy default values to other parameters.
-  Code? get defaultValue;
+  /// A convenience method to get a `code` object equivalent to this parameter.
+  ///
+  /// Note that the original default value will not be included, as it is not a
+  /// part of this API.
+  ParameterCode get code;
 }
 
 /// Type parameter introspection information.
 abstract class TypeParameterDeclaration implements Declaration {
-  /// The bounds for this type parameter, if it has any.
-  TypeAnnotation? get bounds;
+  /// The bound for this type parameter, if it has any.
+  TypeAnnotation? get bound;
+
+  /// A convenience method to get a `code` object equivalent to this type
+  /// parameter.
+  TypeParameterCode get code;
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index f604c80..a645eae 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -2,14 +2,24 @@
 // for 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 'executor/serialization.dart'
+    show SerializationMode, SerializationModeHelpers;
+
 /// Generates a Dart program for a given set of macros, which can be compiled
 /// and then passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
 ///
 /// The [macroDeclarations] is a map from library URIs to macro classes for the
 /// macros supported. The macro classes are provided as a map from macro class
 /// names to the names of the macro class constructors.
+///
+/// The [serializationMode] must be a client variant.
 String bootstrapMacroIsolate(
-    Map<String, Map<String, List<String>>> macroDeclarations) {
+    Map<String, Map<String, List<String>>> macroDeclarations,
+    SerializationMode serializationMode) {
+  if (!serializationMode.isClient) {
+    throw new ArgumentError(
+        'Got $serializationMode but expected a client version.');
+  }
   StringBuffer imports = new StringBuffer();
   StringBuffer constructorEntries = new StringBuffer();
   macroDeclarations
@@ -26,75 +36,119 @@
       constructorEntries.writeln('},');
     });
   });
-  return template.replaceFirst(_importMarker, imports.toString()).replaceFirst(
-      _macroConstructorEntriesMarker, constructorEntries.toString());
+  return template
+      .replaceFirst(_importMarker, imports.toString())
+      .replaceFirst(
+          _macroConstructorEntriesMarker, constructorEntries.toString())
+      .replaceFirst(_modeMarker, serializationMode.asCode);
 }
 
 const String _importMarker = '{{IMPORT}}';
 const String _macroConstructorEntriesMarker = '{{MACRO_CONSTRUCTOR_ENTRIES}}';
+const String _modeMarker = '{{SERIALIZATION_MODE}}';
 
 const String template = '''
 import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
 import 'dart:isolate';
+import 'dart:typed_data';
 
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/execute_macro.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/response_impls.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/serialization.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/protocol.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/execute_macro.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/introspection_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/message_grouper.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/remote_instance.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/response_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/protocol.dart';
 import 'package:_fe_analyzer_shared/src/macros/executor.dart';
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 
 $_importMarker
 
-/// Entrypoint to be spawned with [Isolate.spawnUri].
+/// Entrypoint to be spawned with [Isolate.spawnUri] or [Process.start].
 ///
 /// Supports the client side of the macro expansion protocol.
-void main(_, SendPort sendPort) {
-  /// Local function that sends requests and returns responses using [sendPort].
-  Future<Response> sendRequest(Request request) => _sendRequest(request, sendPort);
+void main(_, [SendPort? sendPort]) {
+  // Function that sends the result of a [Serializer] using either [sendPort]
+  // or [stdout].
+  void Function(Serializer) sendResult;
 
-  withSerializationMode(SerializationMode.client, () {
-    ReceivePort receivePort = new ReceivePort();
-    sendPort.send(receivePort.sendPort);
+  // The stream for incoming messages, could be either a ReceivePort or stdin.
+  Stream<Object?> messageStream;
 
-    receivePort.listen((message) async {
-      var deserializer = JsonDeserializer(message as Iterable<Object?>)
-          ..moveNext();
-      int zoneId = deserializer.expectNum();
-      deserializer..moveNext();
-      var type = MessageType.values[deserializer.expectNum()];
-      var serializer = JsonSerializer();
-      switch (type) {
-        case MessageType.instantiateMacroRequest:
-          var request = new InstantiateMacroRequest.deserialize(deserializer, zoneId);
-          (await _instantiateMacro(request)).serialize(serializer);
-          break;
-        case MessageType.executeDeclarationsPhaseRequest:
-          var request = new ExecuteDeclarationsPhaseRequest.deserialize(deserializer, zoneId);
-          (await _executeDeclarationsPhase(request, sendRequest)).serialize(serializer);
-          break;
-        case MessageType.executeDefinitionsPhaseRequest:
-          var request = new ExecuteDefinitionsPhaseRequest.deserialize(deserializer, zoneId);
-          (await _executeDefinitionsPhase(request, sendRequest)).serialize(serializer);
-          break;
-        case MessageType.executeTypesPhaseRequest:
-          var request = new ExecuteTypesPhaseRequest.deserialize(deserializer, zoneId);
-          (await _executeTypesPhase(request, sendRequest)).serialize(serializer);
-          break;
-        case MessageType.response:
-          var response = new SerializableResponse.deserialize(deserializer, zoneId);
-          _responseCompleters.remove(response.requestId)!.complete(response);
-          return;
-        default:
-          throw new StateError('Unhandled event type \$type');
+  withSerializationMode($_modeMarker, () {
+    if (sendPort != null) {
+      ReceivePort receivePort = new ReceivePort();
+      messageStream = receivePort;
+      sendResult = (Serializer serializer) =>
+          _sendIsolateResult(serializer, sendPort);
+      // If using isolate communication, first send a sendPort to the parent
+      // isolate.
+      sendPort.send(receivePort.sendPort);
+    } else {
+      sendResult = _sendStdoutResult;
+      if (serializationMode == SerializationMode.byteDataClient) {
+        messageStream = MessageGrouper(stdin).messageStream;
+      } else if (serializationMode == SerializationMode.jsonClient) {
+        messageStream = stdin
+          .transform(const Utf8Decoder())
+          .transform(const LineSplitter())
+          .map((line) => jsonDecode(line)!);
+      } else {
+        throw new UnsupportedError(
+            'Unsupported serialization mode \$serializationMode for '
+            'ProcessExecutor');
       }
-      sendPort.send(serializer.result);
-    });
+    }
+
+    messageStream.listen((message) => _handleMessage(message, sendResult));
   });
 }
 
+void _handleMessage(
+    Object? message, void Function(Serializer) sendResult) async {
+  // Serializes `request` and send it using `sendResult`.
+  Future<Response> sendRequest(Request request) =>
+      _sendRequest(request, sendResult);
+
+  if (serializationMode == SerializationMode.byteDataClient
+      && message is TransferableTypedData) {
+    message = message.materialize().asUint8List();
+  }
+  var deserializer = deserializerFactory(message)
+      ..moveNext();
+  int zoneId = deserializer.expectInt();
+  deserializer..moveNext();
+  var type = MessageType.values[deserializer.expectInt()];
+  var serializer = serializerFactory();
+  switch (type) {
+    case MessageType.instantiateMacroRequest:
+      var request = new InstantiateMacroRequest.deserialize(deserializer, zoneId);
+      (await _instantiateMacro(request)).serialize(serializer);
+      break;
+    case MessageType.executeDeclarationsPhaseRequest:
+      var request = new ExecuteDeclarationsPhaseRequest.deserialize(deserializer, zoneId);
+      (await _executeDeclarationsPhase(request, sendRequest)).serialize(serializer);
+      break;
+    case MessageType.executeDefinitionsPhaseRequest:
+      var request = new ExecuteDefinitionsPhaseRequest.deserialize(deserializer, zoneId);
+      (await _executeDefinitionsPhase(request, sendRequest)).serialize(serializer);
+      break;
+    case MessageType.executeTypesPhaseRequest:
+      var request = new ExecuteTypesPhaseRequest.deserialize(deserializer, zoneId);
+      (await _executeTypesPhase(request, sendRequest)).serialize(serializer);
+      break;
+    case MessageType.response:
+      var response = new SerializableResponse.deserialize(deserializer, zoneId);
+      _responseCompleters.remove(response.requestId)!.complete(response);
+      return;
+    default:
+      throw new StateError('Unhandled event type \$type');
+  }
+  sendResult(serializer);
+}
+
 /// Maps macro identifiers to constructors.
 final _macroConstructors = <MacroClassIdentifierImpl, Map<String, Macro Function()>>{
   $_macroConstructorEntriesMarker
@@ -122,7 +176,7 @@
       for (MapEntry<String, Object?> entry in request.arguments.named.entries)
         new Symbol(entry.key): entry.value,
     }) as Macro;
-    var identifier = new MacroInstanceIdentifierImpl(instance);
+    var identifier = new MacroInstanceIdentifierImpl(instance, request.instanceId);
     _macroInstances[identifier] = instance;
     return new SerializableResponse(
         responseType: MessageType.macroInstanceIdentifier,
@@ -148,8 +202,13 @@
       throw new StateError('Unrecognized macro instance \${request.macro}\\n'
           'Known instances: \$_macroInstances)');
     }
+    var identifierResolver = ClientIdentifierResolver(
+        sendRequest,
+        remoteInstance: request.identifierResolver,
+        serializationZoneId: request.serializationZoneId);
 
-    var result = await executeTypesMacro(instance, request.declaration);
+    var result = await executeTypesMacro(
+        instance, request.declaration, identifierResolver);
     return new SerializableResponse(
         responseType: MessageType.macroExecutionResult,
         response: result,
@@ -174,6 +233,10 @@
       throw new StateError('Unrecognized macro instance \${request.macro}\\n'
           'Known instances: \$_macroInstances)');
     }
+    var identifierResolver = ClientIdentifierResolver(
+        sendRequest,
+        remoteInstance: request.identifierResolver,
+        serializationZoneId: request.serializationZoneId);
     var classIntrospector = ClientClassIntrospector(
         sendRequest,
         remoteInstance: request.classIntrospector,
@@ -184,7 +247,8 @@
         serializationZoneId: request.serializationZoneId);
 
     var result = await executeDeclarationsMacro(
-        instance, request.declaration, classIntrospector, typeResolver);
+        instance, request.declaration, identifierResolver, classIntrospector,
+        typeResolver);
     return new SerializableResponse(
         responseType: MessageType.macroExecutionResult,
         response: result,
@@ -209,6 +273,10 @@
       throw new StateError('Unrecognized macro instance \${request.macro}\\n'
           'Known instances: \$_macroInstances)');
     }
+    var identifierResolver = ClientIdentifierResolver(
+        sendRequest,
+        remoteInstance: request.identifierResolver,
+        serializationZoneId: request.serializationZoneId);
     var typeResolver = ClientTypeResolver(
         sendRequest,
         remoteInstance: request.typeResolver,
@@ -223,8 +291,8 @@
         serializationZoneId: request.serializationZoneId);
 
     var result = await executeDefinitionMacro(
-        instance, request.declaration, classIntrospector, typeResolver,
-        typeDeclarationResolver);
+        instance, request.declaration, identifierResolver, classIntrospector,
+        typeResolver, typeDeclarationResolver);
     return new SerializableResponse(
         responseType: MessageType.macroExecutionResult,
         response: result,
@@ -243,15 +311,50 @@
 /// Holds on to response completers by request id.
 final _responseCompleters = <int, Completer<Response>>{};
 
-/// Serializes [request], sends it to [sendPort], and sets up a [Completer] in
-/// [_responseCompleters] to handle the response.
-Future<Response> _sendRequest(Request request, SendPort sendPort) {
+/// Serializes [request], passes it to [sendResult], and sets up a [Completer]
+/// in [_responseCompleters] to handle the response.
+Future<Response> _sendRequest(
+    Request request, void Function(Serializer serializer) sendResult) {
   Completer<Response> completer = Completer();
   _responseCompleters[request.id] = completer;
-  JsonSerializer serializer = JsonSerializer();
-  serializer.addNum(request.serializationZoneId);
+  Serializer serializer = serializerFactory();
+  serializer.addInt(request.serializationZoneId);
   request.serialize(serializer);
-  sendPort.send(serializer.result);
+  sendResult(serializer);
   return completer.future;
 }
+
+/// Sends [serializer.result] to [sendPort], possibly wrapping it in a
+/// [TransferableTypedData] object.
+void _sendIsolateResult(Serializer serializer, SendPort sendPort) {
+  if (serializationMode == SerializationMode.byteDataClient) {
+    sendPort.send(
+        TransferableTypedData.fromList([serializer.result as Uint8List]));
+  } else {
+    sendPort.send(serializer.result);
+  }
+}
+
+/// Sends [serializer.result] to [stdout].
+///
+/// Serializes the result to a string if using JSON.
+void _sendStdoutResult(Serializer serializer) {
+  if (serializationMode == SerializationMode.jsonClient) {
+    stdout.writeln(jsonEncode(serializer.result));
+  } else if (serializationMode == SerializationMode.byteDataClient) {
+    Uint8List result = (serializer as ByteDataSerializer).result;
+    int length = result.lengthInBytes;
+    stdout.add([
+      length >> 24 & 0xff,
+      length >> 16 & 0xff,
+      length >> 8 & 0xff,
+      length & 0xff,
+    ]);
+    stdout.add(result);
+  } else {
+    throw new UnsupportedError(
+        'Unsupported serialization mode \$serializationMode for '
+        'ProcessExecutor');
+  }
+}
 ''';
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
index a4c2df3..c80c9a5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
@@ -4,16 +4,7 @@
 
 import 'api.dart';
 import 'bootstrap.dart'; // For doc comments only.
-import 'executor_shared/serialization.dart';
-
-/// Exposes a platform specific [MacroExecutor], through a top level
-/// `Future<MacroExecutor> start()` function.
-///
-/// TODO: conditionally load isolate_mirrors_executor.dart once conditional
-/// imports of mirrors are supported in AOT (issue #48057).
-import 'fake_executor/fake_executor.dart'
-    if (dart.library.isolate) 'isolated_executor/isolated_executor.dart'
-    as executor_impl show start;
+import 'executor/serialization.dart';
 
 /// The interface used by Dart language implementations, in order to load
 /// and execute macros, as well as produce library augmentations from those
@@ -23,14 +14,6 @@
 /// during macro discovery and expansion, and unifies how augmentation libraries
 /// are produced.
 abstract class MacroExecutor {
-  /// Returns a platform specific [MacroExecutor]. On unsupported platforms this
-  /// will be a fake executor object, which will throw an [UnsupportedError] if
-  /// used.
-  ///
-  /// Note that some implementations will also require calls to [loadMacro]
-  /// to pass a `precompiledKernelUri`.
-  static Future<MacroExecutor> start() => executor_impl.start();
-
   /// Invoked when an implementation discovers a new macro definition in a
   /// [library] with [name], and prepares this executor to run the macro.
   ///
@@ -61,8 +44,8 @@
   /// Runs the type phase for [macro] on a given [declaration].
   ///
   /// Throws an exception if there is an error executing the macro.
-  Future<MacroExecutionResult> executeTypesPhase(
-      MacroInstanceIdentifier macro, covariant Declaration declaration);
+  Future<MacroExecutionResult> executeTypesPhase(MacroInstanceIdentifier macro,
+      covariant Declaration declaration, IdentifierResolver identifierResolver);
 
   /// Runs the declarations phase for [macro] on a given [declaration].
   ///
@@ -70,6 +53,7 @@
   Future<MacroExecutionResult> executeDeclarationsPhase(
       MacroInstanceIdentifier macro,
       covariant Declaration declaration,
+      IdentifierResolver identifierResolver,
       TypeResolver typeResolver,
       ClassIntrospector classIntrospector);
 
@@ -79,14 +63,18 @@
   Future<MacroExecutionResult> executeDefinitionsPhase(
       MacroInstanceIdentifier macro,
       covariant Declaration declaration,
+      IdentifierResolver identifierResolver,
       TypeResolver typeResolver,
       ClassIntrospector classIntrospector,
       TypeDeclarationResolver typeDeclarationResolver);
 
   /// Combines multiple [MacroExecutionResult]s into a single library
   /// augmentation file, and returns a [String] representing that file.
-  Future<String> buildAugmentationLibrary(
-      Iterable<MacroExecutionResult> macroResults);
+  ///
+  /// The [resolveIdentifier] argument should return the import uri to be used
+  /// for that identifier.
+  String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
+      ResolvedIdentifier Function(Identifier) resolveIdentifier);
 
   /// Tell the executor to shut down and clean up any resources it may have
   /// allocated.
@@ -129,7 +117,7 @@
   static Object? _deserializeArg(Deserializer deserializer,
       {bool alreadyMoved = false}) {
     if (!alreadyMoved) deserializer.moveNext();
-    _ArgumentKind kind = _ArgumentKind.values[deserializer.expectNum()];
+    _ArgumentKind kind = _ArgumentKind.values[deserializer.expectInt()];
     switch (kind) {
       case _ArgumentKind.nil:
         return null;
@@ -139,9 +127,12 @@
       case _ArgumentKind.bool:
         deserializer.moveNext();
         return deserializer.expectBool();
-      case _ArgumentKind.num:
+      case _ArgumentKind.int:
         deserializer.moveNext();
-        return deserializer.expectNum();
+        return deserializer.expectInt();
+      case _ArgumentKind.double:
+        deserializer.moveNext();
+        return deserializer.expectDouble();
       case _ArgumentKind.list:
         deserializer.moveNext();
         deserializer.expectList();
@@ -181,22 +172,26 @@
 
   static void _serializeArg(Object? arg, Serializer serializer) {
     if (arg == null) {
-      serializer.addNum(_ArgumentKind.nil.index);
+      serializer.addInt(_ArgumentKind.nil.index);
     } else if (arg is String) {
       serializer
-        ..addNum(_ArgumentKind.string.index)
+        ..addInt(_ArgumentKind.string.index)
         ..addString(arg);
-    } else if (arg is num) {
+    } else if (arg is int) {
       serializer
-        ..addNum(_ArgumentKind.num.index)
-        ..addNum(arg);
+        ..addInt(_ArgumentKind.int.index)
+        ..addInt(arg);
+    } else if (arg is double) {
+      serializer
+        ..addInt(_ArgumentKind.double.index)
+        ..addDouble(arg);
     } else if (arg is bool) {
       serializer
-        ..addNum(_ArgumentKind.bool.index)
+        ..addInt(_ArgumentKind.bool.index)
         ..addBool(arg);
     } else if (arg is List) {
       serializer
-        ..addNum(_ArgumentKind.list.index)
+        ..addInt(_ArgumentKind.list.index)
         ..startList();
       for (Object? item in arg) {
         _serializeArg(item, serializer);
@@ -204,7 +199,7 @@
       serializer.endList();
     } else if (arg is Map) {
       serializer
-        ..addNum(_ArgumentKind.map.index)
+        ..addInt(_ArgumentKind.map.index)
         ..startList();
       for (MapEntry<Object?, Object?> entry in arg.entries) {
         _serializeArg(entry.key, serializer);
@@ -217,6 +212,45 @@
   }
 }
 
+/// A resolved [Identifier], this is used when creating augmentation libraries
+/// to qualify identifiers where needed.
+class ResolvedIdentifier extends Identifier {
+  /// The import URI for the library that defines the member that is referenced
+  /// by this identifier.
+  ///
+  /// If this identifier is an instance member or a built-in type, like
+  /// `void`, [uri] is `null`.
+  final Uri? uri;
+
+  /// Type of identifier this is (instance, static, top level).
+  final IdentifierKind kind;
+
+  /// The unqualified name of this identifier.
+  @override
+  final String name;
+
+  /// If this is a static member, then the name of the fully qualified scope
+  /// surrounding this member. Should not contain a trailing `.`.
+  ///
+  /// Typically this would just be the name of a type.
+  final String? staticScope;
+
+  ResolvedIdentifier({
+    required this.kind,
+    required this.name,
+    required this.staticScope,
+    required this.uri,
+  });
+}
+
+/// The types of identifiers.
+enum IdentifierKind {
+  instanceMember,
+  local, // Parameters, local variables, etc.
+  staticInstanceMember,
+  topLevelMember,
+}
+
 /// An opaque identifier for a macro class, retrieved by
 /// [MacroExecutor.loadMacro].
 ///
@@ -243,12 +277,16 @@
 /// All modifications are expressed in terms of library augmentation
 /// declarations.
 abstract class MacroExecutionResult implements Serializable {
-  /// Any library imports that should be added to support the code used in
-  /// the augmentations.
-  Iterable<DeclarationCode> get imports;
+  /// Any augmentations that should be applied to a class as a result of
+  /// executing a macro, indexed by the name of the class.
+  Map<String, Iterable<DeclarationCode>> get classAugmentations;
 
-  /// Any augmentations that should be applied as a result of executing a macro.
-  Iterable<DeclarationCode> get augmentations;
+  /// Any augmentations that should be applied to the library as a result of
+  /// executing a macro.
+  Iterable<DeclarationCode> get libraryAugmentations;
+
+  /// The names of any new types declared in [augmentations].
+  Iterable<String> get newTypeNames;
 }
 
 /// Each of the possible types of declarations a macro can be applied to
@@ -274,4 +312,4 @@
 }
 
 /// Used for serializing and deserializing arguments.
-enum _ArgumentKind { string, bool, num, list, map, nil }
+enum _ArgumentKind { string, bool, double, int, list, map, nil }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/augmentation_library.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/augmentation_library.dart
new file mode 100644
index 0000000..fd0b26bc
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/augmentation_library.dart
@@ -0,0 +1,86 @@
+// 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 '../api.dart';
+import '../executor.dart';
+
+/// A mixin which provides a shared implementation of
+/// [MacroExecutor.buildAugmentationLibrary].
+mixin AugmentationLibraryBuilder on MacroExecutor {
+  @override
+  String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
+      ResolvedIdentifier Function(Identifier) resolveIdentifier) {
+    StringBuffer importsBuffer = new StringBuffer();
+    StringBuffer directivesBuffer = new StringBuffer();
+    Map<Uri, String> importPrefixes = {};
+    int nextPrefix = 0;
+
+    // Keeps track of the last part written in `lastDirectivePart`.
+    String lastDirectivePart = '';
+    void writeDirectivePart(String part) {
+      lastDirectivePart = part;
+      directivesBuffer.write(part);
+    }
+
+    void buildCode(Code code) {
+      for (Object part in code.parts) {
+        if (part is String) {
+          writeDirectivePart(part);
+        } else if (part is Code) {
+          buildCode(part);
+        } else if (part is Identifier) {
+          ResolvedIdentifier resolved = resolveIdentifier(part);
+          String? prefix;
+          if (resolved.uri != null) {
+            prefix = importPrefixes.putIfAbsent(resolved.uri!, () {
+              String prefix = 'i${nextPrefix++}';
+              importsBuffer.writeln("import '${resolved.uri}' as $prefix;");
+              return prefix;
+            });
+          }
+          if (resolved.kind == IdentifierKind.instanceMember) {
+            // Qualify with `this.` if we don't have a receiver.
+            if (!lastDirectivePart.trimRight().endsWith('.')) {
+              writeDirectivePart('this.');
+            }
+          } else if (prefix != null) {
+            writeDirectivePart('${prefix}.');
+          }
+          if (resolved.kind == IdentifierKind.staticInstanceMember) {
+            writeDirectivePart('${resolved.staticScope!}.');
+          }
+          writeDirectivePart('${part.name}');
+        } else {
+          throw new ArgumentError(
+              'Code objects only support String, Identifier, and Code '
+              'instances but got $part which was not one of those.');
+        }
+      }
+    }
+
+    Map<String, List<DeclarationCode>> mergedClassResults = {};
+    for (MacroExecutionResult result in macroResults) {
+      for (DeclarationCode augmentation in result.libraryAugmentations) {
+        buildCode(augmentation);
+        directivesBuffer.writeln();
+      }
+      for (MapEntry<String, Iterable<DeclarationCode>> entry
+          in result.classAugmentations.entries) {
+        mergedClassResults.update(
+            entry.key, (value) => value..addAll(entry.value),
+            ifAbsent: () => entry.value.toList());
+      }
+    }
+    for (MapEntry<String, List<DeclarationCode>> entry
+        in mergedClassResults.entries) {
+      directivesBuffer.writeln('augment class ${entry.key} {');
+      for (DeclarationCode augmentation in entry.value) {
+        buildCode(augmentation);
+        directivesBuffer.writeln();
+      }
+      directivesBuffer.writeln('}');
+    }
+    return '$importsBuffer\n\n$directivesBuffer';
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart
new file mode 100644
index 0000000..6f522e0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart
@@ -0,0 +1,407 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:_fe_analyzer_shared/src/macros/executor/introspection_impls.dart';
+
+import '../executor.dart';
+import '../api.dart';
+import 'response_impls.dart';
+
+class TypeBuilderBase implements IdentifierResolver {
+  /// The final result, will be built up over `augment` calls.
+  final List<DeclarationCode> _libraryAugmentations;
+
+  /// The final result, will be built up over `augment` calls.
+  final Map<String, List<DeclarationCode>> _classAugmentations;
+
+  /// The names of any new types added in [_libraryAugmentations].
+  final List<String> _newTypeNames = [];
+
+  final IdentifierResolver identifierResolver;
+
+  /// Creates and returns a [MacroExecutionResult] out of the [_augmentations]
+  /// created by this builder.
+  MacroExecutionResult get result => new MacroExecutionResultImpl(
+        classAugmentations: _classAugmentations,
+        libraryAugmentations: _libraryAugmentations,
+        newTypeNames: _newTypeNames,
+      );
+
+  TypeBuilderBase(this.identifierResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : _classAugmentations = parentClassAugmentations ?? {},
+        _libraryAugmentations = parentLibraryAugmentations ?? [];
+
+  @override
+  Future<Identifier> resolveIdentifier(Uri library, String identifier) =>
+      // ignore: deprecated_member_use_from_same_package
+      identifierResolver.resolveIdentifier(library, identifier);
+}
+
+class TypeBuilderImpl extends TypeBuilderBase implements TypeBuilder {
+  TypeBuilderImpl(IdentifierResolver identifierResolver)
+      : super(identifierResolver);
+
+  @override
+  void declareType(String name, DeclarationCode typeDeclaration) {
+    _newTypeNames.add(name);
+    _libraryAugmentations.add(typeDeclaration);
+  }
+}
+
+/// Base class for all [DeclarationBuilder]s.
+class DeclarationBuilderBase extends TypeBuilderBase
+    implements ClassIntrospector, TypeResolver {
+  final ClassIntrospector classIntrospector;
+  final TypeResolver typeResolver;
+
+  DeclarationBuilderBase(IdentifierResolver identifierResolver,
+      this.classIntrospector, this.typeResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
+      classIntrospector.constructorsOf(clazz);
+
+  @override
+  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
+      classIntrospector.fieldsOf(clazz);
+
+  @override
+  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
+      classIntrospector.interfacesOf(clazz);
+
+  @override
+  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
+      classIntrospector.methodsOf(clazz);
+
+  @override
+  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
+      classIntrospector.mixinsOf(clazz);
+
+  @override
+  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
+      classIntrospector.superclassOf(clazz);
+
+  @override
+  Future<StaticType> resolve(TypeAnnotationCode code) =>
+      typeResolver.resolve(code);
+}
+
+class DeclarationBuilderImpl extends DeclarationBuilderBase
+    implements DeclarationBuilder {
+  DeclarationBuilderImpl(IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector, TypeResolver typeResolver)
+      : super(identifierResolver, classIntrospector, typeResolver);
+
+  @override
+  void declareInLibrary(DeclarationCode declaration) {
+    _libraryAugmentations.add(declaration);
+  }
+}
+
+class ClassMemberDeclarationBuilderImpl extends DeclarationBuilderImpl
+    implements ClassMemberDeclarationBuilder {
+  final Identifier definingClass;
+
+  ClassMemberDeclarationBuilderImpl(
+      this.definingClass,
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver)
+      : super(identifierResolver, classIntrospector, typeResolver);
+
+  @override
+  void declareInClass(DeclarationCode declaration) {
+    _classAugmentations.update(
+        definingClass.name, (value) => value..add(declaration),
+        ifAbsent: () => [declaration]);
+  }
+}
+
+/// Base class for all [DefinitionBuilder]s.
+class DefinitionBuilderBase extends DeclarationBuilderBase
+    implements TypeDeclarationResolver {
+  final TypeDeclarationResolver typeDeclarationResolver;
+
+  DefinitionBuilderBase(
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      this.typeDeclarationResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver, classIntrospector, typeResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) =>
+      typeDeclarationResolver.declarationOf(identifier);
+}
+
+class ClassDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements ClassDefinitionBuilder {
+  /// The declaration this is a builder for.
+  final ClassDeclaration declaration;
+
+  ClassDefinitionBuilderImpl(
+      this.declaration,
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver, classIntrospector, typeResolver,
+            typeDeclarationResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  Future<ConstructorDefinitionBuilder> buildConstructor(
+      Identifier identifier) async {
+    ConstructorDeclaration constructor =
+        (await classIntrospector.constructorsOf(declaration))
+            .firstWhere((constructor) => constructor.identifier == identifier);
+    return new ConstructorDefinitionBuilderImpl(constructor, identifierResolver,
+        classIntrospector, typeResolver, typeDeclarationResolver,
+        parentClassAugmentations: _classAugmentations,
+        parentLibraryAugmentations: _libraryAugmentations);
+  }
+
+  @override
+  Future<VariableDefinitionBuilder> buildField(Identifier identifier) async {
+    FieldDeclaration field = (await classIntrospector.fieldsOf(declaration))
+        .firstWhere((field) => field.identifier == identifier);
+    return new VariableDefinitionBuilderImpl(field, identifierResolver,
+        classIntrospector, typeResolver, typeDeclarationResolver,
+        parentClassAugmentations: _classAugmentations,
+        parentLibraryAugmentations: _libraryAugmentations);
+  }
+
+  @override
+  Future<FunctionDefinitionBuilder> buildMethod(Identifier identifier) async {
+    MethodDeclaration method = (await classIntrospector.methodsOf(declaration))
+        .firstWhere((method) => method.identifier == identifier);
+    return new FunctionDefinitionBuilderImpl(method, identifierResolver,
+        classIntrospector, typeResolver, typeDeclarationResolver,
+        parentClassAugmentations: _classAugmentations,
+        parentLibraryAugmentations: _libraryAugmentations);
+  }
+}
+
+/// Implementation of [FunctionDefinitionBuilder].
+class FunctionDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements FunctionDefinitionBuilder {
+  final FunctionDeclaration declaration;
+
+  FunctionDefinitionBuilderImpl(
+      this.declaration,
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver, classIntrospector, typeResolver,
+            typeDeclarationResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  void augment(FunctionBodyCode body) {
+    DeclarationCode augmentation =
+        _buildFunctionAugmentation(body, declaration);
+    if (declaration is ClassMemberDeclaration) {
+      _classAugmentations.update(
+          (declaration as ClassMemberDeclaration).definingClass.name,
+          (value) => value..add(augmentation),
+          ifAbsent: () => [augmentation]);
+    } else {
+      _libraryAugmentations.add(augmentation);
+    }
+  }
+}
+
+class ConstructorDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements ConstructorDefinitionBuilder {
+  final ConstructorDeclaration declaration;
+
+  ConstructorDefinitionBuilderImpl(
+      this.declaration,
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver, classIntrospector, typeResolver,
+            typeDeclarationResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  void augment({FunctionBodyCode? body, List<Code>? initializers}) {
+    body ??= new FunctionBodyCode.fromString('''{
+      augment super();
+    }''');
+    DeclarationCode augmentation = _buildFunctionAugmentation(body, declaration,
+        initializers: initializers);
+    _classAugmentations.update(
+        declaration.definingClass.name, (value) => value..add(augmentation),
+        ifAbsent: () => [augmentation]);
+  }
+}
+
+class VariableDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements VariableDefinitionBuilder {
+  final VariableDeclaration declaration;
+
+  VariableDefinitionBuilderImpl(
+      this.declaration,
+      IdentifierResolver identifierResolver,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {Map<String, List<DeclarationCode>>? parentClassAugmentations,
+      List<DeclarationCode>? parentLibraryAugmentations})
+      : super(identifierResolver, classIntrospector, typeResolver,
+            typeDeclarationResolver,
+            parentClassAugmentations: parentClassAugmentations,
+            parentLibraryAugmentations: parentLibraryAugmentations);
+
+  @override
+  void augment(
+      {DeclarationCode? getter,
+      DeclarationCode? setter,
+      ExpressionCode? initializer}) {
+    List<DeclarationCode> augmentations = _buildVariableAugmentations(
+        declaration,
+        getter: getter,
+        setter: setter,
+        initializer: initializer);
+    if (declaration is ClassMemberDeclaration) {
+      _classAugmentations.update(
+          (declaration as ClassMemberDeclaration).definingClass.name,
+          (value) => value..addAll(augmentations),
+          ifAbsent: () => augmentations);
+    } else {
+      _libraryAugmentations.addAll(augmentations);
+    }
+  }
+}
+
+/// Builds all the possible augmentations for a variable.
+List<DeclarationCode> _buildVariableAugmentations(
+    VariableDeclaration declaration,
+    {DeclarationCode? getter,
+    DeclarationCode? setter,
+    ExpressionCode? initializer}) {
+  List<DeclarationCode> augmentations = [];
+  if (getter != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      if (declaration is FieldDeclaration && declaration.isStatic) 'static ',
+      getter,
+    ]));
+  }
+  if (setter != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      if (declaration is FieldDeclaration && declaration.isStatic) 'static ',
+      setter,
+    ]));
+  }
+  if (initializer != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      if (declaration is FieldDeclaration && declaration.isStatic) 'static ',
+      if (declaration.isFinal) 'final ',
+      declaration.type.code,
+      ' ',
+      declaration.identifier,
+      ' = ',
+      initializer,
+      ';',
+    ]));
+  }
+
+  return augmentations;
+}
+
+/// Builds the code to augment a function, method, or constructor with a new
+/// body.
+///
+/// The [initializers] parameter can only be used if [declaration] is a
+/// constructor.
+DeclarationCode _buildFunctionAugmentation(
+    FunctionBodyCode body, FunctionDeclaration declaration,
+    {List<Code>? initializers}) {
+  assert(initializers == null || declaration is ConstructorDeclaration);
+
+  return new DeclarationCode.fromParts([
+    'augment ',
+    if (declaration is ConstructorDeclaration) ...[
+      declaration.definingClass.name,
+      if (declaration.identifier.name.isNotEmpty) '.',
+    ] else ...[
+      if (declaration is MethodDeclaration && declaration.isStatic) 'static ',
+      declaration.returnType.code,
+      ' ',
+      if (declaration.isOperator) 'operator ',
+    ],
+    declaration.identifier.name,
+    if (declaration.typeParameters.isNotEmpty) ...[
+      '<',
+      for (TypeParameterDeclaration typeParam
+          in declaration.typeParameters) ...[
+        typeParam.identifier.name,
+        if (typeParam.bound != null) ...[' extends ', typeParam.bound!.code],
+        if (typeParam != declaration.typeParameters.last) ', ',
+      ],
+      '>',
+    ],
+    '(',
+    for (ParameterDeclaration positionalRequired
+        in declaration.positionalParameters.takeWhile((p) => p.isRequired)) ...[
+      positionalRequired.code,
+      ', ',
+    ],
+    if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
+      '[',
+      for (ParameterDeclaration positionalOptional
+          in declaration.positionalParameters.where((p) => !p.isRequired)) ...[
+        positionalOptional.code,
+        ', ',
+      ],
+      ']',
+    ],
+    if (declaration.namedParameters.isNotEmpty) ...[
+      '{',
+      for (ParameterDeclaration named in declaration.namedParameters) ...[
+        named.code,
+        ', ',
+      ],
+      '}',
+    ],
+    ') ',
+    if (initializers != null && initializers.isNotEmpty) ...[
+      ' : ',
+      initializers.first,
+      for (Code initializer in initializers.skip(1)) ...[
+        ',\n',
+        initializer,
+      ],
+    ],
+    body,
+  ]);
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart
new file mode 100644
index 0000000..af3224f
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart
@@ -0,0 +1,158 @@
+// 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/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/builder_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+/// Runs [macro] in the types phase and returns a  [MacroExecutionResult].
+Future<MacroExecutionResult> executeTypesMacro(Macro macro,
+    Declaration declaration, IdentifierResolver identifierResolver) async {
+  TypeBuilderImpl builder = new TypeBuilderImpl(identifierResolver);
+  if (declaration is FunctionDeclaration) {
+    if (macro is ConstructorTypesMacro &&
+        declaration is ConstructorDeclaration) {
+      await macro.buildTypesForConstructor(declaration, builder);
+      return builder.result;
+    } else if (macro is MethodTypesMacro && declaration is MethodDeclaration) {
+      await macro.buildTypesForMethod(declaration, builder);
+      return builder.result;
+    } else if (macro is FunctionTypesMacro) {
+      await macro.buildTypesForFunction(declaration, builder);
+      return builder.result;
+    }
+  } else if (declaration is VariableDeclaration) {
+    if (macro is FieldTypesMacro && declaration is FieldDeclaration) {
+      await macro.buildTypesForField(declaration, builder);
+      return builder.result;
+    } else if (macro is VariableTypesMacro) {
+      await macro.buildTypesForVariable(declaration, builder);
+      return builder.result;
+    }
+  } else if (macro is ClassTypesMacro && declaration is ClassDeclaration) {
+    await macro.buildTypesForClass(declaration, builder);
+    return builder.result;
+  }
+  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+      'macro: $macro\ndeclaration: $declaration');
+}
+
+/// Runs [macro] in the declaration phase and returns a  [MacroExecutionResult].
+Future<MacroExecutionResult> executeDeclarationsMacro(
+    Macro macro,
+    Declaration declaration,
+    IdentifierResolver identifierResolver,
+    ClassIntrospector classIntrospector,
+    TypeResolver typeResolver) async {
+  if (declaration is ClassDeclaration && macro is ClassDeclarationsMacro) {
+    ClassMemberDeclarationBuilderImpl builder =
+        new ClassMemberDeclarationBuilderImpl(declaration.identifier,
+            identifierResolver, classIntrospector, typeResolver);
+    await macro.buildDeclarationsForClass(declaration, builder);
+    return builder.result;
+  } else if (declaration is ClassMemberDeclaration) {
+    ClassMemberDeclarationBuilderImpl builder =
+        new ClassMemberDeclarationBuilderImpl(declaration.definingClass,
+            identifierResolver, classIntrospector, typeResolver);
+    if (declaration is FunctionDeclaration) {
+      if (macro is ConstructorDeclarationsMacro &&
+          declaration is ConstructorDeclaration) {
+        await macro.buildDeclarationsForConstructor(declaration, builder);
+        return builder.result;
+      } else if (macro is MethodDeclarationsMacro &&
+          declaration is MethodDeclaration) {
+        await macro.buildDeclarationsForMethod(declaration, builder);
+        return builder.result;
+      } else if (macro is FunctionDeclarationsMacro) {
+        await macro.buildDeclarationsForFunction(
+            declaration as FunctionDeclaration, builder);
+        return builder.result;
+      }
+    } else if (declaration is VariableDeclaration) {
+      if (macro is FieldDeclarationsMacro && declaration is FieldDeclaration) {
+        await macro.buildDeclarationsForField(declaration, builder);
+        return builder.result;
+      } else if (macro is VariableDeclarationsMacro) {
+        DeclarationBuilderImpl builder = new DeclarationBuilderImpl(
+            identifierResolver, classIntrospector, typeResolver);
+        await macro.buildDeclarationsForVariable(
+            declaration as VariableDeclaration, builder);
+        return builder.result;
+      }
+    }
+  } else {
+    DeclarationBuilderImpl builder = new DeclarationBuilderImpl(
+        identifierResolver, classIntrospector, typeResolver);
+    if (declaration is FunctionDeclaration &&
+        macro is FunctionDeclarationsMacro) {
+      await macro.buildDeclarationsForFunction(declaration, builder);
+      return builder.result;
+    } else if (macro is VariableDeclarationsMacro &&
+        declaration is VariableDeclaration) {
+      await macro.buildDeclarationsForVariable(declaration, builder);
+      return builder.result;
+    }
+  }
+  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+      'macro: $macro\ndeclaration: $declaration');
+}
+
+/// Runs [macro] in the definition phase and returns a  [MacroExecutionResult].
+Future<MacroExecutionResult> executeDefinitionMacro(
+    Macro macro,
+    Declaration declaration,
+    IdentifierResolver identifierResolver,
+    ClassIntrospector classIntrospector,
+    TypeResolver typeResolver,
+    TypeDeclarationResolver typeDeclarationResolver) async {
+  if (declaration is FunctionDeclaration) {
+    if (macro is ConstructorDefinitionMacro &&
+        declaration is ConstructorDeclaration) {
+      ConstructorDefinitionBuilderImpl builder =
+          new ConstructorDefinitionBuilderImpl(declaration, identifierResolver,
+              classIntrospector, typeResolver, typeDeclarationResolver);
+      await macro.buildDefinitionForConstructor(declaration, builder);
+      return builder.result;
+    } else {
+      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
+          declaration,
+          identifierResolver,
+          classIntrospector,
+          typeResolver,
+          typeDeclarationResolver);
+      if (macro is MethodDefinitionMacro && declaration is MethodDeclaration) {
+        await macro.buildDefinitionForMethod(declaration, builder);
+        return builder.result;
+      } else if (macro is FunctionDefinitionMacro) {
+        await macro.buildDefinitionForFunction(declaration, builder);
+        return builder.result;
+      }
+    }
+  } else if (declaration is VariableDeclaration) {
+    VariableDefinitionBuilderImpl builder = new VariableDefinitionBuilderImpl(
+        declaration,
+        identifierResolver,
+        classIntrospector,
+        typeResolver,
+        typeDeclarationResolver);
+    if (macro is FieldDefinitionMacro && declaration is FieldDeclaration) {
+      await macro.buildDefinitionForField(declaration, builder);
+      return builder.result;
+    } else if (macro is VariableDefinitionMacro) {
+      await macro.buildDefinitionForVariable(declaration, builder);
+      return builder.result;
+    }
+  } else if (macro is ClassDefinitionMacro && declaration is ClassDeclaration) {
+    ClassDefinitionBuilderImpl builder = new ClassDefinitionBuilderImpl(
+        declaration,
+        identifierResolver,
+        classIntrospector,
+        typeResolver,
+        typeDeclarationResolver);
+    await macro.buildDefinitionForClass(declaration, builder);
+    return builder.result;
+  }
+  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+      'macro: $macro\ndeclaration: $declaration');
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart
new file mode 100644
index 0000000..940fa5a
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart
@@ -0,0 +1,396 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:_fe_analyzer_shared/src/macros/executor/remote_instance.dart';
+
+import '../api.dart';
+import '../executor/introspection_impls.dart';
+import '../executor/protocol.dart';
+import '../executor/serialization.dart';
+import '../executor.dart';
+
+/// Base implementation for macro executors which communicate with some external
+/// process to run macros.
+///
+/// Subtypes must extend this class and implement the [close] and [sendResult]
+/// apis to handle communication with the external macro program.
+abstract class ExternalMacroExecutorBase extends MacroExecutor {
+  /// The stream on which we receive messages from the external macro executor.
+  final Stream<Object> messageStream;
+
+  /// The mode to use for serialization - must be a `server` variant.
+  final SerializationMode serializationMode;
+
+  /// A map of response completers by request id.
+  final _responseCompleters = <int, Completer<Response>>{};
+
+  /// We need to know which serialization zone to deserialize objects in, so
+  /// that we read them from the correct cache. Each macro execution creates its
+  /// own zone which it stores here by ID and then responses are deserialized in
+  /// that same zone.
+  static final _serializationZones = <int, Zone>{};
+
+  /// Incrementing identifier for the serialization zone ids.
+  static int _nextSerializationZoneId = 0;
+
+  ExternalMacroExecutorBase(
+      {required this.messageStream, required this.serializationMode}) {
+    messageStream.listen((message) {
+      withSerializationMode(serializationMode, () {
+        Deserializer deserializer = deserializerFactory(message);
+        // Every object starts with a zone ID which dictates the zone in which
+        // we should deserialize the message.
+        deserializer.moveNext();
+        int zoneId = deserializer.expectInt();
+        Zone zone = _serializationZones[zoneId]!;
+        zone.run(() async {
+          deserializer.moveNext();
+          MessageType messageType =
+              MessageType.values[deserializer.expectInt()];
+          switch (messageType) {
+            case MessageType.response:
+              SerializableResponse response =
+                  new SerializableResponse.deserialize(deserializer, zoneId);
+              Completer<Response>? completer =
+                  _responseCompleters.remove(response.requestId);
+              if (completer == null) {
+                throw new StateError(
+                    'Got a response for an unrecognized request id '
+                    '${response.requestId}');
+              }
+              completer.complete(response);
+              break;
+            case MessageType.resolveIdentifierRequest:
+              ResolveIdentifierRequest request =
+                  new ResolveIdentifierRequest.deserialize(
+                      deserializer, zoneId);
+              SerializableResponse response;
+              try {
+                IdentifierImpl identifier = await (request
+                            .identifierResolver.instance as IdentifierResolver)
+                        // ignore: deprecated_member_use_from_same_package
+                        .resolveIdentifier(request.library, request.name)
+                    as IdentifierImpl;
+                response = new SerializableResponse(
+                    response: identifier,
+                    requestId: request.id,
+                    responseType: MessageType.remoteInstance,
+                    serializationZoneId: zoneId);
+              } catch (error, stackTrace) {
+                response = new SerializableResponse(
+                    error: '$error',
+                    stackTrace: '$stackTrace',
+                    requestId: request.id,
+                    responseType: MessageType.error,
+                    serializationZoneId: zoneId);
+              }
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.resolveTypeRequest:
+              ResolveTypeRequest request =
+                  new ResolveTypeRequest.deserialize(deserializer, zoneId);
+              StaticType instance =
+                  await (request.typeResolver.instance as TypeResolver)
+                      .resolve(request.typeAnnotationCode);
+              SerializableResponse response = new SerializableResponse(
+                  response: new RemoteInstanceImpl(
+                      id: RemoteInstance.uniqueId,
+                      instance: instance,
+                      kind: instance is NamedStaticType
+                          ? RemoteInstanceKind.namedStaticType
+                          : RemoteInstanceKind.staticType),
+                  requestId: request.id,
+                  responseType: instance is NamedStaticType
+                      ? MessageType.namedStaticType
+                      : MessageType.staticType,
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.isExactlyTypeRequest:
+              IsExactlyTypeRequest request =
+                  new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
+              StaticType leftType = request.leftType.instance as StaticType;
+              StaticType rightType = request.rightType.instance as StaticType;
+              SerializableResponse response = new SerializableResponse(
+                  response:
+                      new BooleanValue(await leftType.isExactly(rightType)),
+                  requestId: request.id,
+                  responseType: MessageType.boolean,
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.isSubtypeOfRequest:
+              IsSubtypeOfRequest request =
+                  new IsSubtypeOfRequest.deserialize(deserializer, zoneId);
+              StaticType leftType = request.leftType.instance as StaticType;
+              StaticType rightType = request.rightType.instance as StaticType;
+              SerializableResponse response = new SerializableResponse(
+                  response:
+                      new BooleanValue(await leftType.isSubtypeOf(rightType)),
+                  requestId: request.id,
+                  responseType: MessageType.boolean,
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.declarationOfRequest:
+              DeclarationOfRequest request =
+                  new DeclarationOfRequest.deserialize(deserializer, zoneId);
+              TypeDeclarationResolver resolver = request
+                  .typeDeclarationResolver.instance as TypeDeclarationResolver;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.remoteInstance,
+                  response: (await resolver.declarationOf(request.identifier)
+                      // TODO: Consider refactoring to avoid the need for this.
+                      as TypeDeclarationImpl),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.constructorsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .constructorsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ConstructorDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.fieldsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .fieldsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<FieldDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.interfacesOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .interfacesOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ClassDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.methodsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .methodsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<MethodDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.mixinsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .mixinsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ClassDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.superclassOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.remoteInstance,
+                  response: (await classIntrospector
+                          .superclassOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      as ClassDeclarationImpl?,
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            default:
+              throw new StateError('Unexpected message type $messageType');
+          }
+        });
+      });
+    });
+  }
+
+  /// These calls are handled by the higher level executor.
+  @override
+  String buildAugmentationLibrary(Iterable<MacroExecutionResult> macroResults,
+          ResolvedIdentifier Function(Identifier) resolveIdentifier) =>
+      throw new StateError('Unreachable');
+
+  @override
+  Future<MacroExecutionResult> executeDeclarationsPhase(
+          MacroInstanceIdentifier macro,
+          DeclarationImpl declaration,
+          IdentifierResolver identifierResolver,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector) =>
+      _sendRequest((zoneId) => new ExecuteDeclarationsPhaseRequest(
+          macro,
+          declaration,
+          new RemoteInstanceImpl(
+              instance: identifierResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.identifierResolver),
+          new RemoteInstanceImpl(
+              instance: typeResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeResolver),
+          new RemoteInstanceImpl(
+              instance: classIntrospector,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.classIntrospector),
+          serializationZoneId: zoneId));
+
+  @override
+  Future<MacroExecutionResult> executeDefinitionsPhase(
+          MacroInstanceIdentifier macro,
+          DeclarationImpl declaration,
+          IdentifierResolver identifierResolver,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector,
+          TypeDeclarationResolver typeDeclarationResolver) =>
+      _sendRequest((zoneId) => new ExecuteDefinitionsPhaseRequest(
+          macro,
+          declaration,
+          new RemoteInstanceImpl(
+              instance: identifierResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.identifierResolver),
+          new RemoteInstanceImpl(
+              instance: typeResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeResolver),
+          new RemoteInstanceImpl(
+              instance: classIntrospector,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.classIntrospector),
+          new RemoteInstanceImpl(
+              instance: typeDeclarationResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeDeclarationResolver),
+          serializationZoneId: zoneId));
+
+  @override
+  Future<MacroExecutionResult> executeTypesPhase(MacroInstanceIdentifier macro,
+          DeclarationImpl declaration, IdentifierResolver identifierResolver) =>
+      _sendRequest((zoneId) => new ExecuteTypesPhaseRequest(
+          macro,
+          declaration,
+          new RemoteInstanceImpl(
+              instance: identifierResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.identifierResolver),
+          serializationZoneId: zoneId));
+
+  @override
+  Future<MacroInstanceIdentifier> instantiateMacro(
+          MacroClassIdentifier macroClass,
+          String constructor,
+          Arguments arguments) =>
+      _sendRequest((zoneId) => new InstantiateMacroRequest(
+          macroClass, constructor, arguments, RemoteInstance.uniqueId,
+          serializationZoneId: zoneId));
+
+  /// These calls are handled by the higher level executor.
+  @override
+  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
+          {Uri? precompiledKernelUri}) =>
+      throw new StateError(
+          'This executor should be wrapped in a MultiMacroExecutor which will '
+          'handle load requests.');
+
+  /// Sends [serializer.result] to [sendPort], possibly wrapping it in a
+  /// [TransferableTypedData] object.
+  void sendResult(Serializer serializer);
+
+  /// Creates a [Request] with a given serialization zone ID, and handles the
+  /// response, casting it to the expected type or throwing the error provided.
+  Future<T> _sendRequest<T>(Request Function(int) requestFactory) =>
+      withSerializationMode(serializationMode, () async {
+        int zoneId = _nextSerializationZoneId++;
+        _serializationZones[zoneId] = Zone.current;
+        Request request = requestFactory(zoneId);
+        Serializer serializer = serializerFactory();
+        // It is our responsibility to add the zone ID header.
+        serializer.addInt(zoneId);
+        request.serialize(serializer);
+        sendResult(serializer);
+        Completer<Response> completer = new Completer<Response>();
+        _responseCompleters[request.id] = completer;
+        try {
+          Response response = await completer.future;
+          T? result = response.response as T?;
+          if (result != null) return result;
+          throw new RemoteException(
+              response.error!.toString(), response.stackTrace);
+        } finally {
+          // Clean up the zone after the request is done.
+          _serializationZones.remove(zoneId);
+        }
+      });
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart
new file mode 100644
index 0000000..857674e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart
@@ -0,0 +1,618 @@
+// 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 'remote_instance.dart';
+import 'serialization.dart';
+import 'serialization_extensions.dart';
+import '../api.dart';
+
+class IdentifierImpl extends RemoteInstance implements Identifier {
+  final String name;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.identifier;
+
+  IdentifierImpl({required int id, required this.name}) : super(id);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer.addString(name);
+  }
+}
+
+abstract class TypeAnnotationImpl extends RemoteInstance
+    implements TypeAnnotation {
+  final bool isNullable;
+
+  TypeAnnotationImpl({required int id, required this.isNullable}) : super(id);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer.addBool(isNullable);
+  }
+}
+
+class NamedTypeAnnotationImpl extends TypeAnnotationImpl
+    implements NamedTypeAnnotation {
+  @override
+  TypeAnnotationCode get code {
+    NamedTypeAnnotationCode underlyingType =
+        new NamedTypeAnnotationCode(name: identifier, typeArguments: [
+      for (TypeAnnotation typeArg in typeArguments) typeArg.code,
+    ]);
+    return isNullable ? underlyingType.asNullable : underlyingType;
+  }
+
+  @override
+  final IdentifierImpl identifier;
+
+  @override
+  final List<TypeAnnotationImpl> typeArguments;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.namedTypeAnnotation;
+
+  NamedTypeAnnotationImpl({
+    required int id,
+    required bool isNullable,
+    required this.identifier,
+    required this.typeArguments,
+  }) : super(id: id, isNullable: isNullable);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    identifier.serialize(serializer);
+    serializer.startList();
+    for (TypeAnnotationImpl typeArg in typeArguments) {
+      typeArg.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
+class FunctionTypeAnnotationImpl extends TypeAnnotationImpl
+    implements FunctionTypeAnnotation {
+  @override
+  TypeAnnotationCode get code {
+    FunctionTypeAnnotationCode underlyingType = new FunctionTypeAnnotationCode(
+      returnType: returnType.code,
+      typeParameters: [
+        for (TypeParameterDeclaration typeParam in typeParameters)
+          typeParam.code,
+      ],
+      positionalParameters: [
+        for (ParameterDeclaration positional in positionalParameters)
+          positional.code,
+      ],
+      namedParameters: [
+        for (ParameterDeclaration named in namedParameters) named.code,
+      ],
+    );
+    return isNullable ? underlyingType.asNullable : underlyingType;
+  }
+
+  @override
+  final List<ParameterDeclarationImpl> namedParameters;
+
+  @override
+  final List<ParameterDeclarationImpl> positionalParameters;
+
+  @override
+  final TypeAnnotationImpl returnType;
+
+  @override
+  final List<TypeParameterDeclarationImpl> typeParameters;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.functionTypeAnnotation;
+
+  FunctionTypeAnnotationImpl({
+    required int id,
+    required bool isNullable,
+    required this.namedParameters,
+    required this.positionalParameters,
+    required this.returnType,
+    required this.typeParameters,
+  }) : super(id: id, isNullable: isNullable);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    returnType.serialize(serializer);
+
+    serializer.startList();
+    for (ParameterDeclarationImpl param in positionalParameters) {
+      param.serialize(serializer);
+    }
+    serializer.endList();
+
+    serializer.startList();
+    for (ParameterDeclarationImpl param in namedParameters) {
+      param.serialize(serializer);
+    }
+    serializer.endList();
+
+    serializer.startList();
+    for (TypeParameterDeclarationImpl typeParam in typeParameters) {
+      typeParam.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
+abstract class DeclarationImpl extends RemoteInstance implements Declaration {
+  final IdentifierImpl identifier;
+
+  DeclarationImpl({required int id, required this.identifier}) : super(id);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    identifier.serialize(serializer);
+  }
+}
+
+class ParameterDeclarationImpl extends DeclarationImpl
+    implements ParameterDeclaration {
+  @override
+  final bool isNamed;
+
+  @override
+  final bool isRequired;
+
+  @override
+  final TypeAnnotationImpl type;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.parameterDeclaration;
+
+  ParameterDeclarationImpl({
+    required int id,
+    required IdentifierImpl identifier,
+    required this.isNamed,
+    required this.isRequired,
+    required this.type,
+  }) : super(id: id, identifier: identifier);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer.addBool(isNamed);
+    serializer.addBool(isRequired);
+    type.serialize(serializer);
+  }
+
+  @override
+  ParameterCode get code =>
+      new ParameterCode(name: identifier.name, type: type.code, keywords: [
+        if (isNamed && isRequired) 'required',
+      ]);
+}
+
+class TypeParameterDeclarationImpl extends DeclarationImpl
+    implements TypeParameterDeclaration {
+  @override
+  final TypeAnnotationImpl? bound;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.typeParameterDeclaration;
+
+  TypeParameterDeclarationImpl({
+    required int id,
+    required IdentifierImpl identifier,
+    required this.bound,
+  }) : super(id: id, identifier: identifier);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    TypeAnnotationImpl? bound = this.bound;
+    if (bound == null) {
+      serializer.addNull();
+    } else {
+      bound.serialize(serializer);
+    }
+  }
+
+  @override
+  TypeParameterCode get code =>
+      new TypeParameterCode(name: identifier.name, bound: bound?.code);
+}
+
+class FunctionDeclarationImpl extends DeclarationImpl
+    implements FunctionDeclaration {
+  @override
+  final bool isAbstract;
+
+  @override
+  final bool isExternal;
+
+  @override
+  final bool isGetter;
+
+  @override
+  final bool isOperator;
+
+  @override
+  final bool isSetter;
+
+  @override
+  final List<ParameterDeclarationImpl> namedParameters;
+
+  @override
+  final List<ParameterDeclarationImpl> positionalParameters;
+
+  @override
+  final TypeAnnotationImpl returnType;
+
+  @override
+  final List<TypeParameterDeclarationImpl> typeParameters;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.functionDeclaration;
+
+  FunctionDeclarationImpl({
+    required int id,
+    required IdentifierImpl identifier,
+    required this.isAbstract,
+    required this.isExternal,
+    required this.isGetter,
+    required this.isOperator,
+    required this.isSetter,
+    required this.namedParameters,
+    required this.positionalParameters,
+    required this.returnType,
+    required this.typeParameters,
+  }) : super(id: id, identifier: identifier);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer
+      ..addBool(isAbstract)
+      ..addBool(isExternal)
+      ..addBool(isGetter)
+      ..addBool(isOperator)
+      ..addBool(isSetter)
+      ..startList();
+    for (ParameterDeclarationImpl named in namedParameters) {
+      named.serialize(serializer);
+    }
+    serializer
+      ..endList()
+      ..startList();
+    for (ParameterDeclarationImpl positional in positionalParameters) {
+      positional.serialize(serializer);
+    }
+    serializer.endList();
+    returnType.serialize(serializer);
+    serializer.startList();
+    for (TypeParameterDeclarationImpl param in typeParameters) {
+      param.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
+class MethodDeclarationImpl extends FunctionDeclarationImpl
+    implements MethodDeclaration {
+  @override
+  final IdentifierImpl definingClass;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.methodDeclaration;
+
+  @override
+  final bool isStatic;
+
+  MethodDeclarationImpl({
+    // Declaration fields
+    required int id,
+    required IdentifierImpl identifier,
+    // Function fields
+    required bool isAbstract,
+    required bool isExternal,
+    required bool isGetter,
+    required bool isOperator,
+    required bool isSetter,
+    required List<ParameterDeclarationImpl> namedParameters,
+    required List<ParameterDeclarationImpl> positionalParameters,
+    required TypeAnnotationImpl returnType,
+    required List<TypeParameterDeclarationImpl> typeParameters,
+    // Method fields
+    required this.definingClass,
+    required this.isStatic,
+  }) : super(
+          id: id,
+          identifier: identifier,
+          isAbstract: isAbstract,
+          isExternal: isExternal,
+          isGetter: isGetter,
+          isOperator: isOperator,
+          isSetter: isSetter,
+          namedParameters: namedParameters,
+          positionalParameters: positionalParameters,
+          returnType: returnType,
+          typeParameters: typeParameters,
+        );
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    definingClass.serialize(serializer);
+    serializer.addBool(isStatic);
+  }
+}
+
+class ConstructorDeclarationImpl extends MethodDeclarationImpl
+    implements ConstructorDeclaration {
+  @override
+  final bool isFactory;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.constructorDeclaration;
+
+  ConstructorDeclarationImpl({
+    // Declaration fields
+    required int id,
+    required IdentifierImpl identifier,
+    // Function fields
+    required bool isAbstract,
+    required bool isExternal,
+    required bool isGetter,
+    required bool isOperator,
+    required bool isSetter,
+    required List<ParameterDeclarationImpl> namedParameters,
+    required List<ParameterDeclarationImpl> positionalParameters,
+    required TypeAnnotationImpl returnType,
+    required List<TypeParameterDeclarationImpl> typeParameters,
+    // Method fields
+    required IdentifierImpl definingClass,
+    // Constructor fields
+    required this.isFactory,
+  }) : super(
+          id: id,
+          identifier: identifier,
+          isAbstract: isAbstract,
+          isExternal: isExternal,
+          isGetter: isGetter,
+          isOperator: isOperator,
+          isSetter: isSetter,
+          namedParameters: namedParameters,
+          positionalParameters: positionalParameters,
+          returnType: returnType,
+          typeParameters: typeParameters,
+          definingClass: definingClass,
+          isStatic: true,
+        );
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer.addBool(isFactory);
+  }
+}
+
+class VariableDeclarationImpl extends DeclarationImpl
+    implements VariableDeclaration {
+  @override
+  final bool isExternal;
+
+  @override
+  final bool isFinal;
+
+  @override
+  final bool isLate;
+
+  @override
+  final TypeAnnotationImpl type;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.variableDeclaration;
+
+  VariableDeclarationImpl({
+    required int id,
+    required IdentifierImpl identifier,
+    required this.isExternal,
+    required this.isFinal,
+    required this.isLate,
+    required this.type,
+  }) : super(id: id, identifier: identifier);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer
+      ..addBool(isExternal)
+      ..addBool(isFinal)
+      ..addBool(isLate);
+    type.serialize(serializer);
+  }
+}
+
+class FieldDeclarationImpl extends VariableDeclarationImpl
+    implements FieldDeclaration {
+  @override
+  final IdentifierImpl definingClass;
+
+  @override
+  final bool isStatic;
+
+  FieldDeclarationImpl({
+    // Declaration fields
+    required int id,
+    required IdentifierImpl identifier,
+    // Variable fields
+    required bool isExternal,
+    required bool isFinal,
+    required bool isLate,
+    required TypeAnnotationImpl type,
+    // Field fields
+    required this.definingClass,
+    required this.isStatic,
+  }) : super(
+            id: id,
+            identifier: identifier,
+            isExternal: isExternal,
+            isFinal: isFinal,
+            isLate: isLate,
+            type: type);
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.fieldDeclaration;
+
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    definingClass.serialize(serializer);
+    serializer.addBool(isStatic);
+  }
+}
+
+abstract class TypeDeclarationImpl extends DeclarationImpl
+    implements TypeDeclaration {
+  @override
+  final List<TypeParameterDeclarationImpl> typeParameters;
+
+  TypeDeclarationImpl({
+    required int id,
+    required IdentifierImpl identifier,
+    required this.typeParameters,
+  }) : super(id: id, identifier: identifier);
+
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer..startList();
+    for (TypeParameterDeclarationImpl param in typeParameters) {
+      param.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
+class ClassDeclarationImpl extends TypeDeclarationImpl
+    implements ClassDeclaration {
+  @override
+  final List<TypeAnnotationImpl> interfaces;
+
+  @override
+  final bool isAbstract;
+
+  @override
+  final bool isExternal;
+
+  @override
+  final List<TypeAnnotationImpl> mixins;
+
+  @override
+  final TypeAnnotationImpl? superclass;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.classDeclaration;
+
+  ClassDeclarationImpl({
+    // Declaration fields
+    required int id,
+    required IdentifierImpl identifier,
+    // TypeDeclaration fields
+    required List<TypeParameterDeclarationImpl> typeParameters,
+    // ClassDeclaration fields
+    required this.interfaces,
+    required this.isAbstract,
+    required this.isExternal,
+    required this.mixins,
+    required this.superclass,
+  }) : super(id: id, identifier: identifier, typeParameters: typeParameters);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    serializer.startList();
+    for (TypeAnnotationImpl interface in interfaces) {
+      interface.serialize(serializer);
+    }
+    serializer
+      ..endList()
+      ..addBool(isAbstract)
+      ..addBool(isExternal)
+      ..startList();
+    for (TypeAnnotationImpl mixin in mixins) {
+      mixin.serialize(serializer);
+    }
+    serializer..endList();
+    superclass.serializeNullable(serializer);
+  }
+}
+
+class TypeAliasDeclarationImpl extends TypeDeclarationImpl
+    implements TypeAliasDeclaration {
+  /// The type being aliased.
+  final TypeAnnotationImpl aliasedType;
+
+  @override
+  RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
+
+  TypeAliasDeclarationImpl({
+    // Declaration fields
+    required int id,
+    required IdentifierImpl identifier,
+    // TypeDeclaration fields
+    required List<TypeParameterDeclarationImpl> typeParameters,
+    // TypeAlias fields
+    required this.aliasedType,
+  }) : super(id: id, identifier: identifier, typeParameters: typeParameters);
+
+  @override
+  void serialize(Serializer serializer) {
+    super.serialize(serializer);
+    // Client side we don't encode anything but the ID.
+    if (serializationMode.isClient) return;
+
+    aliasedType.serialize(serializer);
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/isolated_executor.dart
new file mode 100644
index 0000000..ae15038
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/isolated_executor.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:typed_data';
+
+import '../executor/multi_executor.dart';
+import '../executor/executor_base.dart';
+import '../executor/serialization.dart';
+import '../executor.dart';
+
+/// Returns a [MacroExecutor] which loads macros into isolates using precompiled
+/// kernel files and communicates with that isolate using [serializationMode].
+///
+/// The [serializationMode] must be a `server` variant, and any precompiled
+/// programs must use the corresponding `client` variant.
+///
+/// This is the only public api exposed by this library.
+Future<MacroExecutor> start(SerializationMode serializationMode) async =>
+    new MultiMacroExecutor((Uri library, String name,
+        {Uri? precompiledKernelUri}) {
+      if (precompiledKernelUri == null) {
+        throw new UnsupportedError(
+            'This environment requires a non-null `precompiledKernelUri` to be '
+            'passed when loading macros.');
+      }
+
+      return _SingleIsolatedMacroExecutor.start(
+          library, name, precompiledKernelUri, serializationMode);
+    });
+
+/// Actual implementation of the isolate based macro executor.
+class _SingleIsolatedMacroExecutor extends ExternalMacroExecutorBase {
+  /// The send port where we should send requests.
+  final SendPort sendPort;
+
+  /// A function that should be invoked when shutting down this executor
+  /// to perform any necessary cleanup.
+  final void Function() onClose;
+
+  _SingleIsolatedMacroExecutor(
+      {required Stream<Object> messageStream,
+      required this.onClose,
+      required this.sendPort,
+      required SerializationMode serializationMode})
+      : super(
+            messageStream: messageStream, serializationMode: serializationMode);
+
+  static Future<_SingleIsolatedMacroExecutor> start(Uri library, String name,
+      Uri precompiledKernelUri, SerializationMode serializationMode) async {
+    ReceivePort receivePort = new ReceivePort();
+    Isolate isolate =
+        await Isolate.spawnUri(precompiledKernelUri, [], receivePort.sendPort);
+    Completer<SendPort> sendPortCompleter = new Completer();
+    StreamController<Object> messageStreamController =
+        new StreamController(sync: true);
+    receivePort.listen((message) {
+      if (!sendPortCompleter.isCompleted) {
+        sendPortCompleter.complete(message as SendPort);
+      } else {
+        if (serializationMode == SerializationMode.byteDataServer) {
+          message =
+              (message as TransferableTypedData).materialize().asUint8List();
+        }
+        messageStreamController.add(message);
+      }
+    }).onDone(messageStreamController.close);
+
+    return new _SingleIsolatedMacroExecutor(
+        onClose: () {
+          receivePort.close();
+          isolate.kill();
+        },
+        messageStream: messageStreamController.stream,
+        sendPort: await sendPortCompleter.future,
+        serializationMode: serializationMode);
+  }
+
+  @override
+  void close() => onClose();
+
+  /// Sends the [Serializer.result] to [sendPort], possibly wrapping it in a
+  /// [TransferableTypedData] object.
+  void sendResult(Serializer serializer) {
+    if (serializationMode == SerializationMode.byteDataServer) {
+      sendPort.send(
+          new TransferableTypedData.fromList([serializer.result as Uint8List]));
+    } else {
+      sendPort.send(serializer.result);
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/message_grouper.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/message_grouper.dart
new file mode 100644
index 0000000..7e2d390
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/message_grouper.dart
@@ -0,0 +1,91 @@
+// 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 'dart:math';
+import 'dart:typed_data';
+
+/// Collects messages from an input stream of bytes.
+///
+/// Each message should start with a 32 bit big endian uint indicating its size,
+/// followed by that many bytes.
+class MessageGrouper {
+  /// The input bytes stream subscription.
+  late final StreamSubscription _inputStreamSubscription;
+
+  /// The length of the current message to read, or `-1` if we are currently
+  /// reading the length.
+  int _length = -1;
+
+  /// The buffer to store the length bytes in.
+  BytesBuilder _lengthBuffer = new BytesBuilder();
+
+  /// If reading raw data, buffer for the data.
+  Uint8List _messageBuffer = new Uint8List(0);
+
+  /// The position to write the next byte in [_messageBuffer].
+  int _messagePos = 0;
+
+  late StreamController<Uint8List> _messageStreamController =
+      new StreamController<Uint8List>(onCancel: () {
+    _inputStreamSubscription.cancel();
+  });
+  Stream<Uint8List> get messageStream => _messageStreamController.stream;
+
+  MessageGrouper(Stream<List<int>> inputStream) {
+    _inputStreamSubscription = inputStream.listen(_handleBytes, onDone: cancel);
+  }
+
+  void _handleBytes(List<int> bytes, [int offset = 0]) {
+    if (_length == -1) {
+      while (_lengthBuffer.length < 4 && offset < bytes.length) {
+        _lengthBuffer.addByte(bytes[offset++]);
+      }
+      if (_lengthBuffer.length >= 4) {
+        Uint8List lengthBytes = _lengthBuffer.takeBytes();
+        _length = lengthBytes[0] << 24 |
+            lengthBytes[1] << 16 |
+            lengthBytes[2] << 8 |
+            lengthBytes[3];
+      }
+    }
+
+    // Just pass along `bytes` without a copy if we can, and reset our state
+    if (offset == 0 && bytes.length == _length && bytes is Uint8List) {
+      _length = -1;
+      _messageStreamController.add(bytes);
+      return;
+    }
+
+    // Initialize a new buffer.
+    if (_messagePos == 0) {
+      _messageBuffer = new Uint8List(_length);
+    }
+
+    // Read the data from `bytes`.
+    int lenToRead = min(_length - _messagePos, bytes.length - offset);
+    while (lenToRead-- > 0) {
+      _messageBuffer[_messagePos++] = bytes[offset++];
+    }
+
+    // If we completed a message, add it to the output stream, reset our state,
+    // and call ourselves again if we have more data to read.
+    if (_messagePos >= _length) {
+      _messageStreamController.add(_messageBuffer);
+      _length = -1;
+      _messagePos = 0;
+
+      if (offset < bytes.length) {
+        _handleBytes(bytes, offset);
+      }
+    }
+  }
+
+  /// Stop listening to the input stream for further updates, and close the
+  /// output stream.
+  void cancel() {
+    _inputStreamSubscription.cancel();
+    _messageStreamController.close();
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart
new file mode 100644
index 0000000..aa7c907
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../api.dart';
+import '../executor/augmentation_library.dart';
+import '../executor/introspection_impls.dart';
+import '../executor/response_impls.dart';
+import '../executor.dart';
+
+/// A [MacroExecutor] implementation which delegates most work to other
+/// executors which are spawned through a provided callback.
+class MultiMacroExecutor extends MacroExecutor with AugmentationLibraryBuilder {
+  /// Individual executors indexed by [MacroClassIdentifier] or
+  /// [MacroInstanceIdentifier].
+  final _executors = <Object, MacroExecutor>{};
+
+  /// The function to spawn an actual macro executor for a given [loadMacro]
+  /// request.
+  final Future<MacroExecutor> Function(Uri library, String name,
+      {Uri? precompiledKernelUri}) _spawnExecutor;
+
+  MultiMacroExecutor(this._spawnExecutor);
+
+  @override
+  void close() {
+    for (MacroExecutor executor in _executors.values) {
+      executor.close();
+    }
+    _executors.clear();
+  }
+
+  @override
+  Future<MacroExecutionResult> executeDeclarationsPhase(
+          MacroInstanceIdentifier macro,
+          DeclarationImpl declaration,
+          IdentifierResolver identifierResolver,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector) =>
+      _executors[macro]!.executeDeclarationsPhase(macro, declaration,
+          identifierResolver, typeResolver, classIntrospector);
+
+  @override
+  Future<MacroExecutionResult> executeDefinitionsPhase(
+          MacroInstanceIdentifier macro,
+          DeclarationImpl declaration,
+          IdentifierResolver identifierResolver,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector,
+          TypeDeclarationResolver typeDeclarationResolver) =>
+      _executors[macro]!.executeDefinitionsPhase(
+          macro,
+          declaration,
+          identifierResolver,
+          typeResolver,
+          classIntrospector,
+          typeDeclarationResolver);
+
+  @override
+  Future<MacroExecutionResult> executeTypesPhase(MacroInstanceIdentifier macro,
+          DeclarationImpl declaration, IdentifierResolver identifierResolver) =>
+      _executors[macro]!
+          .executeTypesPhase(macro, declaration, identifierResolver);
+
+  @override
+  Future<MacroInstanceIdentifier> instantiateMacro(
+      MacroClassIdentifier macroClass,
+      String constructor,
+      Arguments arguments) async {
+    MacroExecutor executor = _executors[macroClass]!;
+    MacroInstanceIdentifier instance =
+        await executor.instantiateMacro(macroClass, constructor, arguments);
+    _executors[instance] = executor;
+    return instance;
+  }
+
+  @override
+  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
+      {Uri? precompiledKernelUri}) async {
+    MacroClassIdentifier identifier =
+        new MacroClassIdentifierImpl(library, name);
+    _executors.remove(identifier)?.close();
+
+    MacroExecutor executor = await _spawnExecutor(library, name,
+        precompiledKernelUri: precompiledKernelUri);
+    _executors[identifier] = executor;
+    return identifier;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart
new file mode 100644
index 0000000..ed67219
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:_fe_analyzer_shared/src/macros/executor/protocol.dart';
+
+import '../executor/message_grouper.dart';
+import '../executor/multi_executor.dart';
+import '../executor/executor_base.dart';
+import '../executor/serialization.dart';
+import '../executor.dart';
+
+/// Returns a [MacroExecutor] which loads macros as separate processes using
+/// precompiled binaries and communicates with that program using
+/// [serializationMode].
+///
+/// The [serializationMode] must be a `server` variant, and any precompiled
+/// programs spawned must use the corresponding `client` variant.
+///
+/// This is the only public api exposed by this library.
+Future<MacroExecutor> start(SerializationMode serializationMode) async =>
+    new MultiMacroExecutor((Uri library, String name,
+        {Uri? precompiledKernelUri}) {
+      if (precompiledKernelUri == null) {
+        throw new UnsupportedError(
+            'This environment requires a non-null `precompiledKernelUri` to be '
+            'passed when loading macros.');
+      }
+
+      // TODO: We actually assume this is a full precompiled AOT binary, and not
+      // a kernel file. We launch it directly using `Process.start`.
+      return _SingleProcessMacroExecutor.start(
+          library, name, serializationMode, precompiledKernelUri.toFilePath());
+    });
+
+/// Actual implementation of the separate process based macro executor.
+class _SingleProcessMacroExecutor extends ExternalMacroExecutorBase {
+  /// The IOSink that writes to stdin of the external process.
+  final IOSink outSink;
+
+  /// A function that should be invoked when shutting down this executor
+  /// to perform any necessary cleanup.
+  final void Function() onClose;
+
+  _SingleProcessMacroExecutor(
+      {required Stream<Object> messageStream,
+      required this.onClose,
+      required this.outSink,
+      required SerializationMode serializationMode})
+      : super(
+            messageStream: messageStream, serializationMode: serializationMode);
+
+  static Future<_SingleProcessMacroExecutor> start(Uri library, String name,
+      SerializationMode serializationMode, String programPath) async {
+    Process process = await Process.start(programPath, []);
+    process.stderr
+        .transform(const Utf8Decoder())
+        .listen((content) => throw new RemoteException(content));
+
+    Stream<Object> messageStream;
+
+    if (serializationMode == SerializationMode.byteDataServer) {
+      messageStream = new MessageGrouper(process.stdout).messageStream;
+    } else if (serializationMode == SerializationMode.jsonServer) {
+      messageStream = process.stdout
+          .transform(const Utf8Decoder())
+          .transform(const LineSplitter())
+          .map((line) => jsonDecode(line)!);
+    } else {
+      throw new UnsupportedError(
+          'Unsupported serialization mode \$serializationMode for '
+          'ProcessExecutor');
+    }
+
+    return new _SingleProcessMacroExecutor(
+        onClose: () {
+          process.kill();
+        },
+        messageStream: messageStream,
+        outSink: process.stdin,
+        serializationMode: serializationMode);
+  }
+
+  @override
+  void close() => onClose();
+
+  /// Sends the [Serializer.result] to [stdin].
+  ///
+  /// Json results are serialized to a `String`, and separated by newlines.
+  void sendResult(Serializer serializer) {
+    if (serializationMode == SerializationMode.jsonServer) {
+      outSink.writeln(jsonEncode(serializer.result));
+    } else if (serializationMode == SerializationMode.byteDataServer) {
+      Uint8List result = (serializer as ByteDataSerializer).result;
+      int length = result.lengthInBytes;
+      if (length > 0xffffffff) {
+        throw new StateError('Message was larger than the allowed size!');
+      }
+      outSink.add([
+        length >> 24 & 0xff,
+        length >> 16 & 0xff,
+        length >> 8 & 0xff,
+        length & 0xff
+      ]);
+      outSink.add(result);
+    } else {
+      throw new UnsupportedError(
+          'Unsupported serialization mode $serializationMode for '
+          'ProcessExecutor');
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart
new file mode 100644
index 0000000..73d051c6
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart
@@ -0,0 +1,786 @@
+// 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.
+
+/// Defines the objects used for communication between the macro executor and
+/// the isolate or process doing the work of macro loading and execution.
+library _fe_analyzer_shared.src.macros.executor_shared.protocol;
+
+import 'package:meta/meta.dart';
+
+import '../executor.dart';
+import '../api.dart';
+import '../executor/response_impls.dart';
+import 'introspection_impls.dart';
+import 'remote_instance.dart';
+import 'serialization.dart';
+import 'serialization_extensions.dart';
+
+/// Base class all requests extend, provides a unique id for each request.
+abstract class Request implements Serializable {
+  final int id;
+
+  final int serializationZoneId;
+
+  Request({int? id, required this.serializationZoneId})
+      : this.id = id ?? _next++;
+
+  /// The [serializationZoneId] is a part of the header and needs to be parsed
+  /// before deserializing objects, and then passed in here.
+  Request.deserialize(Deserializer deserializer, this.serializationZoneId)
+      : id = (deserializer..moveNext()).expectInt();
+
+  /// The [serializationZoneId] needs to be separately serialized before the
+  /// rest of the object. This is not done by the instances themselves but by
+  /// the macro implementations.
+  @mustCallSuper
+  void serialize(Serializer serializer) => serializer.addInt(id);
+
+  static int _next = 0;
+}
+
+/// A generic response object that contains either a response or an error, and
+/// a unique ID.
+class Response {
+  final Object? response;
+  final Object? error;
+  final String? stackTrace;
+  final int requestId;
+  final MessageType responseType;
+
+  Response({
+    this.response,
+    this.error,
+    this.stackTrace,
+    required this.requestId,
+    required this.responseType,
+  })  : assert(response != null || error != null),
+        assert(response == null || error == null);
+}
+
+/// A serializable [Response], contains the message type as an enum.
+class SerializableResponse implements Response, Serializable {
+  final Serializable? response;
+  final MessageType responseType;
+  final String? error;
+  final String? stackTrace;
+  final int requestId;
+  final int serializationZoneId;
+
+  SerializableResponse({
+    this.error,
+    this.stackTrace,
+    required this.requestId,
+    this.response,
+    required this.responseType,
+    required this.serializationZoneId,
+  });
+
+  /// You must first parse the [serializationZoneId] yourself, and then
+  /// call this function in that zone, and pass the ID.
+  factory SerializableResponse.deserialize(
+      Deserializer deserializer, int serializationZoneId) {
+    deserializer.moveNext();
+    MessageType responseType = MessageType.values[deserializer.expectInt()];
+    Serializable? response;
+    String? error;
+    String? stackTrace;
+    switch (responseType) {
+      case MessageType.error:
+        deserializer.moveNext();
+        error = deserializer.expectString();
+        deserializer.moveNext();
+        stackTrace = deserializer.expectNullableString();
+        break;
+      case MessageType.macroClassIdentifier:
+        response = new MacroClassIdentifierImpl.deserialize(deserializer);
+        break;
+      case MessageType.macroInstanceIdentifier:
+        response = new MacroInstanceIdentifierImpl.deserialize(deserializer);
+        break;
+      case MessageType.macroExecutionResult:
+        response = new MacroExecutionResultImpl.deserialize(deserializer);
+        break;
+      case MessageType.staticType:
+      case MessageType.namedStaticType:
+        response = RemoteInstance.deserialize(deserializer);
+        break;
+      case MessageType.boolean:
+        response = new BooleanValue.deserialize(deserializer);
+        break;
+      case MessageType.declarationList:
+        response = new DeclarationList.deserialize(deserializer);
+        break;
+      case MessageType.remoteInstance:
+        deserializer.moveNext();
+        if (!deserializer.checkNull()) {
+          response = deserializer.expectRemoteInstance();
+        }
+        break;
+      default:
+        throw new StateError('Unexpected response type $responseType');
+    }
+
+    return new SerializableResponse(
+        responseType: responseType,
+        response: response,
+        error: error,
+        stackTrace: stackTrace,
+        requestId: (deserializer..moveNext()).expectInt(),
+        serializationZoneId: serializationZoneId);
+  }
+
+  void serialize(Serializer serializer) {
+    serializer
+      ..addInt(serializationZoneId)
+      ..addInt(MessageType.response.index)
+      ..addInt(responseType.index);
+    switch (responseType) {
+      case MessageType.error:
+        serializer.addString(error!.toString());
+        serializer.addNullableString(stackTrace);
+        break;
+      default:
+        response.serializeNullable(serializer);
+    }
+    serializer.addInt(requestId);
+  }
+}
+
+class BooleanValue implements Serializable {
+  final bool value;
+
+  BooleanValue(this.value);
+
+  BooleanValue.deserialize(Deserializer deserializer)
+      : value = (deserializer..moveNext()).expectBool();
+
+  @override
+  void serialize(Serializer serializer) => serializer..addBool(value);
+}
+
+/// A serialized list of [Declaration]s.
+class DeclarationList<T extends DeclarationImpl> implements Serializable {
+  final List<T> declarations;
+
+  DeclarationList(this.declarations);
+
+  DeclarationList.deserialize(Deserializer deserializer)
+      : declarations = [
+          for (bool hasNext = (deserializer
+                    ..moveNext()
+                    ..expectList())
+                  .moveNext();
+              hasNext;
+              hasNext = deserializer.moveNext())
+            deserializer.expectRemoteInstance(),
+        ];
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.startList();
+    for (DeclarationImpl declaration in declarations) {
+      declaration.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
+/// A request to load a macro in this isolate.
+class LoadMacroRequest extends Request {
+  final Uri library;
+  final String name;
+
+  LoadMacroRequest(this.library, this.name, {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  LoadMacroRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : library = Uri.parse((deserializer..moveNext()).expectString()),
+        name = (deserializer..moveNext()).expectString(),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer
+      ..addInt(MessageType.loadMacroRequest.index)
+      ..addString(library.toString())
+      ..addString(name);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to instantiate a macro instance.
+class InstantiateMacroRequest extends Request {
+  final MacroClassIdentifier macroClass;
+  final String constructorName;
+  final Arguments arguments;
+
+  /// The ID to assign to the identifier, this needs to come from the requesting
+  /// side so that it is unique.
+  final int instanceId;
+
+  InstantiateMacroRequest(
+      this.macroClass, this.constructorName, this.arguments, this.instanceId,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  InstantiateMacroRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : macroClass = new MacroClassIdentifierImpl.deserialize(deserializer),
+        constructorName = (deserializer..moveNext()).expectString(),
+        arguments = new Arguments.deserialize(deserializer),
+        instanceId = (deserializer..moveNext()).expectInt(),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.instantiateMacroRequest.index);
+    macroClass.serialize(serializer);
+    serializer.addString(constructorName);
+    arguments.serialize(serializer);
+    serializer.addInt(instanceId);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to execute a macro on a particular declaration in the types phase.
+class ExecuteTypesPhaseRequest extends Request {
+  final MacroInstanceIdentifier macro;
+  final DeclarationImpl declaration;
+  final RemoteInstanceImpl identifierResolver;
+
+  ExecuteTypesPhaseRequest(
+      this.macro, this.declaration, this.identifierResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ExecuteTypesPhaseRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
+        declaration = RemoteInstance.deserialize(deserializer),
+        identifierResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.executeTypesPhaseRequest.index);
+    macro.serialize(serializer);
+    declaration.serialize(serializer);
+    identifierResolver.serialize(serializer);
+
+    super.serialize(serializer);
+  }
+}
+
+/// A request to execute a macro on a particular declaration in the definition
+/// phase.
+class ExecuteDeclarationsPhaseRequest extends Request {
+  final MacroInstanceIdentifier macro;
+  final DeclarationImpl declaration;
+
+  final RemoteInstanceImpl identifierResolver;
+  final RemoteInstanceImpl typeResolver;
+  final RemoteInstanceImpl classIntrospector;
+
+  ExecuteDeclarationsPhaseRequest(this.macro, this.declaration,
+      this.identifierResolver, this.typeResolver, this.classIntrospector,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ExecuteDeclarationsPhaseRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
+        declaration = RemoteInstance.deserialize(deserializer),
+        identifierResolver = RemoteInstance.deserialize(deserializer),
+        typeResolver = RemoteInstance.deserialize(deserializer),
+        classIntrospector = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.executeDeclarationsPhaseRequest.index);
+    macro.serialize(serializer);
+    declaration.serialize(serializer);
+    identifierResolver.serialize(serializer);
+    typeResolver.serialize(serializer);
+    classIntrospector.serialize(serializer);
+
+    super.serialize(serializer);
+  }
+}
+
+/// A request to execute a macro on a particular declaration in the definition
+/// phase.
+class ExecuteDefinitionsPhaseRequest extends Request {
+  final MacroInstanceIdentifier macro;
+  final DeclarationImpl declaration;
+
+  final RemoteInstanceImpl identifierResolver;
+  final RemoteInstanceImpl typeResolver;
+  final RemoteInstanceImpl classIntrospector;
+  final RemoteInstanceImpl typeDeclarationResolver;
+
+  ExecuteDefinitionsPhaseRequest(
+      this.macro,
+      this.declaration,
+      this.identifierResolver,
+      this.typeResolver,
+      this.classIntrospector,
+      this.typeDeclarationResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ExecuteDefinitionsPhaseRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
+        declaration = RemoteInstance.deserialize(deserializer),
+        identifierResolver = RemoteInstance.deserialize(deserializer),
+        typeResolver = RemoteInstance.deserialize(deserializer),
+        classIntrospector = RemoteInstance.deserialize(deserializer),
+        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.executeDefinitionsPhaseRequest.index);
+    macro.serialize(serializer);
+    declaration.serialize(serializer);
+    identifierResolver.serialize(serializer);
+    typeResolver.serialize(serializer);
+    classIntrospector.serialize(serializer);
+    typeDeclarationResolver.serialize(serializer);
+
+    super.serialize(serializer);
+  }
+}
+
+/// A request to create a resolved identifier.
+class ResolveIdentifierRequest extends Request {
+  final Uri library;
+  final String name;
+
+  final RemoteInstanceImpl identifierResolver;
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ResolveIdentifierRequest(this.library, this.name, this.identifierResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  ResolveIdentifierRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : library = Uri.parse((deserializer..moveNext()).expectString()),
+        name = (deserializer..moveNext()).expectString(),
+        identifierResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer
+      ..addInt(MessageType.resolveIdentifierRequest.index)
+      ..addString(library.toString())
+      ..addString(name);
+    identifierResolver.serialize(serializer);
+
+    super.serialize(serializer);
+  }
+}
+
+/// A request to resolve on a type annotation code object
+class ResolveTypeRequest extends Request {
+  final TypeAnnotationCode typeAnnotationCode;
+  final RemoteInstanceImpl typeResolver;
+
+  ResolveTypeRequest(this.typeAnnotationCode, this.typeResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ResolveTypeRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : typeAnnotationCode = (deserializer..moveNext()).expectCode(),
+        typeResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.resolveTypeRequest.index);
+    typeAnnotationCode.serialize(serializer);
+    typeResolver.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to check if a type is exactly another type.
+class IsExactlyTypeRequest extends Request {
+  final RemoteInstanceImpl leftType;
+  final RemoteInstanceImpl rightType;
+
+  IsExactlyTypeRequest(this.leftType, this.rightType,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  IsExactlyTypeRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : leftType = RemoteInstance.deserialize(deserializer),
+        rightType = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.isExactlyTypeRequest.index);
+    leftType.serialize(serializer);
+    rightType.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to check if a type is exactly another type.
+class IsSubtypeOfRequest extends Request {
+  final RemoteInstanceImpl leftType;
+  final RemoteInstanceImpl rightType;
+
+  IsSubtypeOfRequest(this.leftType, this.rightType,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  IsSubtypeOfRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : leftType = RemoteInstance.deserialize(deserializer),
+        rightType = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.isSubtypeOfRequest.index);
+    leftType.serialize(serializer);
+    rightType.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A general request class for all requests coming from methods on the
+/// [ClassIntrospector] interface.
+class ClassIntrospectionRequest extends Request {
+  final ClassDeclarationImpl classDeclaration;
+  final RemoteInstanceImpl classIntrospector;
+  final MessageType requestKind;
+
+  ClassIntrospectionRequest(
+      this.classDeclaration, this.classIntrospector, this.requestKind,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again and it should instead be passed in here.
+  ClassIntrospectionRequest.deserialize(
+      Deserializer deserializer, this.requestKind, int serializationZoneId)
+      : classDeclaration = RemoteInstance.deserialize(deserializer),
+        classIntrospector = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addInt(requestKind.index);
+    classDeclaration.serialize(serializer);
+    classIntrospector.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to get a [TypeDeclaration] for a [StaticType].
+class DeclarationOfRequest extends Request {
+  final IdentifierImpl identifier;
+  final RemoteInstanceImpl typeDeclarationResolver;
+
+  DeclarationOfRequest(this.identifier, this.typeDeclarationResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  DeclarationOfRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : identifier = RemoteInstance.deserialize(deserializer),
+        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.declarationOfRequest.index);
+    identifier.serialize(serializer);
+    typeDeclarationResolver.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// Client side implementation of an [IdentifierResolver], which creates a
+/// [ResolveIdentifierRequest] and passes it to a given [sendRequest] function
+/// which can return the [Response].
+class ClientIdentifierResolver implements IdentifierResolver {
+  /// The actual remote instance of this type resolver.
+  final RemoteInstanceImpl remoteInstance;
+
+  /// The ID of the zone in which to find the original type resolver.
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) _sendRequest;
+
+  ClientIdentifierResolver(this._sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<Identifier> resolveIdentifier(Uri library, String name) async {
+    ResolveIdentifierRequest request = new ResolveIdentifierRequest(
+        library, name, remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse(await _sendRequest(request));
+  }
+}
+
+/// Client side implementation of a [TypeResolver], which creates a
+/// [ResolveTypeRequest] and passes it to a given [sendRequest] function which
+/// can return the [Response].
+class ClientTypeResolver implements TypeResolver {
+  /// The actual remote instance of this type resolver.
+  final RemoteInstanceImpl remoteInstance;
+
+  /// The ID of the zone in which to find the original type resolver.
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) _sendRequest;
+
+  ClientTypeResolver(this._sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<StaticType> resolve(TypeAnnotationCode typeAnnotation) async {
+    ResolveTypeRequest request = new ResolveTypeRequest(
+        typeAnnotation, remoteInstance,
+        serializationZoneId: serializationZoneId);
+    RemoteInstanceImpl remoteType =
+        _handleResponse(await _sendRequest(request));
+    switch (remoteType.kind) {
+      case RemoteInstanceKind.namedStaticType:
+        return new ClientNamedStaticTypeImpl(_sendRequest,
+            remoteInstance: remoteType,
+            serializationZoneId: serializationZoneId);
+      case RemoteInstanceKind.staticType:
+        return new ClientStaticTypeImpl(_sendRequest,
+            remoteInstance: remoteType,
+            serializationZoneId: serializationZoneId);
+      default:
+        throw new StateError(
+            'Expected either a StaticType or NamedStaticType but got '
+            '${remoteType.kind}');
+    }
+  }
+}
+
+class ClientStaticTypeImpl implements StaticType {
+  /// The actual remote instance of this static type.
+  final RemoteInstanceImpl remoteInstance;
+
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) sendRequest;
+
+  ClientStaticTypeImpl(this.sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<bool> isExactly(ClientStaticTypeImpl other) async {
+    IsExactlyTypeRequest request = new IsExactlyTypeRequest(
+        this.remoteInstance, other.remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
+  }
+
+  @override
+  Future<bool> isSubtypeOf(ClientStaticTypeImpl other) async {
+    IsSubtypeOfRequest request = new IsSubtypeOfRequest(
+        remoteInstance, other.remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
+  }
+}
+
+/// Named variant of the [ClientStaticTypeImpl].
+class ClientNamedStaticTypeImpl extends ClientStaticTypeImpl
+    implements NamedStaticType {
+  ClientNamedStaticTypeImpl(
+      Future<Response> Function(Request request) sendRequest,
+      {required RemoteInstanceImpl remoteInstance,
+      required int serializationZoneId})
+      : super(sendRequest,
+            remoteInstance: remoteInstance,
+            serializationZoneId: serializationZoneId);
+}
+
+/// Client side implementation of the [ClientClassIntrospector], converts all
+/// invocations into remote RPC calls.
+class ClientClassIntrospector implements ClassIntrospector {
+  /// The actual remote instance of this class introspector.
+  final RemoteInstanceImpl remoteInstance;
+
+  /// The ID of the zone in which to find the original type resolver.
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) sendRequest;
+
+  ClientClassIntrospector(this.sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<List<ConstructorDeclaration>> constructorsOf(
+      ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.constructorsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
+  }
+
+  @override
+  Future<List<FieldDeclaration>> fieldsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.fieldsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
+  }
+
+  @override
+  Future<List<ClassDeclaration>> interfacesOf(
+      ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.interfacesOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
+  }
+
+  @override
+  Future<List<MethodDeclaration>> methodsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.methodsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
+  }
+
+  @override
+  Future<List<ClassDeclaration>> mixinsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.mixinsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
+  }
+
+  @override
+  Future<ClassDeclaration?> superclassOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.superclassOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<ClassDeclaration?>(await sendRequest(request));
+  }
+}
+
+/// Client side implementation of a [TypeDeclarationResolver], converts all
+/// invocations into remote procedure calls.
+class ClientTypeDeclarationResolver implements TypeDeclarationResolver {
+  /// The actual remote instance of this type resolver.
+  final RemoteInstanceImpl remoteInstance;
+
+  /// The ID of the zone in which to find the original type resolver.
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) sendRequest;
+
+  ClientTypeDeclarationResolver(this.sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) async {
+    DeclarationOfRequest request = new DeclarationOfRequest(
+        identifier, remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<TypeDeclaration>(await sendRequest(request));
+  }
+}
+
+/// An exception that occurred remotely, the exception object and stack trace
+/// are serialized as [String]s and both included in the [toString] output.
+class RemoteException implements Exception {
+  final String error;
+  final String? stackTrace;
+
+  RemoteException(this.error, [this.stackTrace]);
+
+  String toString() =>
+      'RemoteException: $error${stackTrace == null ? '' : '\n\n$stackTrace'}';
+}
+
+/// Either returns the actual response from [response], casted to [T], or throws
+/// a [RemoteException] with the given error and stack trace.
+T _handleResponse<T>(Response response) {
+  if (response.responseType == MessageType.error) {
+    throw new RemoteException(response.error!.toString(), response.stackTrace);
+  }
+  return response.response as T;
+}
+
+enum MessageType {
+  boolean,
+  constructorsOfRequest,
+  declarationOfRequest,
+  declarationList,
+  fieldsOfRequest,
+  interfacesOfRequest,
+  methodsOfRequest,
+  mixinsOfRequest,
+  superclassOfRequest,
+  error,
+  executeDeclarationsPhaseRequest,
+  executeDefinitionsPhaseRequest,
+  executeTypesPhaseRequest,
+  instantiateMacroRequest,
+  resolveIdentifierRequest,
+  resolveTypeRequest,
+  isExactlyTypeRequest,
+  isSubtypeOfRequest,
+  loadMacroRequest,
+  remoteInstance,
+  macroClassIdentifier,
+  macroInstanceIdentifier,
+  macroExecutionResult,
+  namedStaticType,
+  response,
+  staticType,
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart
new file mode 100644
index 0000000..fc45704
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.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.
+
+import 'dart:async';
+
+import 'package:meta/meta.dart';
+
+import 'serialization.dart';
+import 'serialization_extensions.dart';
+
+/// The key used to store the remote instance cache in the current serialization
+/// zone (in server mode only).
+const Symbol remoteInstanceZoneKey = #remoteInstanceCache;
+
+/// On the server side we keep track of remote instances by their ID.
+///
+/// These are a part of the current serialization zone, which all serialization
+/// and deserialization must be done in.
+///
+/// This means the cache lifetime is that of the serialization zone it is run
+/// in.
+Map<int, RemoteInstance> get _remoteInstanceCache =>
+    Zone.current[remoteInstanceZoneKey];
+
+/// Base class for types that need to be able to be traced back to a specific
+/// instance on the server side.
+abstract class RemoteInstance implements Serializable {
+  /// The unique ID for this instance.
+  final int id;
+
+  /// The type of instance being encoded.
+  RemoteInstanceKind get kind;
+
+  /// Static, incrementing ids.
+  static int _nextId = 0;
+
+  /// Gets the next unique identifier.
+  static int get uniqueId => _nextId++;
+
+  /// On the client side [id]s are given and you should reconstruct objects with
+  /// the given ID. On the server side ids should be created using
+  /// [RemoteInstance.uniqueId].
+  RemoteInstance(this.id);
+
+  /// Retrieves a cached instance by ID.
+  static T cached<T>(int id) => _remoteInstanceCache[id] as T;
+
+  /// Deserializes an instance based on the current [serializationMode].
+  static T deserialize<T>(Deserializer deserializer) =>
+      (deserializer..moveNext()).expectRemoteInstance();
+
+  /// This method should be overridden by all subclasses, which should on their
+  /// first line call this super function.
+  ///
+  /// They should then return immediately if [serializationMode] is
+  /// [SerializationMode.client], so that only an ID is sent.
+  @mustCallSuper
+  void serialize(Serializer serializer) {
+    serializer.addInt(id);
+    // We only send the ID from the client side.
+    if (serializationMode.isClient) return;
+
+    serializer.addInt(kind.index);
+    _remoteInstanceCache[id] = this;
+  }
+
+  @override
+  bool operator ==(Object other) => other is RemoteInstance && id == other.id;
+}
+
+/// A remote instance which is just a pointer to some server side instance of
+/// a generic object.
+///
+/// The wrapped object is not serialized.
+class RemoteInstanceImpl extends RemoteInstance {
+  /// Always null on the client side, has an actual instance on the server side.
+  final Object? instance;
+
+  @override
+  final RemoteInstanceKind kind;
+
+  RemoteInstanceImpl({
+    required int id,
+    this.instance,
+    required this.kind,
+  }) : super(id);
+}
+
+// The kinds of instances.
+enum RemoteInstanceKind {
+  classDeclaration,
+  classIntrospector,
+  constructorDeclaration,
+  fieldDeclaration,
+  functionDeclaration,
+  functionTypeAnnotation,
+  identifier,
+  identifierResolver,
+  namedStaticType,
+  methodDeclaration,
+  namedTypeAnnotation,
+  parameterDeclaration,
+  staticType,
+  typeAliasDeclaration,
+  typeParameterDeclaration,
+  typeResolver,
+  typeDeclarationResolver,
+  variableDeclaration,
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/response_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/response_impls.dart
new file mode 100644
index 0000000..eedc0bc
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/response_impls.dart
@@ -0,0 +1,289 @@
+// 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 '../executor.dart';
+import '../api.dart';
+import 'serialization.dart';
+import 'serialization_extensions.dart';
+
+/// Implementation of [MacroClassIdentifier].
+class MacroClassIdentifierImpl implements MacroClassIdentifier {
+  final String id;
+
+  MacroClassIdentifierImpl(Uri library, String name) : id = '$library#$name';
+
+  MacroClassIdentifierImpl.deserialize(Deserializer deserializer)
+      : id = (deserializer..moveNext()).expectString();
+
+  void serialize(Serializer serializer) => serializer.addString(id);
+
+  operator ==(other) => other is MacroClassIdentifierImpl && id == other.id;
+
+  int get hashCode => id.hashCode;
+}
+
+/// Implementation of [MacroInstanceIdentifier].
+class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
+  /// Unique identifier for this instance, passed in from the server.
+  final int id;
+
+  /// A single int where each bit indicates whether a specific macro interface
+  /// is implemented by this macro.
+  final int _interfaces;
+
+  MacroInstanceIdentifierImpl._(this.id, this._interfaces);
+
+  factory MacroInstanceIdentifierImpl(Macro macro, int instanceId) {
+    // Build up the interfaces value, there is a bit for each declaration/phase
+    // combination (as there is an interface for each).
+    int interfaces = 0;
+    for (DeclarationKind declarationKind in DeclarationKind.values) {
+      for (Phase phase in Phase.values) {
+        int interfaceMask = _interfaceMask(declarationKind, phase);
+        switch (declarationKind) {
+          case DeclarationKind.clazz:
+            switch (phase) {
+              case Phase.types:
+                if (macro is ClassTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is ClassDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is ClassDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+          case DeclarationKind.constructor:
+            switch (phase) {
+              case Phase.types:
+                if (macro is ConstructorTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is ConstructorDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is ConstructorDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+          case DeclarationKind.field:
+            switch (phase) {
+              case Phase.types:
+                if (macro is FieldTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is FieldDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is FieldDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+          case DeclarationKind.function:
+            switch (phase) {
+              case Phase.types:
+                if (macro is FunctionTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is FunctionDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is FunctionDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+          case DeclarationKind.method:
+            switch (phase) {
+              case Phase.types:
+                if (macro is MethodTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is MethodDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is MethodDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+          case DeclarationKind.variable:
+            switch (phase) {
+              case Phase.types:
+                if (macro is VariableTypesMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.declarations:
+                if (macro is VariableDeclarationsMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+              case Phase.definitions:
+                if (macro is VariableDefinitionMacro) {
+                  interfaces |= interfaceMask;
+                }
+                break;
+            }
+            break;
+        }
+      }
+    }
+
+    return new MacroInstanceIdentifierImpl._(instanceId, interfaces);
+  }
+
+  MacroInstanceIdentifierImpl.deserialize(Deserializer deserializer)
+      : id = (deserializer..moveNext()).expectInt(),
+        _interfaces = (deserializer..moveNext()).expectInt();
+
+  void serialize(Serializer serializer) => serializer
+    ..addInt(id)
+    ..addInt(_interfaces);
+
+  operator ==(other) => other is MacroInstanceIdentifierImpl && id == other.id;
+
+  int get hashCode => id;
+
+  @override
+  bool shouldExecute(DeclarationKind declarationKind, Phase phase) {
+    int mask = _interfaceMask(declarationKind, phase);
+    if (declarationKind == DeclarationKind.method) {
+      // Apply function macros to methods.
+      mask |= _interfaceMask(DeclarationKind.function, phase);
+    } else if (declarationKind == DeclarationKind.field) {
+      // Apply variable macros to fields.
+      mask |= _interfaceMask(DeclarationKind.variable, phase);
+    }
+    return _interfaces & mask != 0x0;
+  }
+
+  @override
+  bool supportsDeclarationKind(DeclarationKind declarationKind) {
+    for (Phase phase in Phase.values) {
+      if (shouldExecute(declarationKind, phase)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// The mask for a particular interface, which is a combination of a kind of
+  /// declaration and a phase.
+  static int _interfaceMask(DeclarationKind declarationKind, Phase phase) =>
+      0x1 << (declarationKind.index * Phase.values.length) << phase.index;
+}
+
+/// Implementation of [MacroExecutionResult].
+class MacroExecutionResultImpl implements MacroExecutionResult {
+  @override
+  final Map<String, List<DeclarationCode>> classAugmentations;
+
+  @override
+  final List<DeclarationCode> libraryAugmentations;
+
+  @override
+  final List<String> newTypeNames;
+
+  MacroExecutionResultImpl({
+    required this.classAugmentations,
+    required this.libraryAugmentations,
+    required this.newTypeNames,
+  });
+
+  factory MacroExecutionResultImpl.deserialize(Deserializer deserializer) {
+    deserializer.moveNext();
+    deserializer.expectList();
+    Map<String, List<DeclarationCode>> classAugmentations = {
+      for (bool hasNext = deserializer.moveNext();
+          hasNext;
+          hasNext = deserializer.moveNext())
+        deserializer.expectString(): [
+          for (bool hasNextCode = (deserializer
+                    ..moveNext()
+                    ..expectList())
+                  .moveNext();
+              hasNextCode;
+              hasNextCode = deserializer.moveNext())
+            deserializer.expectCode(),
+        ]
+    };
+
+    deserializer.moveNext();
+    deserializer.expectList();
+    List<DeclarationCode> libraryAugmentations = [
+      for (bool hasNext = deserializer.moveNext();
+          hasNext;
+          hasNext = deserializer.moveNext())
+        deserializer.expectCode()
+    ];
+    deserializer.moveNext();
+    deserializer.expectList();
+    List<String> newTypeNames = [
+      for (bool hasNext = deserializer.moveNext();
+          hasNext;
+          hasNext = deserializer.moveNext())
+        deserializer.expectString()
+    ];
+
+    return new MacroExecutionResultImpl(
+      classAugmentations: classAugmentations,
+      libraryAugmentations: libraryAugmentations,
+      newTypeNames: newTypeNames,
+    );
+  }
+
+  void serialize(Serializer serializer) {
+    serializer.startList();
+    for (String clazz in classAugmentations.keys) {
+      serializer.addString(clazz);
+      serializer.startList();
+      for (DeclarationCode augmentation in classAugmentations[clazz]!) {
+        augmentation.serialize(serializer);
+      }
+      serializer.endList();
+    }
+    serializer.endList();
+
+    serializer.startList();
+    for (DeclarationCode augmentation in libraryAugmentations) {
+      augmentation.serialize(serializer);
+    }
+    serializer.endList();
+    serializer.startList();
+    for (String name in newTypeNames) {
+      serializer.addString(name);
+    }
+    serializer.endList();
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization.dart
new file mode 100644
index 0000000..50d98fd
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization.dart
@@ -0,0 +1,629 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:typed_data';
+
+import 'remote_instance.dart';
+
+/// All serialization must be done in a serialization Zone, which tells it
+/// whether we are the client or server.
+///
+/// In [SerializationMode.server], sets up a remote instance cache to use when
+/// deserializing remote instances back to their original instance.
+T withSerializationMode<T>(
+  SerializationMode mode,
+  T Function() fn, {
+  Serializer Function()? serializerFactory,
+  Deserializer Function(Object? data)? deserializerFactory,
+}) =>
+    runZoned(fn, zoneValues: {
+      #serializationMode: mode,
+      if (!mode.isClient) remoteInstanceZoneKey: <int, RemoteInstance>{}
+    });
+
+/// Serializable interface
+abstract class Serializable {
+  /// Serializes this object using [serializer].
+  void serialize(Serializer serializer);
+}
+
+/// A push based object serialization interface.
+abstract class Serializer {
+  /// Serializes a [String].
+  void addString(String value);
+
+  /// Serializes a nullable [String].
+  void addNullableString(String? value) =>
+      value == null ? addNull() : addString(value);
+
+  /// Serializes a [double].
+  void addDouble(double value);
+
+  /// Serializes a nullable [double].
+  void addNullableDouble(double? value) =>
+      value == null ? addNull() : addDouble(value);
+
+  /// Serializes an [int].
+  void addInt(int value);
+
+  /// Serializes a nullable [int].
+  void addNullableInt(int? value) => value == null ? addNull() : addInt(value);
+
+  /// Serializes a [bool].
+  void addBool(bool value);
+
+  /// Serializes a nullable [bool].
+  void addNullableBool(bool? value) =>
+      value == null ? addNull() : addBool(value);
+
+  /// Serializes a `null` literal.
+  void addNull();
+
+  /// Used to signal the start of an arbitrary length list of items.
+  void startList();
+
+  /// Used to signal the end of an arbitrary length list of items.
+  void endList();
+
+  /// Returns the resulting serialized object.
+  Object get result;
+}
+
+/// A pull based object deserialization interface.
+///
+/// You must call [moveNext] before reading any items, and in order to advance
+/// to the next item.
+abstract class Deserializer {
+  /// Checks if the current value is a null, returns `true` if so and `false`
+  /// otherwise.
+  bool checkNull();
+
+  /// Reads the current value as a non-nullable [String].
+  bool expectBool();
+
+  /// Reads the current value as a nullable [bool].
+  bool? expectNullableBool() => checkNull() ? null : expectBool();
+
+  /// Reads the current value as a non-nullable [double].
+  double expectDouble();
+
+  /// Reads the current value as a nullable [double].
+  double? expectNullableDouble() => checkNull() ? null : expectDouble();
+
+  /// Reads the current value as a non-nullable [int].
+  int expectInt();
+
+  /// Reads the current value as a nullable [int].
+  int? expectNullableInt() => checkNull() ? null : expectInt();
+
+  /// Reads the current value as a non-nullable [String].
+  String expectString();
+
+  /// Reads the current value as a nullable [String].
+  String? expectNullableString() => checkNull() ? null : expectString();
+
+  /// Asserts that the current item is the start of a list.
+  ///
+  /// An example for how to read from a list is as follows:
+  ///
+  /// var json = JsonReader.fromString(source);
+  /// I know it's a list of strings.
+  ///
+  /// ```
+  ///   var result = <String>[];
+  ///   deserializer.moveNext();
+  ///   deserializer.expectList();
+  ///   while (json.moveNext()) {
+  ///     result.add(json.expectString());
+  ///   }
+  ///   // Can now read later items, but need to call `moveNext` again to move
+  ///   // past the list.
+  ///   deserializer.moveNext();
+  ///   deserializer.expectBool();
+  /// ```
+  void expectList();
+
+  /// Moves to the next item, returns `false` if there are no more items to
+  /// read.
+  ///
+  /// If inside of a list, this returns `false` when the end of the list is
+  /// reached, and moves back to the parent, but does not advance it, so another
+  /// call to `moveNext` is needed. See example in the [expectList] docs.
+  bool moveNext();
+}
+
+class JsonSerializer implements Serializer {
+  /// The full result.
+  final _result = <Object?>[];
+
+  /// A path to the current list we are modifying.
+  late List<List<Object?>> _path = [_result];
+
+  /// Returns the result as an unmodifiable [Iterable].
+  ///
+  /// Asserts that all [List] entries have not been closed with [endList].
+  @override
+  Iterable<Object?> get result {
+    assert(_path.length == 1);
+    return _result;
+  }
+
+  @override
+  void addBool(bool value) => _path.last.add(value);
+  @override
+  void addNullableBool(bool? value) => _path.last.add(value);
+
+  @override
+  void addDouble(double value) => _path.last.add(value);
+  @override
+  void addNullableDouble(double? value) => _path.last.add(value);
+
+  @override
+  void addInt(int value) => _path.last.add(value);
+  @override
+  void addNullableInt(int? value) => _path.last.add(value);
+
+  @override
+  void addString(String value) => _path.last.add(value);
+  @override
+  void addNullableString(String? value) => _path.last.add(value);
+
+  @override
+  void addNull() => _path.last.add(null);
+
+  @override
+  void startList() {
+    List<Object?> sublist = [];
+    _path.last.add(sublist);
+    _path.add(sublist);
+  }
+
+  @override
+  void endList() {
+    _path.removeLast();
+  }
+}
+
+class JsonDeserializer implements Deserializer {
+  /// The root source list to read from.
+  final Iterable<Object?> _source;
+
+  /// The path to the current iterator we are reading from.
+  late List<Iterator<Object?>> _path = [];
+
+  /// Whether we have received our first [moveNext] call.
+  bool _initialized = false;
+
+  /// Initialize this deserializer from `_source`.
+  JsonDeserializer(this._source);
+
+  @override
+  bool checkNull() => _expectValue<Object?>() == null;
+
+  @override
+  void expectList() => _path.add(_expectValue<Iterable<Object?>>().iterator);
+
+  @override
+  bool expectBool() => _expectValue();
+  @override
+  bool? expectNullableBool() => _expectValue();
+
+  @override
+  double expectDouble() => _expectValue();
+  @override
+  double? expectNullableDouble() => _expectValue();
+
+  @override
+  int expectInt() => _expectValue();
+  @override
+  int? expectNullableInt() => _expectValue();
+
+  @override
+  String expectString() => _expectValue();
+  @override
+  String? expectNullableString() => _expectValue();
+
+  /// Reads the current value and casts it to [T].
+  T _expectValue<T>() {
+    if (!_initialized) {
+      throw new StateError(
+          'You must call `moveNext()` before reading any values.');
+    }
+    return _path.last.current as T;
+  }
+
+  @override
+  bool moveNext() {
+    if (!_initialized) {
+      _path.add(_source.iterator);
+      _initialized = true;
+    }
+
+    // Move the current iterable, if its at the end of its items remove it from
+    // the current path and return false.
+    if (!_path.last.moveNext()) {
+      _path.removeLast();
+      return false;
+    }
+
+    return true;
+  }
+}
+
+class ByteDataSerializer extends Serializer {
+  final BytesBuilder _builder = new BytesBuilder();
+
+  // Re-usable 8 byte list and view for encoding doubles.
+  final Uint8List _eightByteList = new Uint8List(8);
+  late final ByteData _eightByteListData =
+      new ByteData.sublistView(_eightByteList);
+
+  @override
+  void addBool(bool value) => _builder
+      .addByte(value ? DataKind.boolTrue.index : DataKind.boolFalse.index);
+
+  @override
+  void addDouble(double value) {
+    _eightByteListData.setFloat64(0, value);
+    _builder
+      ..addByte(DataKind.float64.index)
+      ..add(_eightByteList);
+  }
+
+  @override
+  void addNull() => _builder.addByte(DataKind.nil.index);
+
+  @override
+  void addInt(int value) {
+    if (value >= 0x0) {
+      if (value + DataKind.values.length <= 0xff) {
+        _builder..addByte(value + DataKind.values.length);
+      } else if (value <= 0xff) {
+        _builder
+          ..addByte(DataKind.uint8.index)
+          ..addByte(value);
+      } else if (value <= 0xffff) {
+        _builder
+          ..addByte(DataKind.uint16.index)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      } else if (value <= 0xffffffff) {
+        _builder
+          ..addByte(DataKind.uint32.index)
+          ..addByte(value >> 24)
+          ..addByte(value >> 16)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      } else {
+        _builder
+          ..addByte(DataKind.uint64.index)
+          ..addByte(value >> 56)
+          ..addByte(value >> 48)
+          ..addByte(value >> 40)
+          ..addByte(value >> 32)
+          ..addByte(value >> 24)
+          ..addByte(value >> 16)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      }
+    } else {
+      if (value >= -0x80) {
+        _builder
+          ..addByte(DataKind.int8.index)
+          ..addByte(value);
+      } else if (value >= -0x8000) {
+        _builder
+          ..addByte(DataKind.int16.index)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      } else if (value >= -0x8000000) {
+        _builder
+          ..addByte(DataKind.int32.index)
+          ..addByte(value >> 24)
+          ..addByte(value >> 16)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      } else {
+        _builder
+          ..addByte(DataKind.int64.index)
+          ..addByte(value >> 56)
+          ..addByte(value >> 48)
+          ..addByte(value >> 40)
+          ..addByte(value >> 32)
+          ..addByte(value >> 24)
+          ..addByte(value >> 16)
+          ..addByte(value >> 8)
+          ..addByte(value);
+      }
+    }
+  }
+
+  @override
+  void addString(String value) {
+    for (int i = 0; i < value.length; i++) {
+      if (value.codeUnitAt(i) > 0xff) {
+        _addTwoByteString(value);
+        return;
+      }
+    }
+    _addOneByteString(value);
+  }
+
+  void _addOneByteString(String value) {
+    _builder.addByte(DataKind.oneByteString.index);
+    addInt(value.length);
+    for (int i = 0; i < value.length; i++) {
+      _builder.addByte(value.codeUnitAt(i));
+    }
+  }
+
+  void _addTwoByteString(String value) {
+    _builder.addByte(DataKind.twoByteString.index);
+    addInt(value.length);
+    for (int i = 0; i < value.length; i++) {
+      int codeUnit = value.codeUnitAt(i);
+      switch (Endian.host) {
+        case Endian.little:
+          _builder
+            ..addByte(codeUnit)
+            ..addByte(codeUnit >> 8);
+          break;
+        case Endian.big:
+          _builder
+            ..addByte(codeUnit >> 8)
+            ..addByte(codeUnit);
+          break;
+      }
+    }
+  }
+
+  @override
+  void endList() => _builder.addByte(DataKind.endList.index);
+
+  @override
+  void startList() => _builder.addByte(DataKind.startList.index);
+
+  @override
+  Uint8List get result => _builder.takeBytes();
+}
+
+class ByteDataDeserializer extends Deserializer {
+  final ByteData _bytes;
+  int _byteOffset = 0;
+  int? _byteOffsetIncrement = 0;
+
+  ByteDataDeserializer(this._bytes);
+
+  /// Reads the next [DataKind] and advances [_byteOffset].
+  DataKind _readKind([int offset = 0]) {
+    int value = _bytes.getUint8(_byteOffset + offset);
+    if (value < DataKind.values.length) {
+      return DataKind.values[value];
+    } else {
+      return DataKind.directEncodedUint8;
+    }
+  }
+
+  @override
+  bool checkNull() {
+    _byteOffsetIncrement = 1;
+    return _readKind() == DataKind.nil;
+  }
+
+  @override
+  bool expectBool() {
+    DataKind kind = _readKind();
+    _byteOffsetIncrement = 1;
+    if (kind == DataKind.boolTrue) {
+      return true;
+    } else if (kind == DataKind.boolFalse) {
+      return false;
+    } else {
+      throw new StateError('Expected a bool but found a $kind');
+    }
+  }
+
+  @override
+  double expectDouble() {
+    DataKind kind = _readKind();
+    if (kind != DataKind.float64) {
+      throw new StateError('Expected a double but found a $kind');
+    }
+    _byteOffsetIncrement = 9;
+    return _bytes.getFloat64(_byteOffset + 1);
+  }
+
+  @override
+  int expectInt() => _expectInt(0);
+
+  int _expectInt(int offset) {
+    DataKind kind = _readKind(offset);
+    if (kind == DataKind.directEncodedUint8) {
+      _byteOffsetIncrement = offset + 1;
+      return _bytes.getUint8(_byteOffset + offset) - DataKind.values.length;
+    }
+    offset += 1;
+    int result;
+    switch (kind) {
+      case DataKind.int8:
+        result = _bytes.getInt8(_byteOffset + offset);
+        _byteOffsetIncrement = 1 + offset;
+        break;
+      case DataKind.int16:
+        result = _bytes.getInt16(_byteOffset + offset);
+        _byteOffsetIncrement = 2 + offset;
+        break;
+      case DataKind.int32:
+        result = _bytes.getInt32(_byteOffset + offset);
+        _byteOffsetIncrement = 4 + offset;
+        break;
+      case DataKind.int64:
+        result = _bytes.getInt64(_byteOffset + offset);
+        _byteOffsetIncrement = 8 + offset;
+        break;
+      case DataKind.uint8:
+        result = _bytes.getUint8(_byteOffset + offset);
+        _byteOffsetIncrement = 1 + offset;
+        break;
+      case DataKind.uint16:
+        result = _bytes.getUint16(_byteOffset + offset);
+        _byteOffsetIncrement = 2 + offset;
+        break;
+      case DataKind.uint32:
+        result = _bytes.getUint32(_byteOffset + offset);
+        _byteOffsetIncrement = 4 + offset;
+        break;
+      case DataKind.uint64:
+        result = _bytes.getUint64(_byteOffset + offset);
+        _byteOffsetIncrement = 8 + offset;
+        break;
+      default:
+        throw new StateError('Expected an int but found a $kind');
+    }
+    return result;
+  }
+
+  @override
+  void expectList() {
+    DataKind kind = _readKind();
+    if (kind != DataKind.startList) {
+      throw new StateError('Expected the start to a list but found a $kind');
+    }
+    _byteOffsetIncrement = 1;
+  }
+
+  @override
+  String expectString() {
+    DataKind kind = _readKind();
+    int length = _expectInt(1);
+    int offset = _byteOffsetIncrement! + _byteOffset;
+    if (kind == DataKind.oneByteString) {
+      _byteOffsetIncrement = _byteOffsetIncrement! + length;
+      return new String.fromCharCodes(
+          _bytes.buffer.asUint8List(offset, length));
+    } else if (kind == DataKind.twoByteString) {
+      length = length * 2;
+      _byteOffsetIncrement = _byteOffsetIncrement! + length;
+      Uint8List bytes =
+          new Uint8List.fromList(_bytes.buffer.asUint8List(offset, length));
+      return new String.fromCharCodes(bytes.buffer.asUint16List());
+    } else {
+      throw new StateError('Expected a string but found a $kind');
+    }
+  }
+
+  @override
+  bool moveNext() {
+    int? increment = _byteOffsetIncrement;
+    _byteOffsetIncrement = null;
+    if (increment == null) {
+      throw new StateError("Can't move until consuming the current element");
+    }
+    _byteOffset += increment;
+    if (_byteOffset >= _bytes.lengthInBytes) {
+      return false;
+    } else if (_readKind() == DataKind.endList) {
+      // You don't explicitly consume list end markers.
+      _byteOffsetIncrement = 1;
+      return false;
+    } else {
+      return true;
+    }
+  }
+}
+
+enum DataKind {
+  nil,
+  boolTrue,
+  boolFalse,
+  directEncodedUint8, // Encoded in the kind byte.
+  startList,
+  endList,
+  int8,
+  int16,
+  int32,
+  int64,
+  uint8,
+  uint16,
+  uint32,
+  uint64,
+  float64,
+  oneByteString,
+  twoByteString,
+}
+
+/// Must be set using `withSerializationMode` before doing any serialization or
+/// deserialization.
+SerializationMode get serializationMode {
+  SerializationMode? mode =
+      Zone.current[#serializationMode] as SerializationMode?;
+  if (mode == null) {
+    throw new StateError('No SerializationMode set, you must do all '
+        'serialization inside a call to `withSerializationMode`.');
+  }
+  return mode;
+}
+
+/// Returns the current deserializer factory for the zone.
+Deserializer Function(Object?) get deserializerFactory {
+  switch (serializationMode) {
+    case SerializationMode.byteDataClient:
+    case SerializationMode.byteDataServer:
+      return (Object? message) => new ByteDataDeserializer(
+          new ByteData.sublistView(message as Uint8List));
+    case SerializationMode.jsonClient:
+    case SerializationMode.jsonServer:
+      return (Object? message) =>
+          new JsonDeserializer(message as Iterable<Object?>);
+  }
+}
+
+/// Returns the current serializer factory for the zone.
+Serializer Function() get serializerFactory {
+  switch (serializationMode) {
+    case SerializationMode.byteDataClient:
+    case SerializationMode.byteDataServer:
+      return () => new ByteDataSerializer();
+    case SerializationMode.jsonClient:
+    case SerializationMode.jsonServer:
+      return () => new JsonSerializer();
+  }
+}
+
+/// Some objects are serialized differently on the client side versus the server
+/// side. This indicates the different modes, as well as the format used.
+enum SerializationMode {
+  byteDataClient,
+  byteDataServer,
+  jsonServer,
+  jsonClient,
+}
+
+extension SerializationModeHelpers on SerializationMode {
+  bool get isClient {
+    switch (this) {
+      case SerializationMode.byteDataClient:
+      case SerializationMode.jsonClient:
+        return true;
+      case SerializationMode.byteDataServer:
+      case SerializationMode.jsonServer:
+        return false;
+    }
+  }
+
+  /// A stable string to write in code.
+  String get asCode {
+    switch (this) {
+      case SerializationMode.byteDataClient:
+        return 'SerializationMode.byteDataClient';
+      case SerializationMode.byteDataServer:
+        return 'SerializationMode.byteDataServer';
+      case SerializationMode.jsonClient:
+        return 'SerializationMode.jsonClient';
+      case SerializationMode.jsonServer:
+        return 'SerializationMode.jsonServer';
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart
new file mode 100644
index 0000000..d039f7d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart
@@ -0,0 +1,401 @@
+import 'package:_fe_analyzer_shared/src/macros/executor/introspection_impls.dart';
+
+import 'remote_instance.dart';
+import 'serialization.dart';
+import '../api.dart';
+
+extension DeserializerExtensions on Deserializer {
+  T expectRemoteInstance<T>() {
+    int id = expectInt();
+
+    // Server side we just return the cached remote instance by ID.
+    if (!serializationMode.isClient) {
+      return RemoteInstance.cached(id) as T;
+    }
+
+    moveNext();
+    RemoteInstanceKind kind = RemoteInstanceKind.values[expectInt()];
+    switch (kind) {
+      case RemoteInstanceKind.classIntrospector:
+      case RemoteInstanceKind.identifierResolver:
+      case RemoteInstanceKind.namedStaticType:
+      case RemoteInstanceKind.staticType:
+      case RemoteInstanceKind.typeDeclarationResolver:
+      case RemoteInstanceKind.typeResolver:
+        // These are simple wrappers, just pass in the kind
+        return new RemoteInstanceImpl(id: id, kind: kind) as T;
+      case RemoteInstanceKind.classDeclaration:
+        moveNext();
+        return _expectClassDeclaration(id) as T;
+      case RemoteInstanceKind.constructorDeclaration:
+        moveNext();
+        return _expectConstructorDeclaration(id) as T;
+      case RemoteInstanceKind.fieldDeclaration:
+        moveNext();
+        return _expectFieldDeclaration(id) as T;
+      case RemoteInstanceKind.functionDeclaration:
+        moveNext();
+        return _expectFunctionDeclaration(id) as T;
+      case RemoteInstanceKind.functionTypeAnnotation:
+        moveNext();
+        return _expectFunctionTypeAnnotation(id) as T;
+      case RemoteInstanceKind.identifier:
+        moveNext();
+        return _expectIdentifier(id) as T;
+      case RemoteInstanceKind.methodDeclaration:
+        moveNext();
+        return _expectMethodDeclaration(id) as T;
+      case RemoteInstanceKind.namedTypeAnnotation:
+        moveNext();
+        return _expectNamedTypeAnnotation(id) as T;
+      case RemoteInstanceKind.parameterDeclaration:
+        moveNext();
+        return _expectParameterDeclaration(id) as T;
+      case RemoteInstanceKind.typeAliasDeclaration:
+        moveNext();
+        return _expectTypeAliasDeclaration(id) as T;
+      case RemoteInstanceKind.typeParameterDeclaration:
+        moveNext();
+        return _expectTypeParameterDeclaration(id) as T;
+      case RemoteInstanceKind.variableDeclaration:
+        moveNext();
+        return _expectVariableDeclaration(id) as T;
+    }
+  }
+
+  /// Helper method to read a list of [RemoteInstance]s.
+  List<T> _expectRemoteInstanceList<T extends RemoteInstance>() {
+    expectList();
+    return [
+      for (bool hasNext = moveNext(); hasNext; hasNext = moveNext())
+        expectRemoteInstance(),
+    ];
+  }
+
+  NamedTypeAnnotation _expectNamedTypeAnnotation(int id) =>
+      new NamedTypeAnnotationImpl(
+        id: id,
+        isNullable: expectBool(),
+        identifier: RemoteInstance.deserialize(this),
+        typeArguments: (this..moveNext())._expectRemoteInstanceList(),
+      );
+
+  FunctionTypeAnnotation _expectFunctionTypeAnnotation(int id) =>
+      new FunctionTypeAnnotationImpl(
+        id: id,
+        isNullable: expectBool(),
+        returnType: RemoteInstance.deserialize(this),
+        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
+        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+      );
+
+  Identifier _expectIdentifier(int id) => new IdentifierImpl(
+        id: id,
+        name: expectString(),
+      );
+
+  ParameterDeclaration _expectParameterDeclaration(int id) =>
+      new ParameterDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isNamed: (this..moveNext()).expectBool(),
+        isRequired: (this..moveNext()).expectBool(),
+        type: RemoteInstance.deserialize(this),
+      );
+
+  TypeParameterDeclaration _expectTypeParameterDeclaration(int id) =>
+      new TypeParameterDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        bound: (this..moveNext()).checkNull() ? null : expectRemoteInstance(),
+      );
+
+  FunctionDeclaration _expectFunctionDeclaration(int id) =>
+      new FunctionDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isAbstract: (this..moveNext()).expectBool(),
+        isExternal: (this..moveNext()).expectBool(),
+        isGetter: (this..moveNext()).expectBool(),
+        isOperator: (this..moveNext()).expectBool(),
+        isSetter: (this..moveNext()).expectBool(),
+        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
+        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
+        returnType: RemoteInstance.deserialize(this),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+      );
+
+  MethodDeclaration _expectMethodDeclaration(int id) =>
+      new MethodDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isAbstract: (this..moveNext()).expectBool(),
+        isExternal: (this..moveNext()).expectBool(),
+        isGetter: (this..moveNext()).expectBool(),
+        isOperator: (this..moveNext()).expectBool(),
+        isSetter: (this..moveNext()).expectBool(),
+        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
+        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
+        returnType: RemoteInstance.deserialize(this),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+        definingClass: RemoteInstance.deserialize(this),
+        isStatic: (this..moveNext()).expectBool(),
+      );
+
+  ConstructorDeclaration _expectConstructorDeclaration(int id) =>
+      new ConstructorDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isAbstract: (this..moveNext()).expectBool(),
+        isExternal: (this..moveNext()).expectBool(),
+        isGetter: (this..moveNext()).expectBool(),
+        isOperator: (this..moveNext()).expectBool(),
+        isSetter: (this..moveNext()).expectBool(),
+        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
+        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
+        returnType: RemoteInstance.deserialize(this),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+        definingClass: RemoteInstance.deserialize(this),
+        // There is an extra boolean here representing the `isStatic` field
+        // which we just skip past.
+        isFactory: (this
+              ..moveNext()
+              ..expectBool()
+              ..moveNext())
+            .expectBool(),
+      );
+
+  VariableDeclaration _expectVariableDeclaration(int id) =>
+      new VariableDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isExternal: (this..moveNext()).expectBool(),
+        isFinal: (this..moveNext()).expectBool(),
+        isLate: (this..moveNext()).expectBool(),
+        type: RemoteInstance.deserialize(this),
+      );
+
+  FieldDeclaration _expectFieldDeclaration(int id) => new FieldDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        isExternal: (this..moveNext()).expectBool(),
+        isFinal: (this..moveNext()).expectBool(),
+        isLate: (this..moveNext()).expectBool(),
+        type: RemoteInstance.deserialize(this),
+        definingClass: RemoteInstance.deserialize(this),
+        isStatic: (this..moveNext()).expectBool(),
+      );
+
+  ClassDeclaration _expectClassDeclaration(int id) => new ClassDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+        interfaces: (this..moveNext())._expectRemoteInstanceList(),
+        isAbstract: (this..moveNext()).expectBool(),
+        isExternal: (this..moveNext()).expectBool(),
+        mixins: (this..moveNext())._expectRemoteInstanceList(),
+        superclass:
+            (this..moveNext()).checkNull() ? null : expectRemoteInstance(),
+      );
+
+  TypeAliasDeclaration _expectTypeAliasDeclaration(int id) =>
+      new TypeAliasDeclarationImpl(
+        id: id,
+        identifier: expectRemoteInstance(),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+        aliasedType: RemoteInstance.deserialize(this),
+      );
+
+  List<String> _readStringList() => [
+        for (bool hasNext = (this
+                  ..moveNext()
+                  ..expectList())
+                .moveNext();
+            hasNext;
+            hasNext = moveNext())
+          expectString(),
+      ];
+
+  List<T> _readCodeList<T extends Code>() => [
+        for (bool hasNext = (this
+                  ..moveNext()
+                  ..expectList())
+                .moveNext();
+            hasNext;
+            hasNext = moveNext())
+          expectCode(),
+      ];
+
+  List<Object> _readParts() {
+    moveNext();
+    expectList();
+    List<Object> parts = [];
+    while (moveNext()) {
+      _CodePartKind partKind = _CodePartKind.values[expectInt()];
+      moveNext();
+      switch (partKind) {
+        case _CodePartKind.code:
+          parts.add(expectCode());
+          break;
+        case _CodePartKind.string:
+          parts.add(expectString());
+          break;
+        case _CodePartKind.identifier:
+          parts.add(expectRemoteInstance());
+          break;
+      }
+    }
+    return parts;
+  }
+
+  T expectCode<T extends Code>() {
+    CodeKind kind = CodeKind.values[expectInt()];
+
+    switch (kind) {
+      case CodeKind.raw:
+        return new Code.fromParts(_readParts()) as T;
+      case CodeKind.declaration:
+        return new DeclarationCode.fromParts(_readParts()) as T;
+      case CodeKind.expression:
+        return new ExpressionCode.fromParts(_readParts()) as T;
+      case CodeKind.functionBody:
+        return new FunctionBodyCode.fromParts(_readParts()) as T;
+      case CodeKind.functionTypeAnnotation:
+        return new FunctionTypeAnnotationCode(
+            namedParameters: _readCodeList(),
+            positionalParameters: _readCodeList(),
+            returnType: (this..moveNext()).expectNullableCode(),
+            typeParameters: _readCodeList()) as T;
+      case CodeKind.namedTypeAnnotation:
+        return new NamedTypeAnnotationCode(
+            name: RemoteInstance.deserialize(this),
+            typeArguments: _readCodeList()) as T;
+      case CodeKind.nullableTypeAnnotation:
+        return new NullableTypeAnnotationCode((this..moveNext()).expectCode())
+            as T;
+      case CodeKind.parameter:
+        return new ParameterCode(
+            defaultValue: (this..moveNext()).expectNullableCode(),
+            keywords: _readStringList(),
+            name: (this..moveNext()).expectString(),
+            type: (this..moveNext()).expectNullableCode()) as T;
+      case CodeKind.typeParameter:
+        return new TypeParameterCode(
+            bound: (this..moveNext()).expectNullableCode(),
+            name: (this..moveNext()).expectString()) as T;
+    }
+  }
+
+  T? expectNullableCode<T extends Code>() {
+    if (checkNull()) return null;
+    return expectCode();
+  }
+}
+
+extension SerializeNullable on Serializable? {
+  /// Either serializes a `null` literal or the object.
+  void serializeNullable(Serializer serializer) {
+    Serializable? self = this;
+    if (self == null) {
+      serializer.addNull();
+    } else {
+      self.serialize(serializer);
+    }
+  }
+}
+
+extension SerializeNullableCode on Code? {
+  /// Either serializes a `null` literal or the code object.
+  void serializeNullable(Serializer serializer) {
+    Code? self = this;
+    if (self == null) {
+      serializer.addNull();
+    } else {
+      self.serialize(serializer);
+    }
+  }
+}
+
+extension SerializeCode on Code {
+  void serialize(Serializer serializer) {
+    serializer.addInt(kind.index);
+    switch (kind) {
+      case CodeKind.namedTypeAnnotation:
+        NamedTypeAnnotationCode self = this as NamedTypeAnnotationCode;
+        (self.name as IdentifierImpl).serialize(serializer);
+        serializer.startList();
+        for (TypeAnnotationCode typeArg in self.typeArguments) {
+          typeArg.serialize(serializer);
+        }
+        serializer.endList();
+        return;
+      case CodeKind.functionTypeAnnotation:
+        FunctionTypeAnnotationCode self = this as FunctionTypeAnnotationCode;
+        serializer.startList();
+        for (ParameterCode named in self.namedParameters) {
+          named.serialize(serializer);
+        }
+        serializer
+          ..endList()
+          ..startList();
+        for (ParameterCode positional in self.positionalParameters) {
+          positional.serialize(serializer);
+        }
+        serializer..endList();
+        self.returnType.serializeNullable(serializer);
+        serializer.startList();
+        for (TypeParameterCode typeParam in self.typeParameters) {
+          typeParam.serialize(serializer);
+        }
+        serializer.endList();
+        return;
+      case CodeKind.nullableTypeAnnotation:
+        NullableTypeAnnotationCode self = this as NullableTypeAnnotationCode;
+        self.underlyingType.serialize(serializer);
+        return;
+      case CodeKind.parameter:
+        ParameterCode self = this as ParameterCode;
+        self.defaultValue.serializeNullable(serializer);
+        serializer.startList();
+        for (String keyword in self.keywords) {
+          serializer.addString(keyword);
+        }
+        serializer
+          ..endList()
+          ..addString(self.name);
+        self.type.serializeNullable(serializer);
+        return;
+      case CodeKind.typeParameter:
+        TypeParameterCode self = this as TypeParameterCode;
+        self.bound.serializeNullable(serializer);
+        serializer.addString(self.name);
+        return;
+      default:
+        serializer.startList();
+        for (Object part in parts) {
+          if (part is String) {
+            serializer
+              ..addInt(_CodePartKind.string.index)
+              ..addString(part);
+          } else if (part is Code) {
+            serializer.addInt(_CodePartKind.code.index);
+            part.serialize(serializer);
+          } else if (part is IdentifierImpl) {
+            serializer.addInt(_CodePartKind.identifier.index);
+            part.serialize(serializer);
+          } else {
+            throw new StateError('Unrecognized code part $part');
+          }
+        }
+        serializer.endList();
+        return;
+    }
+  }
+}
+
+enum _CodePartKind {
+  string,
+  code,
+  identifier,
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
deleted file mode 100644
index 099c58e..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
+++ /dev/null
@@ -1,378 +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 'dart:async';
-
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
-
-import '../executor.dart';
-import '../api.dart';
-import 'response_impls.dart';
-
-class TypeBuilderBase {
-  /// The final result, will be built up over `augment` calls.
-  final List<DeclarationCode> _augmentations;
-
-  /// Creates and returns a [MacroExecutionResult] out of the [_augmentations]
-  /// created by this builder.
-  MacroExecutionResult get result => new MacroExecutionResultImpl(
-        augmentations: _augmentations,
-        // TODO: Implement `imports`, or possibly drop it?
-        imports: [],
-      );
-
-  TypeBuilderBase({List<DeclarationCode>? parentAugmentations})
-      : _augmentations = parentAugmentations ?? [];
-}
-
-class TypeBuilderImpl extends TypeBuilderBase implements TypeBuilder {
-  @override
-  void declareType(DeclarationCode typeDeclaration) {
-    _augmentations.add(typeDeclaration);
-  }
-}
-
-/// Base class for all [DeclarationBuilder]s.
-class DeclarationBuilderBase extends TypeBuilderBase
-    implements ClassIntrospector, TypeResolver {
-  final ClassIntrospector classIntrospector;
-  final TypeResolver typeResolver;
-
-  DeclarationBuilderBase(this.classIntrospector, this.typeResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(parentAugmentations: parentAugmentations);
-
-  @override
-  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
-      classIntrospector.constructorsOf(clazz);
-
-  @override
-  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
-      classIntrospector.fieldsOf(clazz);
-
-  @override
-  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
-      classIntrospector.interfacesOf(clazz);
-
-  @override
-  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
-      classIntrospector.methodsOf(clazz);
-
-  @override
-  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
-      classIntrospector.mixinsOf(clazz);
-
-  @override
-  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
-      classIntrospector.superclassOf(clazz);
-
-  @override
-  Future<StaticType> instantiateCode(ExpressionCode code) =>
-      typeResolver.instantiateCode(code);
-
-  @override
-  Future<StaticType> instantiateType(TypeAnnotation typeAnnotation) =>
-      typeResolver.instantiateType(typeAnnotation);
-}
-
-class DeclarationBuilderImpl extends DeclarationBuilderBase
-    implements DeclarationBuilder {
-  DeclarationBuilderImpl(
-      ClassIntrospector classIntrospector, TypeResolver typeResolver)
-      : super(classIntrospector, typeResolver);
-
-  @override
-  void declareInLibrary(DeclarationCode declaration) {
-    _augmentations.add(declaration);
-  }
-}
-
-class ClassMemberDeclarationBuilderImpl extends DeclarationBuilderImpl
-    implements ClassMemberDeclarationBuilder {
-  final Identifier definingClass;
-
-  ClassMemberDeclarationBuilderImpl(this.definingClass,
-      ClassIntrospector classIntrospector, TypeResolver typeResolver)
-      : super(classIntrospector, typeResolver);
-
-  @override
-  void declareInClass(DeclarationCode declaration) {
-    _augmentations.add(_buildClassAugmentation(definingClass, [declaration]));
-  }
-}
-
-/// Base class for all [DefinitionBuilder]s.
-class DefinitionBuilderBase extends DeclarationBuilderBase
-    implements TypeDeclarationResolver {
-  final TypeDeclarationResolver typeDeclarationResolver;
-
-  DefinitionBuilderBase(ClassIntrospector classIntrospector,
-      TypeResolver typeResolver, this.typeDeclarationResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(classIntrospector, typeResolver,
-            parentAugmentations: parentAugmentations);
-
-  @override
-  Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) =>
-      typeDeclarationResolver.declarationOf(identifier);
-}
-
-class ClassDefinitionBuilderImpl extends DefinitionBuilderBase
-    implements ClassDefinitionBuilder {
-  /// The declaration this is a builder for.
-  final ClassDeclaration declaration;
-
-  ClassDefinitionBuilderImpl(
-      this.declaration,
-      ClassIntrospector classIntrospector,
-      TypeResolver typeResolver,
-      TypeDeclarationResolver typeDeclarationResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(classIntrospector, typeResolver, typeDeclarationResolver,
-            parentAugmentations: parentAugmentations);
-
-  @override
-  Future<ConstructorDefinitionBuilder> buildConstructor(
-      Identifier identifier) async {
-    ConstructorDeclaration constructor =
-        (await classIntrospector.constructorsOf(declaration))
-            .firstWhere((constructor) => constructor.identifier == identifier);
-    return new ConstructorDefinitionBuilderImpl(
-        constructor, classIntrospector, typeResolver, typeDeclarationResolver,
-        parentAugmentations: _augmentations);
-  }
-
-  @override
-  Future<VariableDefinitionBuilder> buildField(Identifier identifier) async {
-    FieldDeclaration field = (await classIntrospector.fieldsOf(declaration))
-        .firstWhere((field) => field.identifier == identifier);
-    return new VariableDefinitionBuilderImpl(
-        field, classIntrospector, typeResolver, typeDeclarationResolver,
-        parentAugmentations: _augmentations);
-  }
-
-  @override
-  Future<FunctionDefinitionBuilder> buildMethod(Identifier identifier) async {
-    MethodDeclaration method = (await classIntrospector.methodsOf(declaration))
-        .firstWhere((method) => method.identifier == identifier);
-    return new FunctionDefinitionBuilderImpl(
-        method, classIntrospector, typeResolver, typeDeclarationResolver,
-        parentAugmentations: _augmentations);
-  }
-}
-
-/// Implementation of [FunctionDefinitionBuilder].
-class FunctionDefinitionBuilderImpl extends DefinitionBuilderBase
-    implements FunctionDefinitionBuilder {
-  final FunctionDeclaration declaration;
-
-  FunctionDefinitionBuilderImpl(
-      this.declaration,
-      ClassIntrospector classIntrospector,
-      TypeResolver typeResolver,
-      TypeDeclarationResolver typeDeclarationResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(classIntrospector, typeResolver, typeDeclarationResolver,
-            parentAugmentations: parentAugmentations);
-
-  @override
-  void augment(FunctionBodyCode body) {
-    DeclarationCode augmentation =
-        _buildFunctionAugmentation(body, declaration);
-    if (declaration is ClassMemberDeclaration) {
-      augmentation = _buildClassAugmentation(
-          (declaration as ClassMemberDeclaration).definingClass,
-          [augmentation]);
-    }
-    _augmentations.add(augmentation);
-  }
-}
-
-class ConstructorDefinitionBuilderImpl extends DefinitionBuilderBase
-    implements ConstructorDefinitionBuilder {
-  final ConstructorDeclaration declaration;
-
-  ConstructorDefinitionBuilderImpl(
-      this.declaration,
-      ClassIntrospector classIntrospector,
-      TypeResolver typeResolver,
-      TypeDeclarationResolver typeDeclarationResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(classIntrospector, typeResolver, typeDeclarationResolver,
-            parentAugmentations: parentAugmentations);
-
-  @override
-  void augment({FunctionBodyCode? body, List<Code>? initializers}) {
-    body ??= new FunctionBodyCode.fromString('''{
-      augment super();
-    }''');
-    _augmentations.add(_buildClassAugmentation(declaration.definingClass, [
-      _buildFunctionAugmentation(body, declaration, initializers: initializers)
-    ]));
-  }
-}
-
-class VariableDefinitionBuilderImpl extends DefinitionBuilderBase
-    implements VariableDefinitionBuilder {
-  final VariableDeclaration declaration;
-
-  VariableDefinitionBuilderImpl(
-      this.declaration,
-      ClassIntrospector classIntrospector,
-      TypeResolver typeResolver,
-      TypeDeclarationResolver typeDeclarationResolver,
-      {List<DeclarationCode>? parentAugmentations})
-      : super(classIntrospector, typeResolver, typeDeclarationResolver,
-            parentAugmentations: parentAugmentations);
-
-  @override
-  void augment(
-      {DeclarationCode? getter,
-      DeclarationCode? setter,
-      ExpressionCode? initializer}) {
-    List<DeclarationCode> augmentations = _buildVariableAugmentations(
-        declaration,
-        getter: getter,
-        setter: setter,
-        initializer: initializer);
-    if (declaration is ClassMemberDeclaration) {
-      augmentations = [
-        _buildClassAugmentation(
-            (declaration as ClassMemberDeclaration).definingClass,
-            augmentations)
-      ];
-    }
-
-    _augmentations.addAll(augmentations);
-  }
-}
-
-/// Creates an augmentation of [clazz] with member [augmentations].
-DeclarationCode _buildClassAugmentation(
-        Identifier clazz, List<DeclarationCode> augmentations) =>
-    new DeclarationCode.fromParts([
-      'augment class ',
-      clazz,
-      ' {\n',
-      ...augmentations.joinAsCode('\n'),
-      '\n}',
-    ]);
-
-/// Builds all the possible augmentations for a variable.
-List<DeclarationCode> _buildVariableAugmentations(
-    VariableDeclaration declaration,
-    {DeclarationCode? getter,
-    DeclarationCode? setter,
-    ExpressionCode? initializer}) {
-  List<DeclarationCode> augmentations = [];
-  if (getter != null) {
-    augmentations.add(new DeclarationCode.fromParts([
-      'augment ',
-      getter,
-    ]));
-  }
-  if (setter != null) {
-    augmentations.add(new DeclarationCode.fromParts([
-      'augment ',
-      setter,
-    ]));
-  }
-  if (initializer != null) {
-    augmentations.add(new DeclarationCode.fromParts([
-      'augment ',
-      if (declaration.isFinal) 'final ',
-      declaration.type.code,
-      ' ',
-      declaration.identifier,
-      ' = ',
-      initializer,
-      ';',
-    ]));
-  }
-
-  return augmentations;
-}
-
-/// Builds the code to augment a function, method, or constructor with a new
-/// body.
-///
-/// The [initializers] parameter can only be used if [declaration] is a
-/// constructor.
-DeclarationCode _buildFunctionAugmentation(
-    FunctionBodyCode body, FunctionDeclaration declaration,
-    {List<Code>? initializers}) {
-  assert(initializers == null || declaration is ConstructorDeclaration);
-
-  return new DeclarationCode.fromParts([
-    'augment ',
-    if (declaration is ConstructorDeclaration) ...[
-      declaration.definingClass,
-      if (declaration.identifier.name.isNotEmpty) '.',
-    ] else ...[
-      declaration.returnType.code,
-      ' ',
-    ],
-    declaration.identifier,
-    if (declaration.typeParameters.isNotEmpty) ...[
-      '<',
-      for (TypeParameterDeclaration typeParam
-          in declaration.typeParameters) ...[
-        typeParam.identifier,
-        if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
-        if (typeParam != declaration.typeParameters.last) ', ',
-      ],
-      '>',
-    ],
-    '(',
-    for (ParameterDeclaration positionalRequired
-        in declaration.positionalParameters.where((p) => p.isRequired)) ...[
-      new ParameterCode.fromParts([
-        positionalRequired.type.code,
-        ' ',
-        positionalRequired.identifier,
-      ]),
-      ', '
-    ],
-    if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
-      '[',
-      for (ParameterDeclaration positionalOptional
-          in declaration.positionalParameters.where((p) => !p.isRequired)) ...[
-        new ParameterCode.fromParts([
-          positionalOptional.type.code,
-          ' ',
-          positionalOptional.identifier,
-        ]),
-        ', ',
-      ],
-      ']',
-    ],
-    if (declaration.namedParameters.isNotEmpty) ...[
-      '{',
-      for (ParameterDeclaration named in declaration.namedParameters) ...[
-        new ParameterCode.fromParts([
-          if (named.isRequired) 'required ',
-          named.type.code,
-          ' ',
-          named.identifier,
-          if (named.defaultValue != null) ...[
-            ' = ',
-            named.defaultValue!,
-          ],
-        ]),
-        ', ',
-      ],
-      '}',
-    ],
-    ') ',
-    if (initializers != null && initializers.isNotEmpty) ...[
-      ' : ',
-      initializers.first,
-      for (Code initializer in initializers.skip(1)) ...[
-        ',\n',
-        initializer,
-      ],
-    ],
-    body,
-  ]);
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
deleted file mode 100644
index 7488445..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
+++ /dev/null
@@ -1,147 +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 'package:_fe_analyzer_shared/src/macros/executor.dart';
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/builder_impls.dart';
-import 'package:_fe_analyzer_shared/src/macros/api.dart';
-
-/// Runs [macro] in the types phase and returns a  [MacroExecutionResult].
-Future<MacroExecutionResult> executeTypesMacro(
-    Macro macro, Declaration declaration) async {
-  TypeBuilderImpl builder = new TypeBuilderImpl();
-  if (declaration is FunctionDeclaration) {
-    if (macro is ConstructorTypesMacro &&
-        declaration is ConstructorDeclaration) {
-      await macro.buildTypesForConstructor(declaration, builder);
-      return builder.result;
-    } else if (macro is MethodTypesMacro && declaration is MethodDeclaration) {
-      await macro.buildTypesForMethod(declaration, builder);
-      return builder.result;
-    } else if (macro is FunctionTypesMacro) {
-      await macro.buildTypesForFunction(declaration, builder);
-      return builder.result;
-    }
-  } else if (declaration is VariableDeclaration) {
-    if (macro is FieldTypesMacro && declaration is FieldDeclaration) {
-      await macro.buildTypesForField(declaration, builder);
-      return builder.result;
-    } else if (macro is VariableTypesMacro) {
-      await macro.buildTypesForVariable(declaration, builder);
-      return builder.result;
-    }
-  } else if (macro is ClassTypesMacro && declaration is ClassDeclaration) {
-    await macro.buildTypesForClass(declaration, builder);
-    return builder.result;
-  }
-  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
-      'macro: $macro\ndeclaration: $declaration');
-}
-
-/// Runs [macro] in the declaration phase and returns a  [MacroExecutionResult].
-Future<MacroExecutionResult> executeDeclarationsMacro(
-    Macro macro,
-    Declaration declaration,
-    ClassIntrospector classIntrospector,
-    TypeResolver typeResolver) async {
-  if (declaration is ClassDeclaration && macro is ClassDeclarationsMacro) {
-    ClassMemberDeclarationBuilderImpl builder =
-        new ClassMemberDeclarationBuilderImpl(
-            declaration.identifier, classIntrospector, typeResolver);
-    await macro.buildDeclarationsForClass(declaration, builder);
-    return builder.result;
-  } else if (declaration is ClassMemberDeclaration) {
-    ClassMemberDeclarationBuilderImpl builder =
-        new ClassMemberDeclarationBuilderImpl(
-            declaration.definingClass, classIntrospector, typeResolver);
-    if (declaration is FunctionDeclaration) {
-      if (macro is ConstructorDeclarationsMacro &&
-          declaration is ConstructorDeclaration) {
-        await macro.buildDeclarationsForConstructor(declaration, builder);
-        return builder.result;
-      } else if (macro is MethodDeclarationsMacro &&
-          declaration is MethodDeclaration) {
-        await macro.buildDeclarationsForMethod(declaration, builder);
-        return builder.result;
-      } else if (macro is FunctionDeclarationsMacro) {
-        await macro.buildDeclarationsForFunction(
-            declaration as FunctionDeclaration, builder);
-        return builder.result;
-      }
-    } else if (declaration is VariableDeclaration) {
-      if (macro is FieldDeclarationsMacro && declaration is FieldDeclaration) {
-        await macro.buildDeclarationsForField(declaration, builder);
-        return builder.result;
-      } else if (macro is VariableDeclarationsMacro) {
-        DeclarationBuilderImpl builder =
-            new DeclarationBuilderImpl(classIntrospector, typeResolver);
-        await macro.buildDeclarationsForVariable(
-            declaration as VariableDeclaration, builder);
-        return builder.result;
-      }
-    }
-  } else {
-    DeclarationBuilderImpl builder =
-        new DeclarationBuilderImpl(classIntrospector, typeResolver);
-    if (declaration is FunctionDeclaration &&
-        macro is FunctionDeclarationsMacro) {
-      await macro.buildDeclarationsForFunction(declaration, builder);
-      return builder.result;
-    } else if (macro is VariableDeclarationsMacro &&
-        declaration is VariableDeclaration) {
-      await macro.buildDeclarationsForVariable(declaration, builder);
-      return builder.result;
-    }
-  }
-  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
-      'macro: $macro\ndeclaration: $declaration');
-}
-
-/// Runs [macro] in the definition phase and returns a  [MacroExecutionResult].
-Future<MacroExecutionResult> executeDefinitionMacro(
-    Macro macro,
-    Declaration declaration,
-    ClassIntrospector classIntrospector,
-    TypeResolver typeResolver,
-    TypeDeclarationResolver typeDeclarationResolver) async {
-  if (declaration is FunctionDeclaration) {
-    if (macro is ConstructorDefinitionMacro &&
-        declaration is ConstructorDeclaration) {
-      ConstructorDefinitionBuilderImpl builder =
-          new ConstructorDefinitionBuilderImpl(declaration, classIntrospector,
-              typeResolver, typeDeclarationResolver);
-      await macro.buildDefinitionForConstructor(declaration, builder);
-      return builder.result;
-    } else {
-      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
-          declaration,
-          classIntrospector,
-          typeResolver,
-          typeDeclarationResolver);
-      if (macro is MethodDefinitionMacro && declaration is MethodDeclaration) {
-        await macro.buildDefinitionForMethod(declaration, builder);
-        return builder.result;
-      } else if (macro is FunctionDefinitionMacro) {
-        await macro.buildDefinitionForFunction(declaration, builder);
-        return builder.result;
-      }
-    }
-  } else if (declaration is VariableDeclaration) {
-    VariableDefinitionBuilderImpl builder = new VariableDefinitionBuilderImpl(
-        declaration, classIntrospector, typeResolver, typeDeclarationResolver);
-    if (macro is FieldDefinitionMacro && declaration is FieldDeclaration) {
-      await macro.buildDefinitionForField(declaration, builder);
-      return builder.result;
-    } else if (macro is VariableDefinitionMacro) {
-      await macro.buildDefinitionForVariable(declaration, builder);
-      return builder.result;
-    }
-  } else if (macro is ClassDefinitionMacro && declaration is ClassDeclaration) {
-    ClassDefinitionBuilderImpl builder = new ClassDefinitionBuilderImpl(
-        declaration, classIntrospector, typeResolver, typeDeclarationResolver);
-    await macro.buildDefinitionForClass(declaration, builder);
-    return builder.result;
-  }
-  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
-      'macro: $macro\ndeclaration: $declaration');
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
deleted file mode 100644
index 64e5e4f..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
+++ /dev/null
@@ -1,653 +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 'remote_instance.dart';
-import 'serialization.dart';
-import 'serialization_extensions.dart';
-import '../api.dart';
-
-class IdentifierImpl extends RemoteInstance implements Identifier {
-  final String name;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.identifier;
-
-  IdentifierImpl({required int id, required this.name}) : super(id);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer.addString(name);
-  }
-}
-
-abstract class TypeAnnotationImpl extends RemoteInstance
-    implements TypeAnnotation {
-  final bool isNullable;
-
-  TypeAnnotationImpl({required int id, required this.isNullable}) : super(id);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer.addBool(isNullable);
-  }
-}
-
-class NamedTypeAnnotationImpl extends TypeAnnotationImpl
-    implements NamedTypeAnnotation {
-  @override
-  Code get code => new Code.fromParts([
-        identifier,
-        if (typeArguments.isNotEmpty) ...[
-          '<',
-          typeArguments.first.code,
-          for (TypeAnnotation arg in typeArguments.skip(1)) ...[', ', arg.code],
-          '>',
-        ],
-        if (isNullable) '?',
-      ]);
-
-  @override
-  final IdentifierImpl identifier;
-
-  @override
-  final List<TypeAnnotationImpl> typeArguments;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.namedTypeAnnotation;
-
-  NamedTypeAnnotationImpl({
-    required int id,
-    required bool isNullable,
-    required this.identifier,
-    required this.typeArguments,
-  }) : super(id: id, isNullable: isNullable);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    identifier.serialize(serializer);
-    serializer.startList();
-    for (TypeAnnotationImpl typeArg in typeArguments) {
-      typeArg.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
-
-class FunctionTypeAnnotationImpl extends TypeAnnotationImpl
-    implements FunctionTypeAnnotation {
-  @override
-  Code get code => new Code.fromParts([
-        returnType.code,
-        'Function',
-        if (typeParameters.isNotEmpty) ...[
-          '<',
-          typeParameters.first.identifier.name,
-          if (typeParameters.first.bounds != null) ...[
-            ' extends ',
-            typeParameters.first.bounds!.code,
-          ],
-          for (TypeParameterDeclaration arg in typeParameters.skip(1)) ...[
-            ', ',
-            arg.identifier.name,
-            if (arg.bounds != null) ...[' extends ', arg.bounds!.code],
-          ],
-          '>',
-        ],
-        '(',
-        for (ParameterDeclaration positional in positionalParameters) ...[
-          positional.type.code,
-          ' ${positional.identifier.name}',
-        ],
-        if (namedParameters.isNotEmpty) ...[
-          '{',
-          for (ParameterDeclaration named in namedParameters) ...[
-            named.type.code,
-            ' ${named.identifier.name}',
-          ],
-          '}',
-        ],
-        ')',
-        if (isNullable) '?',
-      ]);
-
-  @override
-  final List<ParameterDeclarationImpl> namedParameters;
-
-  @override
-  final List<ParameterDeclarationImpl> positionalParameters;
-
-  @override
-  final TypeAnnotationImpl returnType;
-
-  @override
-  final List<TypeParameterDeclarationImpl> typeParameters;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.functionTypeAnnotation;
-
-  FunctionTypeAnnotationImpl({
-    required int id,
-    required bool isNullable,
-    required this.namedParameters,
-    required this.positionalParameters,
-    required this.returnType,
-    required this.typeParameters,
-  }) : super(id: id, isNullable: isNullable);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    returnType.serialize(serializer);
-
-    serializer.startList();
-    for (ParameterDeclarationImpl param in positionalParameters) {
-      param.serialize(serializer);
-    }
-    serializer.endList();
-
-    serializer.startList();
-    for (ParameterDeclarationImpl param in namedParameters) {
-      param.serialize(serializer);
-    }
-    serializer.endList();
-
-    serializer.startList();
-    for (TypeParameterDeclarationImpl typeParam in typeParameters) {
-      typeParam.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
-
-abstract class DeclarationImpl extends RemoteInstance implements Declaration {
-  final IdentifierImpl identifier;
-
-  DeclarationImpl({required int id, required this.identifier}) : super(id);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    identifier.serialize(serializer);
-  }
-}
-
-class ParameterDeclarationImpl extends DeclarationImpl
-    implements ParameterDeclaration {
-  @override
-  final Code? defaultValue;
-
-  @override
-  final bool isNamed;
-
-  @override
-  final bool isRequired;
-
-  @override
-  final TypeAnnotationImpl type;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.parameterDeclaration;
-
-  ParameterDeclarationImpl({
-    required int id,
-    required IdentifierImpl identifier,
-    required this.defaultValue,
-    required this.isNamed,
-    required this.isRequired,
-    required this.type,
-  }) : super(id: id, identifier: identifier);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    if (defaultValue == null) {
-      serializer.addNull();
-    } else {
-      defaultValue!.serialize(serializer);
-    }
-    serializer.addBool(isNamed);
-    serializer.addBool(isRequired);
-    type.serialize(serializer);
-  }
-}
-
-class TypeParameterDeclarationImpl extends DeclarationImpl
-    implements TypeParameterDeclaration {
-  @override
-  final TypeAnnotationImpl? bounds;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.typeParameterDeclaration;
-
-  TypeParameterDeclarationImpl({
-    required int id,
-    required IdentifierImpl identifier,
-    required this.bounds,
-  }) : super(id: id, identifier: identifier);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    TypeAnnotationImpl? bounds = this.bounds;
-    if (bounds == null) {
-      serializer.addNull();
-    } else {
-      bounds.serialize(serializer);
-    }
-  }
-}
-
-class FunctionDeclarationImpl extends DeclarationImpl
-    implements FunctionDeclaration {
-  @override
-  final bool isAbstract;
-
-  @override
-  final bool isExternal;
-
-  @override
-  final bool isGetter;
-
-  @override
-  final bool isSetter;
-
-  @override
-  final List<ParameterDeclarationImpl> namedParameters;
-
-  @override
-  final List<ParameterDeclarationImpl> positionalParameters;
-
-  @override
-  final TypeAnnotationImpl returnType;
-
-  @override
-  final List<TypeParameterDeclarationImpl> typeParameters;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.functionDeclaration;
-
-  FunctionDeclarationImpl({
-    required int id,
-    required IdentifierImpl identifier,
-    required this.isAbstract,
-    required this.isExternal,
-    required this.isGetter,
-    required this.isSetter,
-    required this.namedParameters,
-    required this.positionalParameters,
-    required this.returnType,
-    required this.typeParameters,
-  }) : super(id: id, identifier: identifier);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer
-      ..addBool(isAbstract)
-      ..addBool(isExternal)
-      ..addBool(isGetter)
-      ..addBool(isSetter)
-      ..startList();
-    for (ParameterDeclarationImpl named in namedParameters) {
-      named.serialize(serializer);
-    }
-    serializer
-      ..endList()
-      ..startList();
-    for (ParameterDeclarationImpl positional in positionalParameters) {
-      positional.serialize(serializer);
-    }
-    serializer.endList();
-    returnType.serialize(serializer);
-    serializer.startList();
-    for (TypeParameterDeclarationImpl param in typeParameters) {
-      param.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
-
-class MethodDeclarationImpl extends FunctionDeclarationImpl
-    implements MethodDeclaration {
-  @override
-  final IdentifierImpl definingClass;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.methodDeclaration;
-
-  MethodDeclarationImpl({
-    // Declaration fields
-    required int id,
-    required IdentifierImpl identifier,
-    // Function fields
-    required bool isAbstract,
-    required bool isExternal,
-    required bool isGetter,
-    required bool isSetter,
-    required List<ParameterDeclarationImpl> namedParameters,
-    required List<ParameterDeclarationImpl> positionalParameters,
-    required TypeAnnotationImpl returnType,
-    required List<TypeParameterDeclarationImpl> typeParameters,
-    // Method fields
-    required this.definingClass,
-  }) : super(
-          id: id,
-          identifier: identifier,
-          isAbstract: isAbstract,
-          isExternal: isExternal,
-          isGetter: isGetter,
-          isSetter: isSetter,
-          namedParameters: namedParameters,
-          positionalParameters: positionalParameters,
-          returnType: returnType,
-          typeParameters: typeParameters,
-        );
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    definingClass.serialize(serializer);
-  }
-}
-
-class ConstructorDeclarationImpl extends MethodDeclarationImpl
-    implements ConstructorDeclaration {
-  @override
-  final bool isFactory;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.constructorDeclaration;
-
-  ConstructorDeclarationImpl({
-    // Declaration fields
-    required int id,
-    required IdentifierImpl identifier,
-    // Function fields
-    required bool isAbstract,
-    required bool isExternal,
-    required bool isGetter,
-    required bool isSetter,
-    required List<ParameterDeclarationImpl> namedParameters,
-    required List<ParameterDeclarationImpl> positionalParameters,
-    required TypeAnnotationImpl returnType,
-    required List<TypeParameterDeclarationImpl> typeParameters,
-    // Method fields
-    required IdentifierImpl definingClass,
-    // Constructor fields
-    required this.isFactory,
-  }) : super(
-          id: id,
-          identifier: identifier,
-          isAbstract: isAbstract,
-          isExternal: isExternal,
-          isGetter: isGetter,
-          isSetter: isSetter,
-          namedParameters: namedParameters,
-          positionalParameters: positionalParameters,
-          returnType: returnType,
-          typeParameters: typeParameters,
-          definingClass: definingClass,
-        );
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer.addBool(isFactory);
-  }
-}
-
-class VariableDeclarationImpl extends DeclarationImpl
-    implements VariableDeclaration {
-  @override
-  final ExpressionCode? initializer;
-
-  @override
-  final bool isExternal;
-
-  @override
-  final bool isFinal;
-
-  @override
-  final bool isLate;
-
-  @override
-  final TypeAnnotationImpl type;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.variableDeclaration;
-
-  VariableDeclarationImpl({
-    required int id,
-    required IdentifierImpl identifier,
-    required this.initializer,
-    required this.isExternal,
-    required this.isFinal,
-    required this.isLate,
-    required this.type,
-  }) : super(id: id, identifier: identifier);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    initializer.serializeNullable(serializer);
-    serializer
-      ..addBool(isExternal)
-      ..addBool(isFinal)
-      ..addBool(isLate);
-    type.serialize(serializer);
-  }
-}
-
-class FieldDeclarationImpl extends VariableDeclarationImpl
-    implements FieldDeclaration {
-  @override
-  final IdentifierImpl definingClass;
-
-  FieldDeclarationImpl({
-    // Declaration fields
-    required int id,
-    required IdentifierImpl identifier,
-    // Variable fields
-    required ExpressionCode? initializer,
-    required bool isExternal,
-    required bool isFinal,
-    required bool isLate,
-    required TypeAnnotationImpl type,
-    // Field fields
-    required this.definingClass,
-  }) : super(
-            id: id,
-            identifier: identifier,
-            initializer: initializer,
-            isExternal: isExternal,
-            isFinal: isFinal,
-            isLate: isLate,
-            type: type);
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.fieldDeclaration;
-
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    definingClass.serialize(serializer);
-  }
-}
-
-abstract class TypeDeclarationImpl extends DeclarationImpl
-    implements TypeDeclaration {
-  @override
-  final List<TypeParameterDeclarationImpl> typeParameters;
-
-  TypeDeclarationImpl({
-    required int id,
-    required IdentifierImpl identifier,
-    required this.typeParameters,
-  }) : super(id: id, identifier: identifier);
-
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer..startList();
-    for (TypeParameterDeclarationImpl param in typeParameters) {
-      param.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
-
-class ClassDeclarationImpl extends TypeDeclarationImpl
-    implements ClassDeclaration {
-  @override
-  final List<TypeAnnotationImpl> interfaces;
-
-  @override
-  final bool isAbstract;
-
-  @override
-  final bool isExternal;
-
-  @override
-  final List<TypeAnnotationImpl> mixins;
-
-  @override
-  final TypeAnnotationImpl? superclass;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.classDeclaration;
-
-  ClassDeclarationImpl({
-    // Declaration fields
-    required int id,
-    required IdentifierImpl identifier,
-    // TypeDeclaration fields
-    required List<TypeParameterDeclarationImpl> typeParameters,
-    // ClassDeclaration fields
-    required this.interfaces,
-    required this.isAbstract,
-    required this.isExternal,
-    required this.mixins,
-    required this.superclass,
-  }) : super(id: id, identifier: identifier, typeParameters: typeParameters);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    serializer.startList();
-    for (TypeAnnotationImpl interface in interfaces) {
-      interface.serialize(serializer);
-    }
-    serializer
-      ..endList()
-      ..addBool(isAbstract)
-      ..addBool(isExternal)
-      ..startList();
-    for (TypeAnnotationImpl mixin in mixins) {
-      mixin.serialize(serializer);
-    }
-    serializer..endList();
-    superclass.serializeNullable(serializer);
-  }
-}
-
-class TypeAliasDeclarationImpl extends TypeDeclarationImpl
-    implements TypeAliasDeclaration {
-  /// The type being aliased.
-  final TypeAnnotationImpl aliasedType;
-
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
-
-  TypeAliasDeclarationImpl({
-    // Declaration fields
-    required int id,
-    required IdentifierImpl identifier,
-    // TypeDeclaration fields
-    required List<TypeParameterDeclarationImpl> typeParameters,
-    // TypeAlias fields
-    required this.aliasedType,
-  }) : super(id: id, identifier: identifier, typeParameters: typeParameters);
-
-  @override
-  void serialize(Serializer serializer) {
-    super.serialize(serializer);
-    // Client side we don't encode anything but the ID.
-    if (serializationMode == SerializationMode.client) {
-      return;
-    }
-
-    aliasedType.serialize(serializer);
-  }
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
deleted file mode 100644
index 0577fa2..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
+++ /dev/null
@@ -1,712 +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.
-
-/// Defines the objects used for communication between the macro executor and
-/// the isolate or process doing the work of macro loading and execution.
-library _fe_analyzer_shared.src.macros.executor_shared.protocol;
-
-import 'package:meta/meta.dart';
-
-import '../executor.dart';
-import '../api.dart';
-import '../executor_shared/response_impls.dart';
-import 'introspection_impls.dart';
-import 'remote_instance.dart';
-import 'serialization.dart';
-import 'serialization_extensions.dart';
-
-/// Base class all requests extend, provides a unique id for each request.
-abstract class Request implements Serializable {
-  final int id;
-
-  final int serializationZoneId;
-
-  Request({int? id, required this.serializationZoneId})
-      : this.id = id ?? _next++;
-
-  /// The [serializationZoneId] is a part of the header and needs to be parsed
-  /// before deserializing objects, and then passed in here.
-  Request.deserialize(Deserializer deserializer, this.serializationZoneId)
-      : id = (deserializer..moveNext()).expectNum();
-
-  /// The [serializationZoneId] needs to be separately serialized before the
-  /// rest of the object. This is not done by the instances themselves but by
-  /// the macro implementations.
-  @mustCallSuper
-  void serialize(Serializer serializer) => serializer.addNum(id);
-
-  static int _next = 0;
-}
-
-/// A generic response object that contains either a response or an error, and
-/// a unique ID.
-class Response {
-  final Object? response;
-  final Object? error;
-  final String? stackTrace;
-  final int requestId;
-  final MessageType responseType;
-
-  Response({
-    this.response,
-    this.error,
-    this.stackTrace,
-    required this.requestId,
-    required this.responseType,
-  })  : assert(response != null || error != null),
-        assert(response == null || error == null);
-}
-
-/// A serializable [Response], contains the message type as an enum.
-class SerializableResponse implements Response, Serializable {
-  final Serializable? response;
-  final MessageType responseType;
-  final String? error;
-  final String? stackTrace;
-  final int requestId;
-  final int serializationZoneId;
-
-  SerializableResponse({
-    this.error,
-    this.stackTrace,
-    required this.requestId,
-    this.response,
-    required this.responseType,
-    required this.serializationZoneId,
-  });
-
-  /// You must first parse the [serializationZoneId] yourself, and then
-  /// call this function in that zone, and pass the ID.
-  factory SerializableResponse.deserialize(
-      Deserializer deserializer, int serializationZoneId) {
-    deserializer.moveNext();
-    MessageType responseType = MessageType.values[deserializer.expectNum()];
-    Serializable? response;
-    String? error;
-    String? stackTrace;
-    switch (responseType) {
-      case MessageType.error:
-        deserializer.moveNext();
-        error = deserializer.expectString();
-        deserializer.moveNext();
-        stackTrace = deserializer.expectNullableString();
-        break;
-      case MessageType.macroClassIdentifier:
-        response = new MacroClassIdentifierImpl.deserialize(deserializer);
-        break;
-      case MessageType.macroInstanceIdentifier:
-        response = new MacroInstanceIdentifierImpl.deserialize(deserializer);
-        break;
-      case MessageType.macroExecutionResult:
-        response = new MacroExecutionResultImpl.deserialize(deserializer);
-        break;
-      case MessageType.staticType:
-      case MessageType.namedStaticType:
-        response = RemoteInstance.deserialize(deserializer);
-        break;
-      case MessageType.boolean:
-        response = new BooleanValue.deserialize(deserializer);
-        break;
-      case MessageType.declarationList:
-        response = new DeclarationList.deserialize(deserializer);
-        break;
-      case MessageType.remoteInstance:
-        deserializer.moveNext();
-        if (!deserializer.checkNull()) {
-          response = deserializer.expectRemoteInstance();
-        }
-        break;
-      default:
-        throw new StateError('Unexpected response type $responseType');
-    }
-
-    return new SerializableResponse(
-        responseType: responseType,
-        response: response,
-        error: error,
-        stackTrace: stackTrace,
-        requestId: (deserializer..moveNext()).expectNum(),
-        serializationZoneId: serializationZoneId);
-  }
-
-  void serialize(Serializer serializer) {
-    serializer
-      ..addNum(serializationZoneId)
-      ..addNum(MessageType.response.index)
-      ..addNum(responseType.index);
-    switch (responseType) {
-      case MessageType.error:
-        serializer.addString(error!.toString());
-        serializer.addNullableString(stackTrace);
-        break;
-      default:
-        response.serializeNullable(serializer);
-    }
-    serializer.addNum(requestId);
-  }
-}
-
-class BooleanValue implements Serializable {
-  final bool value;
-
-  BooleanValue(this.value);
-
-  BooleanValue.deserialize(Deserializer deserializer)
-      : value = (deserializer..moveNext()).expectBool();
-
-  @override
-  void serialize(Serializer serializer) => serializer..addBool(value);
-}
-
-/// A serialized list of [Declaration]s.
-class DeclarationList<T extends DeclarationImpl> implements Serializable {
-  final List<T> declarations;
-
-  DeclarationList(this.declarations);
-
-  DeclarationList.deserialize(Deserializer deserializer)
-      : declarations = [
-          for (bool hasNext = (deserializer
-                    ..moveNext()
-                    ..expectList())
-                  .moveNext();
-              hasNext;
-              hasNext = deserializer.moveNext())
-            deserializer.expectRemoteInstance(),
-        ];
-
-  @override
-  void serialize(Serializer serializer) {
-    serializer.startList();
-    for (DeclarationImpl declaration in declarations) {
-      declaration.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
-
-/// A request to load a macro in this isolate.
-class LoadMacroRequest extends Request {
-  final Uri library;
-  final String name;
-
-  LoadMacroRequest(this.library, this.name, {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  LoadMacroRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : library = Uri.parse((deserializer..moveNext()).expectString()),
-        name = (deserializer..moveNext()).expectString(),
-        super.deserialize(deserializer, serializationZoneId);
-
-  @override
-  void serialize(Serializer serializer) {
-    serializer
-      ..addNum(MessageType.loadMacroRequest.index)
-      ..addString(library.toString())
-      ..addString(name);
-    super.serialize(serializer);
-  }
-}
-
-/// A request to instantiate a macro instance.
-class InstantiateMacroRequest extends Request {
-  final MacroClassIdentifier macroClass;
-  final String constructorName;
-  final Arguments arguments;
-
-  InstantiateMacroRequest(this.macroClass, this.constructorName, this.arguments,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  InstantiateMacroRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : macroClass = new MacroClassIdentifierImpl.deserialize(deserializer),
-        constructorName = (deserializer..moveNext()).expectString(),
-        arguments = new Arguments.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  @override
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.instantiateMacroRequest.index);
-    macroClass.serialize(serializer);
-    serializer.addString(constructorName);
-    arguments.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// A request to execute a macro on a particular declaration in the types phase.
-class ExecuteTypesPhaseRequest extends Request {
-  final MacroInstanceIdentifier macro;
-  final DeclarationImpl declaration;
-
-  ExecuteTypesPhaseRequest(this.macro, this.declaration,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  ExecuteTypesPhaseRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
-        declaration = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.executeTypesPhaseRequest.index);
-    macro.serialize(serializer);
-    declaration.serialize(serializer);
-
-    super.serialize(serializer);
-  }
-}
-
-/// A request to execute a macro on a particular declaration in the definition
-/// phase.
-class ExecuteDeclarationsPhaseRequest extends Request {
-  final MacroInstanceIdentifier macro;
-  final DeclarationImpl declaration;
-
-  final RemoteInstanceImpl typeResolver;
-  final RemoteInstanceImpl classIntrospector;
-
-  ExecuteDeclarationsPhaseRequest(
-      this.macro, this.declaration, this.typeResolver, this.classIntrospector,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  ExecuteDeclarationsPhaseRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
-        declaration = RemoteInstance.deserialize(deserializer),
-        typeResolver = RemoteInstance.deserialize(deserializer),
-        classIntrospector = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.executeDeclarationsPhaseRequest.index);
-    macro.serialize(serializer);
-    declaration.serialize(serializer);
-    typeResolver.serialize(serializer);
-    classIntrospector.serialize(serializer);
-
-    super.serialize(serializer);
-  }
-}
-
-/// A request to execute a macro on a particular declaration in the definition
-/// phase.
-class ExecuteDefinitionsPhaseRequest extends Request {
-  final MacroInstanceIdentifier macro;
-  final DeclarationImpl declaration;
-
-  final RemoteInstanceImpl typeResolver;
-  final RemoteInstanceImpl classIntrospector;
-  final RemoteInstanceImpl typeDeclarationResolver;
-
-  ExecuteDefinitionsPhaseRequest(this.macro, this.declaration,
-      this.typeResolver, this.classIntrospector, this.typeDeclarationResolver,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  ExecuteDefinitionsPhaseRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
-        declaration = RemoteInstance.deserialize(deserializer),
-        typeResolver = RemoteInstance.deserialize(deserializer),
-        classIntrospector = RemoteInstance.deserialize(deserializer),
-        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.executeDefinitionsPhaseRequest.index);
-    macro.serialize(serializer);
-    declaration.serialize(serializer);
-    typeResolver.serialize(serializer);
-    classIntrospector.serialize(serializer);
-    typeDeclarationResolver.serialize(serializer);
-
-    super.serialize(serializer);
-  }
-}
-
-/// A request to reflect on a type annotation
-class InstantiateTypeRequest extends Request {
-  final TypeAnnotationImpl typeAnnotation;
-  final RemoteInstanceImpl typeResolver;
-
-  InstantiateTypeRequest(this.typeAnnotation, this.typeResolver,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  InstantiateTypeRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : typeAnnotation = RemoteInstance.deserialize(deserializer),
-        typeResolver = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.instantiateTypeRequest.index);
-    typeAnnotation.serialize(serializer);
-    typeResolver.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// A request to check if a type is exactly another type.
-class IsExactlyTypeRequest extends Request {
-  final RemoteInstanceImpl leftType;
-  final RemoteInstanceImpl rightType;
-
-  IsExactlyTypeRequest(this.leftType, this.rightType,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  IsExactlyTypeRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : leftType = RemoteInstance.deserialize(deserializer),
-        rightType = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.isExactlyTypeRequest.index);
-    leftType.serialize(serializer);
-    rightType.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// A request to check if a type is exactly another type.
-class IsSubtypeOfRequest extends Request {
-  final RemoteInstanceImpl leftType;
-  final RemoteInstanceImpl rightType;
-
-  IsSubtypeOfRequest(this.leftType, this.rightType,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  IsSubtypeOfRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : leftType = RemoteInstance.deserialize(deserializer),
-        rightType = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.isSubtypeOfRequest.index);
-    leftType.serialize(serializer);
-    rightType.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// A general request class for all requests coming from methods on the
-/// [ClassIntrospector] interface.
-class ClassIntrospectionRequest extends Request {
-  final ClassDeclarationImpl classDeclaration;
-  final RemoteInstanceImpl classIntrospector;
-  final MessageType requestKind;
-
-  ClassIntrospectionRequest(
-      this.classDeclaration, this.classIntrospector, this.requestKind,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again and it should instead be passed in here.
-  ClassIntrospectionRequest.deserialize(
-      Deserializer deserializer, this.requestKind, int serializationZoneId)
-      : classDeclaration = RemoteInstance.deserialize(deserializer),
-        classIntrospector = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  @override
-  void serialize(Serializer serializer) {
-    serializer.addNum(requestKind.index);
-    classDeclaration.serialize(serializer);
-    classIntrospector.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// A request to get a [TypeDeclaration] for a [StaticType].
-class DeclarationOfRequest extends Request {
-  final IdentifierImpl identifier;
-  final RemoteInstanceImpl typeDeclarationResolver;
-
-  DeclarationOfRequest(this.identifier, this.typeDeclarationResolver,
-      {required int serializationZoneId})
-      : super(serializationZoneId: serializationZoneId);
-
-  /// When deserializing we have already consumed the message type, so we don't
-  /// consume it again.
-  DeclarationOfRequest.deserialize(
-      Deserializer deserializer, int serializationZoneId)
-      : identifier = RemoteInstance.deserialize(deserializer),
-        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
-        super.deserialize(deserializer, serializationZoneId);
-
-  @override
-  void serialize(Serializer serializer) {
-    serializer.addNum(MessageType.declarationOfRequest.index);
-    identifier.serialize(serializer);
-    typeDeclarationResolver.serialize(serializer);
-    super.serialize(serializer);
-  }
-}
-
-/// Client side implementation of a [TypeResolver], which creates a
-/// [ResolveTypeRequest] and passes it to a given [sendRequest] function which
-/// can return the [Response].
-class ClientTypeResolver implements TypeResolver {
-  /// The actual remote instance of this type resolver.
-  final RemoteInstanceImpl remoteInstance;
-
-  /// The ID of the zone in which to find the original type resolver.
-  final int serializationZoneId;
-
-  /// A function that can send a request and return a response using an
-  /// arbitrary communication channel.
-  final Future<Response> Function(Request request) _sendRequest;
-
-  ClientTypeResolver(this._sendRequest,
-      {required this.remoteInstance, required this.serializationZoneId});
-
-  @override
-  Future<StaticType> instantiateType(TypeAnnotationImpl typeAnnotation) async {
-    InstantiateTypeRequest request = new InstantiateTypeRequest(
-        typeAnnotation, remoteInstance,
-        serializationZoneId: serializationZoneId);
-    RemoteInstanceImpl remoteType =
-        _handleResponse(await _sendRequest(request));
-    switch (remoteType.kind) {
-      case RemoteInstanceKind.namedStaticType:
-        return new ClientNamedStaticTypeImpl(_sendRequest,
-            remoteInstance: remoteType,
-            serializationZoneId: serializationZoneId);
-      case RemoteInstanceKind.staticType:
-        return new ClientStaticTypeImpl(_sendRequest,
-            remoteInstance: remoteType,
-            serializationZoneId: serializationZoneId);
-      default:
-        throw new StateError(
-            'Expected either a StaticType or NamedStaticType but got '
-            '${remoteType.kind}');
-    }
-  }
-
-  @override
-  Future<StaticType> instantiateCode(ExpressionCode code) {
-    // TODO: implement instantiateCode
-    throw new UnimplementedError();
-  }
-}
-
-class ClientStaticTypeImpl implements StaticType {
-  /// The actual remote instance of this static type.
-  final RemoteInstanceImpl remoteInstance;
-
-  final int serializationZoneId;
-
-  /// A function that can send a request and return a response using an
-  /// arbitrary communication channel.
-  final Future<Response> Function(Request request) sendRequest;
-
-  ClientStaticTypeImpl(this.sendRequest,
-      {required this.remoteInstance, required this.serializationZoneId});
-
-  @override
-  Future<bool> isExactly(ClientStaticTypeImpl other) async {
-    IsExactlyTypeRequest request = new IsExactlyTypeRequest(
-        this.remoteInstance, other.remoteInstance,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
-  }
-
-  @override
-  Future<bool> isSubtypeOf(ClientStaticTypeImpl other) async {
-    IsSubtypeOfRequest request = new IsSubtypeOfRequest(
-        remoteInstance, other.remoteInstance,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
-  }
-}
-
-/// Named variant of the [ClientStaticTypeImpl].
-class ClientNamedStaticTypeImpl extends ClientStaticTypeImpl
-    implements NamedStaticType {
-  ClientNamedStaticTypeImpl(
-      Future<Response> Function(Request request) sendRequest,
-      {required RemoteInstanceImpl remoteInstance,
-      required int serializationZoneId})
-      : super(sendRequest,
-            remoteInstance: remoteInstance,
-            serializationZoneId: serializationZoneId);
-}
-
-/// Client side implementation of the [ClientClassIntrospector], converts all
-/// invocations into remote RPC calls.
-class ClientClassIntrospector implements ClassIntrospector {
-  /// The actual remote instance of this class introspector.
-  final RemoteInstanceImpl remoteInstance;
-
-  /// The ID of the zone in which to find the original type resolver.
-  final int serializationZoneId;
-
-  /// A function that can send a request and return a response using an
-  /// arbitrary communication channel.
-  final Future<Response> Function(Request request) sendRequest;
-
-  ClientClassIntrospector(this.sendRequest,
-      {required this.remoteInstance, required this.serializationZoneId});
-
-  @override
-  Future<List<ConstructorDeclaration>> constructorsOf(
-      ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.constructorsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
-  }
-
-  @override
-  Future<List<FieldDeclaration>> fieldsOf(ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.fieldsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
-  }
-
-  @override
-  Future<List<ClassDeclaration>> interfacesOf(
-      ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.interfacesOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
-  }
-
-  @override
-  Future<List<MethodDeclaration>> methodsOf(ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.methodsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
-  }
-
-  @override
-  Future<List<ClassDeclaration>> mixinsOf(ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.mixinsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
-  }
-
-  @override
-  Future<ClassDeclaration?> superclassOf(ClassDeclarationImpl clazz) async {
-    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
-        clazz, remoteInstance, MessageType.superclassOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<ClassDeclaration?>(await sendRequest(request));
-  }
-}
-
-/// Client side implementation of a [TypeDeclarationResolver], converts all
-/// invocations into remote procedure calls.
-class ClientTypeDeclarationResolver implements TypeDeclarationResolver {
-  /// The actual remote instance of this type resolver.
-  final RemoteInstanceImpl remoteInstance;
-
-  /// The ID of the zone in which to find the original type resolver.
-  final int serializationZoneId;
-
-  /// A function that can send a request and return a response using an
-  /// arbitrary communication channel.
-  final Future<Response> Function(Request request) sendRequest;
-
-  ClientTypeDeclarationResolver(this.sendRequest,
-      {required this.remoteInstance, required this.serializationZoneId});
-
-  @override
-  Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) async {
-    DeclarationOfRequest request = new DeclarationOfRequest(
-        identifier, remoteInstance,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<TypeDeclaration>(await sendRequest(request));
-  }
-}
-
-/// An exception that occurred remotely, the exception object and stack trace
-/// are serialized as [String]s and both included in the [toString] output.
-class RemoteException implements Exception {
-  final String error;
-  final String? stackTrace;
-
-  RemoteException(this.error, [this.stackTrace]);
-
-  String toString() =>
-      'RemoteException: $error${stackTrace == null ? '' : '\n\n$stackTrace'}';
-}
-
-/// Either returns the actual response from [response], casted to [T], or throws
-/// a [RemoteException] with the given error and stack trace.
-T _handleResponse<T>(Response response) {
-  if (response.responseType == MessageType.error) {
-    throw new RemoteException(response.error!.toString(), response.stackTrace);
-  }
-  return response.response as T;
-}
-
-enum MessageType {
-  boolean,
-  constructorsOfRequest,
-  declarationOfRequest,
-  declarationList,
-  fieldsOfRequest,
-  interfacesOfRequest,
-  methodsOfRequest,
-  mixinsOfRequest,
-  superclassOfRequest,
-  error,
-  executeDeclarationsPhaseRequest,
-  executeDefinitionsPhaseRequest,
-  executeTypesPhaseRequest,
-  instantiateMacroRequest,
-  instantiateTypeRequest,
-  isExactlyTypeRequest,
-  isSubtypeOfRequest,
-  loadMacroRequest,
-  remoteInstance,
-  macroClassIdentifier,
-  macroInstanceIdentifier,
-  macroExecutionResult,
-  namedStaticType,
-  response,
-  staticType,
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
deleted file mode 100644
index 7ba94f8..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
+++ /dev/null
@@ -1,113 +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:async';
-
-import 'package:meta/meta.dart';
-
-import 'serialization.dart';
-import 'serialization_extensions.dart';
-
-/// The key used to store the remote instance cache in the current serialization
-/// zone (in server mode only).
-const Symbol remoteInstanceZoneKey = #remoteInstanceCache;
-
-/// On the server side we keep track of remote instances by their ID.
-///
-/// These are a part of the current serialization zone, which all serialization
-/// and deserialization must be done in.
-///
-/// This means the cache lifetime is that of the serialization zone it is run
-/// in.
-Map<int, RemoteInstance> get _remoteInstanceCache =>
-    Zone.current[remoteInstanceZoneKey];
-
-/// Base class for types that need to be able to be traced back to a specific
-/// instance on the server side.
-abstract class RemoteInstance implements Serializable {
-  /// The unique ID for this instance.
-  final int id;
-
-  /// The type of instance being encoded.
-  RemoteInstanceKind get kind;
-
-  /// Static, incrementing ids.
-  static int _nextId = 0;
-
-  /// Gets the next unique identifier.
-  static int get uniqueId => _nextId++;
-
-  /// On the client side [id]s are given and you should reconstruct objects with
-  /// the given ID. On the server side ids should be created using
-  /// [RemoteInstance.uniqueId].
-  RemoteInstance(this.id);
-
-  /// Retrieves a cached instance by ID.
-  static T cached<T>(int id) => _remoteInstanceCache[id] as T;
-
-  /// Deserializes an instance based on the current [serializationMode].
-  static T deserialize<T>(Deserializer deserializer) =>
-      (deserializer..moveNext()).expectRemoteInstance();
-
-  /// This method should be overridden by all subclasses, which should on their
-  /// first line call this super function.
-  ///
-  /// They should then return immediately if [serializationMode] is
-  /// [SerializationMode.client], so that only an ID is sent.
-  @mustCallSuper
-  void serialize(Serializer serializer) {
-    serializer.addNum(id);
-    switch (serializationMode) {
-      case SerializationMode.client:
-        // We only send the ID from the client side.
-        return;
-      case SerializationMode.server:
-        serializer.addNum(kind.index);
-        _remoteInstanceCache[id] = this;
-        return;
-    }
-  }
-
-  @override
-  bool operator ==(Object other) => other is RemoteInstance && id == other.id;
-}
-
-/// A remote instance which is just a pointer to some server side instance of
-/// a generic object.
-///
-/// The wrapped object is not serialized.
-class RemoteInstanceImpl extends RemoteInstance {
-  /// Always null on the client side, has an actual instance on the server side.
-  final Object? instance;
-
-  @override
-  final RemoteInstanceKind kind;
-
-  RemoteInstanceImpl({
-    required int id,
-    this.instance,
-    required this.kind,
-  }) : super(id);
-}
-
-// The kinds of instances.
-enum RemoteInstanceKind {
-  classDeclaration,
-  classIntrospector,
-  constructorDeclaration,
-  fieldDeclaration,
-  functionDeclaration,
-  functionTypeAnnotation,
-  identifier,
-  namedStaticType,
-  methodDeclaration,
-  namedTypeAnnotation,
-  parameterDeclaration,
-  staticType,
-  typeAliasDeclaration,
-  typeParameterDeclaration,
-  typeResolver,
-  typeDeclarationResolver,
-  variableDeclaration,
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
deleted file mode 100644
index eb4e5ae..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
+++ /dev/null
@@ -1,257 +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 '../executor.dart';
-import '../api.dart';
-import 'serialization.dart';
-import 'serialization_extensions.dart';
-
-/// Implementation of [MacroClassIdentifier].
-class MacroClassIdentifierImpl implements MacroClassIdentifier {
-  final String id;
-
-  MacroClassIdentifierImpl(Uri library, String name) : id = '$library#$name';
-
-  MacroClassIdentifierImpl.deserialize(Deserializer deserializer)
-      : id = (deserializer..moveNext()).expectString();
-
-  void serialize(Serializer serializer) => serializer.addString(id);
-
-  operator ==(other) => other is MacroClassIdentifierImpl && id == other.id;
-
-  int get hashCode => id.hashCode;
-}
-
-/// Implementation of [MacroInstanceIdentifier].
-class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
-  /// A single int where each bit indicates whether a specific macro interface
-  /// is implemented by this macro.
-  final int _interfaces;
-
-  static int _next = 0;
-
-  final int id;
-
-  MacroInstanceIdentifierImpl._(this._interfaces) : id = _next++;
-
-  factory MacroInstanceIdentifierImpl(Macro macro) {
-    // Build up the interfaces value, there is a bit for each declaration/phase
-    // combination (as there is an interface for each).
-    int interfaces = 0;
-    for (DeclarationKind declarationKind in DeclarationKind.values) {
-      for (Phase phase in Phase.values) {
-        int interfaceMask = _interfaceMask(declarationKind, phase);
-        switch (declarationKind) {
-          case DeclarationKind.clazz:
-            switch (phase) {
-              case Phase.types:
-                if (macro is ClassTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is ClassDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is ClassDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-          case DeclarationKind.constructor:
-            switch (phase) {
-              case Phase.types:
-                if (macro is ConstructorTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is ConstructorDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is ConstructorDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-          case DeclarationKind.field:
-            switch (phase) {
-              case Phase.types:
-                if (macro is FieldTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is FieldDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is FieldDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-          case DeclarationKind.function:
-            switch (phase) {
-              case Phase.types:
-                if (macro is FunctionTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is FunctionDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is FunctionDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-          case DeclarationKind.method:
-            switch (phase) {
-              case Phase.types:
-                if (macro is MethodTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is MethodDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is MethodDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-          case DeclarationKind.variable:
-            switch (phase) {
-              case Phase.types:
-                if (macro is VariableTypesMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.declarations:
-                if (macro is VariableDeclarationsMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-              case Phase.definitions:
-                if (macro is VariableDefinitionMacro) {
-                  interfaces |= interfaceMask;
-                }
-                break;
-            }
-            break;
-        }
-      }
-    }
-
-    return new MacroInstanceIdentifierImpl._(interfaces);
-  }
-
-  MacroInstanceIdentifierImpl.deserialize(Deserializer deserializer)
-      : id = (deserializer..moveNext()).expectNum(),
-        _interfaces = (deserializer..moveNext()).expectNum();
-
-  void serialize(Serializer serializer) => serializer
-    ..addNum(id)
-    ..addNum(_interfaces);
-
-  operator ==(other) => other is MacroInstanceIdentifierImpl && id == other.id;
-
-  int get hashCode => id;
-
-  @override
-  bool shouldExecute(DeclarationKind declarationKind, Phase phase) {
-    int mask = _interfaceMask(declarationKind, phase);
-    if (declarationKind == DeclarationKind.method) {
-      // Apply function macros to methods.
-      mask |= _interfaceMask(DeclarationKind.function, phase);
-    } else if (declarationKind == DeclarationKind.field) {
-      // Apply variable macros to fields.
-      mask |= _interfaceMask(DeclarationKind.variable, phase);
-    }
-    return _interfaces & mask != 0x0;
-  }
-
-  @override
-  bool supportsDeclarationKind(DeclarationKind declarationKind) {
-    for (Phase phase in Phase.values) {
-      if (shouldExecute(declarationKind, phase)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// The mask for a particular interface, which is a combination of a kind of
-  /// declaration and a phase.
-  static int _interfaceMask(DeclarationKind declarationKind, Phase phase) =>
-      0x1 << (declarationKind.index * Phase.values.length) << phase.index;
-}
-
-/// Implementation of [MacroExecutionResult].
-class MacroExecutionResultImpl implements MacroExecutionResult {
-  @override
-  final List<DeclarationCode> augmentations;
-
-  @override
-  final List<DeclarationCode> imports;
-
-  MacroExecutionResultImpl({
-    required this.augmentations,
-    required this.imports,
-  });
-
-  factory MacroExecutionResultImpl.deserialize(Deserializer deserializer) {
-    deserializer.moveNext();
-    deserializer.expectList();
-    List<DeclarationCode> augmentations = [
-      for (bool hasNext = deserializer.moveNext();
-          hasNext;
-          hasNext = deserializer.moveNext())
-        deserializer.expectCode()
-    ];
-    deserializer.moveNext();
-    deserializer.expectList();
-    List<DeclarationCode> imports = [
-      for (bool hasNext = deserializer.moveNext();
-          hasNext;
-          hasNext = deserializer.moveNext())
-        deserializer.expectCode()
-    ];
-
-    return new MacroExecutionResultImpl(
-      augmentations: augmentations,
-      imports: imports,
-    );
-  }
-
-  void serialize(Serializer serializer) {
-    serializer.startList();
-    for (DeclarationCode augmentation in augmentations) {
-      augmentation.serialize(serializer);
-    }
-    serializer.endList();
-    serializer.startList();
-    for (DeclarationCode import in imports) {
-      import.serialize(serializer);
-    }
-    serializer.endList();
-  }
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization.dart
deleted file mode 100644
index 89bbf59..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization.dart
+++ /dev/null
@@ -1,238 +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 'dart:async';
-
-import 'remote_instance.dart';
-
-/// All serialization must be done in a serialization Zone, which tells it
-/// whether we are the client or server.
-///
-/// In [SerializationMode.server], sets up a remote instance cache to use when
-/// deserializing remote instances back to their original instance.
-T withSerializationMode<T>(SerializationMode mode, T Function() fn) =>
-    runZoned(fn, zoneValues: {
-      #serializationMode: mode,
-      if (mode == SerializationMode.server)
-        remoteInstanceZoneKey: <int, RemoteInstance>{}
-    });
-
-/// Serializable interface
-abstract class Serializable {
-  /// Serializes this object using [serializer].
-  void serialize(Serializer serializer);
-}
-
-/// A push based object serialization interface.
-abstract class Serializer {
-  /// Serializes a [String].
-  void addString(String value);
-
-  /// Serializes a nullable [String].
-  void addNullableString(String? value);
-
-  /// Serializes a [num].
-  void addNum(num value);
-
-  /// Serializes a nullable [num].
-  void addNullableNum(num? value);
-
-  /// Serializes a [bool].
-  void addBool(bool value);
-
-  /// Serializes a nullable [bool].
-  void addNullableBool(bool? value);
-
-  /// Serializes a `null` literal.
-  void addNull();
-
-  /// Used to signal the start of an arbitrary length list of items.
-  void startList();
-
-  /// Used to signal the end of an arbitrary length list of items.
-  void endList();
-}
-
-/// A pull based object deserialization interface.
-///
-/// You must call [moveNext] before reading any items, and in order to advance
-/// to the next item.
-abstract class Deserializer {
-  /// Checks if the current value is a null, returns `true` if so and `false`
-  /// otherwise.
-  bool checkNull();
-
-  /// Reads the current value as a non-nullable [String].
-  bool expectBool();
-
-  /// Reads the current value as a nullable [bool].
-  bool? expectNullableBool();
-
-  /// Reads the current value as a non-nullable [String].
-  T expectNum<T extends num>();
-
-  /// Reads the current value as a nullable [num].
-  num? expectNullableNum();
-
-  /// Reads the current value as a non-nullable [String].
-  String expectString();
-
-  /// Reads the current value as a nullable [String].
-  String? expectNullableString();
-
-  /// Asserts that the current item is the start of a list.
-  ///
-  /// An example for how to read from a list is as follows:
-  ///
-  /// var json = JsonReader.fromString(source);
-  /// I know it's a list of strings.
-  ///
-  /// ```
-  ///   var result = <String>[];
-  ///   deserializer.moveNext();
-  ///   deserializer.expectList();
-  ///   while (json.moveNext()) {
-  ///     result.add(json.expectString());
-  ///   }
-  ///   // Can now read later items, but need to call `moveNext` again to move
-  ///   // past the list.
-  ///   deserializer.moveNext();
-  ///   deserializer.expectBool();
-  /// ```
-  void expectList();
-
-  /// Moves to the next item, returns `false` if there are no more items to
-  /// read.
-  ///
-  /// If inside of a list, this returns `false` when the end of the list is
-  /// reached, and moves back to the parent, but does not advance it, so another
-  /// call to `moveNext` is needed. See example in the [expectList] docs.
-  bool moveNext();
-}
-
-class JsonSerializer implements Serializer {
-  /// The full result.
-  final _result = <Object?>[];
-
-  /// A path to the current list we are modifying.
-  late List<List<Object?>> _path = [_result];
-
-  /// Returns the result as an unmodifiable [Iterable].
-  ///
-  /// Asserts that all [List] entries have not been closed with [endList].
-  Iterable<Object?> get result {
-    assert(_path.length == 1);
-    return _result;
-  }
-
-  @override
-  void addBool(bool value) => _path.last.add(value);
-  @override
-  void addNullableBool(bool? value) => _path.last.add(value);
-
-  @override
-  void addNum(num value) => _path.last.add(value);
-  @override
-  void addNullableNum(num? value) => _path.last.add(value);
-
-  @override
-  void addString(String value) => _path.last.add(value);
-  @override
-  void addNullableString(String? value) => _path.last.add(value);
-
-  @override
-  void addNull() => _path.last.add(null);
-
-  @override
-  void startList() {
-    List<Object?> sublist = [];
-    _path.last.add(sublist);
-    _path.add(sublist);
-  }
-
-  @override
-  void endList() {
-    _path.removeLast();
-  }
-}
-
-class JsonDeserializer implements Deserializer {
-  /// The root source list to read from.
-  final Iterable<Object?> _source;
-
-  /// The path to the current iterator we are reading from.
-  late List<Iterator<Object?>> _path = [];
-
-  /// Whether we have received our first [moveNext] call.
-  bool _initialized = false;
-
-  /// Initialize this deserializer from `_source`.
-  JsonDeserializer(this._source);
-
-  @override
-  bool checkNull() => _expectValue<Object?>() == null;
-
-  @override
-  void expectList() => _path.add(_expectValue<Iterable<Object?>>().iterator);
-
-  @override
-  bool expectBool() => _expectValue();
-  @override
-  bool? expectNullableBool() => _expectValue();
-
-  @override
-  T expectNum<T extends num>() => _expectValue();
-  @override
-  num? expectNullableNum() => _expectValue();
-
-  @override
-  String expectString() => _expectValue();
-  @override
-  String? expectNullableString() => _expectValue();
-
-  /// Reads the current value and casts it to [T].
-  T _expectValue<T>() {
-    if (!_initialized) {
-      throw new StateError(
-          'You must call `moveNext()` before reading any values.');
-    }
-    return _path.last.current as T;
-  }
-
-  @override
-  bool moveNext() {
-    if (!_initialized) {
-      _path.add(_source.iterator);
-      _initialized = true;
-    }
-
-    // Move the current iterable, if its at the end of its items remove it from
-    // the current path and return false.
-    if (!_path.last.moveNext()) {
-      _path.removeLast();
-      return false;
-    }
-
-    return true;
-  }
-}
-
-/// Must be set using `withSerializationMode` before doing any serialization or
-/// deserialization.
-SerializationMode get serializationMode {
-  SerializationMode? mode =
-      Zone.current[#serializationMode] as SerializationMode?;
-  if (mode == null) {
-    throw new StateError('No SerializationMode set, you must do all '
-        'serialization inside a call to `withSerializationMode`.');
-  }
-  return mode;
-}
-
-/// Some objects are serialized differently on the client side versus the server
-/// side. This indicates the different modes.
-enum SerializationMode {
-  server,
-  client,
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
deleted file mode 100644
index ff8a0b2..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
+++ /dev/null
@@ -1,299 +0,0 @@
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
-
-import 'remote_instance.dart';
-import 'serialization.dart';
-import '../api.dart';
-
-extension DeserializerExtensions on Deserializer {
-  T expectRemoteInstance<T>() {
-    int id = expectNum();
-    switch (serializationMode) {
-      case SerializationMode.client:
-        moveNext();
-        RemoteInstanceKind kind = RemoteInstanceKind.values[expectNum()];
-        switch (kind) {
-          case RemoteInstanceKind.classIntrospector:
-          case RemoteInstanceKind.namedStaticType:
-          case RemoteInstanceKind.staticType:
-          case RemoteInstanceKind.typeDeclarationResolver:
-          case RemoteInstanceKind.typeResolver:
-            // These are simple wrappers, just pass in the kind
-            return new RemoteInstanceImpl(id: id, kind: kind) as T;
-          case RemoteInstanceKind.classDeclaration:
-            moveNext();
-            return _expectClassDeclaration(id) as T;
-          case RemoteInstanceKind.constructorDeclaration:
-            moveNext();
-            return _expectConstructorDeclaration(id) as T;
-          case RemoteInstanceKind.fieldDeclaration:
-            moveNext();
-            return _expectFieldDeclaration(id) as T;
-          case RemoteInstanceKind.functionDeclaration:
-            moveNext();
-            return _expectFunctionDeclaration(id) as T;
-          case RemoteInstanceKind.functionTypeAnnotation:
-            moveNext();
-            return _expectFunctionTypeAnnotation(id) as T;
-          case RemoteInstanceKind.identifier:
-            moveNext();
-            return _expectIdentifier(id) as T;
-          case RemoteInstanceKind.methodDeclaration:
-            moveNext();
-            return _expectMethodDeclaration(id) as T;
-          case RemoteInstanceKind.namedTypeAnnotation:
-            moveNext();
-            return _expectNamedTypeAnnotation(id) as T;
-          case RemoteInstanceKind.parameterDeclaration:
-            moveNext();
-            return _expectParameterDeclaration(id) as T;
-          case RemoteInstanceKind.typeAliasDeclaration:
-            moveNext();
-            return _expectTypeAliasDeclaration(id) as T;
-          case RemoteInstanceKind.typeParameterDeclaration:
-            moveNext();
-            return _expectTypeParameterDeclaration(id) as T;
-          case RemoteInstanceKind.variableDeclaration:
-            moveNext();
-            return _expectVariableDeclaration(id) as T;
-        }
-      case SerializationMode.server:
-        return RemoteInstance.cached(id) as T;
-    }
-  }
-
-  /// Helper method to read a list of [RemoteInstance]s.
-  List<T> _expectRemoteInstanceList<T extends RemoteInstance>() {
-    expectList();
-    return [
-      for (bool hasNext = moveNext(); hasNext; hasNext = moveNext())
-        expectRemoteInstance(),
-    ];
-  }
-
-  NamedTypeAnnotation _expectNamedTypeAnnotation(int id) =>
-      new NamedTypeAnnotationImpl(
-        id: id,
-        isNullable: expectBool(),
-        identifier: RemoteInstance.deserialize(this),
-        typeArguments: (this..moveNext())._expectRemoteInstanceList(),
-      );
-
-  FunctionTypeAnnotation _expectFunctionTypeAnnotation(int id) =>
-      new FunctionTypeAnnotationImpl(
-        id: id,
-        isNullable: expectBool(),
-        returnType: RemoteInstance.deserialize(this),
-        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
-        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-      );
-
-  Identifier _expectIdentifier(int id) => new IdentifierImpl(
-        id: id,
-        name: expectString(),
-      );
-
-  ParameterDeclaration _expectParameterDeclaration(int id) =>
-      new ParameterDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        defaultValue: (this..moveNext()).checkNull() ? null : expectCode(),
-        isNamed: (this..moveNext()).expectBool(),
-        isRequired: (this..moveNext()).expectBool(),
-        type: RemoteInstance.deserialize(this),
-      );
-
-  TypeParameterDeclaration _expectTypeParameterDeclaration(int id) =>
-      new TypeParameterDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        bounds: (this..moveNext()).checkNull() ? null : expectRemoteInstance(),
-      );
-
-  FunctionDeclaration _expectFunctionDeclaration(int id) =>
-      new FunctionDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        isAbstract: (this..moveNext()).expectBool(),
-        isExternal: (this..moveNext()).expectBool(),
-        isGetter: (this..moveNext()).expectBool(),
-        isSetter: (this..moveNext()).expectBool(),
-        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
-        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
-        returnType: RemoteInstance.deserialize(this),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-      );
-
-  MethodDeclaration _expectMethodDeclaration(int id) =>
-      new MethodDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        isAbstract: (this..moveNext()).expectBool(),
-        isExternal: (this..moveNext()).expectBool(),
-        isGetter: (this..moveNext()).expectBool(),
-        isSetter: (this..moveNext()).expectBool(),
-        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
-        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
-        returnType: RemoteInstance.deserialize(this),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-        definingClass: RemoteInstance.deserialize(this),
-      );
-
-  ConstructorDeclaration _expectConstructorDeclaration(int id) =>
-      new ConstructorDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        isAbstract: (this..moveNext()).expectBool(),
-        isExternal: (this..moveNext()).expectBool(),
-        isGetter: (this..moveNext()).expectBool(),
-        isSetter: (this..moveNext()).expectBool(),
-        namedParameters: (this..moveNext())._expectRemoteInstanceList(),
-        positionalParameters: (this..moveNext())._expectRemoteInstanceList(),
-        returnType: RemoteInstance.deserialize(this),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-        definingClass: RemoteInstance.deserialize(this),
-        isFactory: (this..moveNext()).expectBool(),
-      );
-
-  VariableDeclaration _expectVariableDeclaration(int id) =>
-      new VariableDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        initializer: (this..moveNext()).expectNullableCode(),
-        isExternal: (this..moveNext()).expectBool(),
-        isFinal: (this..moveNext()).expectBool(),
-        isLate: (this..moveNext()).expectBool(),
-        type: RemoteInstance.deserialize(this),
-      );
-
-  FieldDeclaration _expectFieldDeclaration(int id) => new FieldDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        initializer: (this..moveNext()).expectNullableCode(),
-        isExternal: (this..moveNext()).expectBool(),
-        isFinal: (this..moveNext()).expectBool(),
-        isLate: (this..moveNext()).expectBool(),
-        type: RemoteInstance.deserialize(this),
-        definingClass: RemoteInstance.deserialize(this),
-      );
-
-  ClassDeclaration _expectClassDeclaration(int id) => new ClassDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-        interfaces: (this..moveNext())._expectRemoteInstanceList(),
-        isAbstract: (this..moveNext()).expectBool(),
-        isExternal: (this..moveNext()).expectBool(),
-        mixins: (this..moveNext())._expectRemoteInstanceList(),
-        superclass:
-            (this..moveNext()).checkNull() ? null : expectRemoteInstance(),
-      );
-
-  TypeAliasDeclaration _expectTypeAliasDeclaration(int id) =>
-      new TypeAliasDeclarationImpl(
-        id: id,
-        identifier: expectRemoteInstance(),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
-        aliasedType: RemoteInstance.deserialize(this),
-      );
-
-  T expectCode<T extends Code>() {
-    CodeKind kind = CodeKind.values[expectNum()];
-    moveNext();
-    expectList();
-    List<Object> parts = [];
-    while (moveNext()) {
-      CodePartKind partKind = CodePartKind.values[expectNum()];
-      moveNext();
-      switch (partKind) {
-        case CodePartKind.code:
-          parts.add(expectCode());
-          break;
-        case CodePartKind.string:
-          parts.add(expectString());
-          break;
-        case CodePartKind.identifier:
-          parts.add(expectRemoteInstance());
-          break;
-      }
-    }
-
-    switch (kind) {
-      case CodeKind.raw:
-        return new Code.fromParts(parts) as T;
-      case CodeKind.declaration:
-        return new DeclarationCode.fromParts(parts) as T;
-      case CodeKind.element:
-        return new ElementCode.fromParts(parts) as T;
-      case CodeKind.expression:
-        return new ExpressionCode.fromParts(parts) as T;
-      case CodeKind.functionBody:
-        return new FunctionBodyCode.fromParts(parts) as T;
-      case CodeKind.namedArgument:
-        return new NamedArgumentCode.fromParts(parts) as T;
-      case CodeKind.parameter:
-        return new ParameterCode.fromParts(parts) as T;
-      case CodeKind.statement:
-        return new StatementCode.fromParts(parts) as T;
-    }
-  }
-
-  T? expectNullableCode<T extends Code>() {
-    if (checkNull()) return null;
-    return expectCode();
-  }
-}
-
-extension SerializeNullable on Serializable? {
-  /// Either serializes a `null` literal or the object.
-  void serializeNullable(Serializer serializer) {
-    Serializable? self = this;
-    if (self == null) {
-      serializer.addNull();
-    } else {
-      self.serialize(serializer);
-    }
-  }
-}
-
-extension SerializeNullableCode on Code? {
-  /// Either serializes a `null` literal or the code object.
-  void serializeNullable(Serializer serializer) {
-    Code? self = this;
-    if (self == null) {
-      serializer.addNull();
-    } else {
-      self.serialize(serializer);
-    }
-  }
-}
-
-extension SerializeCode on Code {
-  void serialize(Serializer serializer) {
-    serializer
-      ..addNum(kind.index)
-      ..startList();
-    for (Object part in parts) {
-      if (part is String) {
-        serializer
-          ..addNum(CodePartKind.string.index)
-          ..addString(part);
-      } else if (part is Code) {
-        serializer.addNum(CodePartKind.code.index);
-        part.serialize(serializer);
-      } else if (part is IdentifierImpl) {
-        serializer.addNum(CodePartKind.identifier.index);
-        part.serialize(serializer);
-      } else {
-        throw new StateError('Unrecognized code part $part');
-      }
-    }
-    serializer.endList();
-  }
-}
-
-enum CodePartKind {
-  string,
-  code,
-  identifier,
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart
deleted file mode 100644
index 9bfd0a7..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart
+++ /dev/null
@@ -1,18 +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 '../executor.dart';
-
-/// The only public api exposed by this library, returns a [_FakeMacroExecutor].
-Future<MacroExecutor> start() async => new _FakeMacroExecutor();
-
-/// A [MacroExecutor] implementation which throws an [UnsupportedError] in all
-/// methods.
-class _FakeMacroExecutor implements MacroExecutor {
-  @override
-  dynamic noSuchMethod(Invocation invocation) {
-    throw new UnsupportedError(
-        'Macro expansion is not supported on this platform.');
-  }
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
deleted file mode 100644
index 797ffb8..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
+++ /dev/null
@@ -1,169 +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 'dart:async';
-import 'dart:isolate';
-import 'dart:mirrors';
-
-import 'isolate_mirrors_impl.dart';
-import '../executor_shared/introspection_impls.dart';
-import '../executor_shared/protocol.dart';
-import '../executor_shared/remote_instance.dart';
-import '../executor.dart';
-import '../api.dart';
-
-/// Returns an instance of [_IsolateMirrorMacroExecutor].
-///
-/// This is the only public api exposed by this library.
-Future<MacroExecutor> start() => _IsolateMirrorMacroExecutor.start();
-
-/// A [MacroExecutor] implementation which relies on [IsolateMirror.loadUri]
-/// in order to load macros libraries.
-///
-/// All actual work happens in a separate [Isolate], and this class serves as
-/// a bridge between that isolate and the language frontends.
-class _IsolateMirrorMacroExecutor implements MacroExecutor {
-  /// The actual isolate doing macro loading and execution.
-  final Isolate _macroIsolate;
-
-  /// The channel used to send requests to the [_macroIsolate].
-  final SendPort _sendPort;
-
-  /// The stream of responses from the [_macroIsolate].
-  final Stream<Response> _responseStream;
-
-  /// A map of response completers by request id.
-  final _responseCompleters = <int, Completer<Response>>{};
-
-  /// A function that should be invoked when shutting down this executor
-  /// to perform any necessary cleanup.
-  final void Function() _onClose;
-
-  _IsolateMirrorMacroExecutor._(
-      this._macroIsolate, this._sendPort, this._responseStream, this._onClose) {
-    _responseStream.listen((event) {
-      Completer<Response>? completer =
-          _responseCompleters.remove(event.requestId);
-      if (completer == null) {
-        throw new StateError(
-            'Got a response for an unrecognized request id ${event.requestId}');
-      }
-      completer.complete(event);
-    });
-  }
-
-  /// Initialize an [IsolateMirrorMacroExecutor] and return it once ready.
-  ///
-  /// Spawns the macro isolate and sets up a communication channel.
-  static Future<MacroExecutor> start() async {
-    ReceivePort receivePort = new ReceivePort();
-    Completer<SendPort> sendPortCompleter = new Completer<SendPort>();
-    StreamController<Response> responseStreamController =
-        new StreamController<Response>(sync: true);
-    receivePort.listen((message) {
-      if (!sendPortCompleter.isCompleted) {
-        sendPortCompleter.complete(message as SendPort);
-      } else {
-        responseStreamController.add(message as Response);
-      }
-    }).onDone(responseStreamController.close);
-    Isolate macroIsolate = await Isolate.spawn(spawn, receivePort.sendPort);
-
-    return new _IsolateMirrorMacroExecutor._(
-        macroIsolate,
-        await sendPortCompleter.future,
-        responseStreamController.stream,
-        receivePort.close);
-  }
-
-  @override
-  Future<String> buildAugmentationLibrary(
-      Iterable<MacroExecutionResult> macroResults) {
-    // TODO: implement buildAugmentationLibrary
-    throw new UnimplementedError();
-  }
-
-  @override
-  void close() {
-    _onClose();
-    _macroIsolate.kill();
-  }
-
-  @override
-  Future<MacroExecutionResult> executeDeclarationsPhase(
-      MacroInstanceIdentifier macro,
-      Declaration declaration,
-      TypeResolver typeResolver,
-      ClassIntrospector classIntrospector) {
-    // TODO: implement executeDeclarationsPhase
-    throw new UnimplementedError();
-  }
-
-  @override
-  Future<MacroExecutionResult> executeDefinitionsPhase(
-          MacroInstanceIdentifier macro,
-          DeclarationImpl declaration,
-          TypeResolver typeResolver,
-          ClassIntrospector classIntrospector,
-          TypeDeclarationResolver typeDeclarationResolver) =>
-      _sendRequest(new ExecuteDefinitionsPhaseRequest(
-          macro,
-          declaration,
-          new RemoteInstanceImpl(
-              instance: typeResolver,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.typeResolver),
-          new RemoteInstanceImpl(
-              instance: classIntrospector,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.classIntrospector),
-          new RemoteInstanceImpl(
-              instance: typeDeclarationResolver,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.typeDeclarationResolver),
-          // Serialization zones are not necessary in this executor.
-          serializationZoneId: -1));
-
-  @override
-  Future<MacroExecutionResult> executeTypesPhase(
-      MacroInstanceIdentifier macro, Declaration declaration) {
-    // TODO: implement executeTypesPhase
-    throw new UnimplementedError();
-  }
-
-  @override
-  Future<MacroInstanceIdentifier> instantiateMacro(
-          MacroClassIdentifier macroClass,
-          String constructor,
-          Arguments arguments) =>
-      _sendRequest(
-          new InstantiateMacroRequest(macroClass, constructor, arguments,
-              // Serialization zones are not necessary in this executor.
-              serializationZoneId: -1));
-
-  @override
-  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
-      {Uri? precompiledKernelUri}) {
-    if (precompiledKernelUri != null) {
-      // TODO: Implement support?
-      throw new UnsupportedError(
-          'The IsolateMirrorsExecutor does not support precompiled dill files');
-    }
-    return _sendRequest(new LoadMacroRequest(library, name,
-        // Serialization zones are not necessary in this executor.
-        serializationZoneId: -1));
-  }
-
-  /// Sends a request and returns the response, casting it to the expected
-  /// type.
-  Future<T> _sendRequest<T>(Request request) async {
-    _sendPort.send(request);
-    Completer<Response> completer = new Completer<Response>();
-    _responseCompleters[request.id] = completer;
-    Response response = await completer.future;
-    T? result = response.response as T?;
-    if (result != null) return result;
-    throw response.error!;
-  }
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
deleted file mode 100644
index 4c435f6..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
+++ /dev/null
@@ -1,131 +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 'dart:async';
-import 'dart:isolate';
-import 'dart:mirrors';
-
-import '../executor_shared/builder_impls.dart';
-import '../executor_shared/introspection_impls.dart';
-import '../executor_shared/response_impls.dart';
-import '../executor_shared/protocol.dart';
-import '../api.dart';
-
-/// Spawns a new isolate for loading and executing macros.
-void spawn(SendPort sendPort) {
-  ReceivePort receivePort = new ReceivePort();
-  sendPort.send(receivePort.sendPort);
-  receivePort.listen((message) async {
-    Response response;
-    if (message is LoadMacroRequest) {
-      response = await _loadMacro(message);
-    } else if (message is InstantiateMacroRequest) {
-      response = await _instantiateMacro(message);
-    } else if (message is ExecuteDefinitionsPhaseRequest) {
-      response = await _executeDefinitionsPhase(message);
-    } else {
-      throw new StateError('Unrecognized event type $message');
-    }
-    sendPort.send(response);
-  });
-}
-
-/// Maps macro identifiers to class mirrors.
-final _macroClasses = <MacroClassIdentifierImpl, ClassMirror>{};
-
-/// Handles [LoadMacroRequest]s.
-Future<Response> _loadMacro(LoadMacroRequest request) async {
-  try {
-    MacroClassIdentifierImpl identifier =
-        new MacroClassIdentifierImpl(request.library, request.name);
-    if (_macroClasses.containsKey(identifier)) {
-      throw new UnsupportedError(
-          'Reloading macros is not supported by this implementation');
-    }
-    LibraryMirror libMirror =
-        await currentMirrorSystem().isolate.loadUri(request.library);
-    ClassMirror macroClass =
-        libMirror.declarations[new Symbol(request.name)] as ClassMirror;
-    _macroClasses[identifier] = macroClass;
-    return new Response(
-        response: identifier,
-        requestId: request.id,
-        responseType: MessageType.macroClassIdentifier);
-  } catch (e) {
-    return new Response(
-        error: e, requestId: request.id, responseType: MessageType.error);
-  }
-}
-
-/// Maps macro instance identifiers to instances.
-final _macroInstances = <MacroInstanceIdentifierImpl, Macro>{};
-
-/// Handles [InstantiateMacroRequest]s.
-Future<Response> _instantiateMacro(InstantiateMacroRequest request) async {
-  try {
-    ClassMirror? clazz = _macroClasses[request.macroClass];
-    if (clazz == null) {
-      throw new ArgumentError('Unrecognized macro class ${request.macroClass}');
-    }
-    Macro instance = clazz.newInstance(
-        new Symbol(request.constructorName), request.arguments.positional, {
-      for (MapEntry<String, Object?> entry in request.arguments.named.entries)
-        new Symbol(entry.key): entry.value,
-    }).reflectee as Macro;
-    MacroInstanceIdentifierImpl identifier =
-        new MacroInstanceIdentifierImpl(instance);
-    _macroInstances[identifier] = instance;
-    return new Response(
-        response: identifier,
-        requestId: request.id,
-        responseType: MessageType.macroInstanceIdentifier);
-  } catch (e) {
-    return new Response(
-        error: e, requestId: request.id, responseType: MessageType.error);
-  }
-}
-
-Future<Response> _executeDefinitionsPhase(
-    ExecuteDefinitionsPhaseRequest request) async {
-  try {
-    Macro? instance = _macroInstances[request.macro];
-    if (instance == null) {
-      throw new StateError('Unrecognized macro instance ${request.macro}\n'
-          'Known instances: $_macroInstances)');
-    }
-    DeclarationImpl declaration = request.declaration;
-    if (instance is FunctionDefinitionMacro &&
-        declaration is FunctionDeclarationImpl) {
-      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
-          declaration,
-          request.classIntrospector.instance as ClassIntrospector,
-          request.typeResolver.instance as TypeResolver,
-          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
-      await instance.buildDefinitionForFunction(declaration, builder);
-      return new Response(
-          response: builder.result,
-          requestId: request.id,
-          responseType: MessageType.macroExecutionResult);
-    } else if (instance is MethodDefinitionMacro &&
-        declaration is MethodDeclarationImpl) {
-      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
-          declaration,
-          request.classIntrospector.instance as ClassIntrospector,
-          request.typeResolver.instance as TypeResolver,
-          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
-      await instance.buildDefinitionForMethod(declaration, builder);
-      return new SerializableResponse(
-          responseType: MessageType.macroExecutionResult,
-          response: builder.result,
-          requestId: request.id,
-          serializationZoneId: request.serializationZoneId);
-    } else {
-      throw new UnsupportedError(
-          'Only Method and Function Definition Macros are supported currently');
-    }
-  } catch (e) {
-    return new Response(
-        error: e, requestId: request.id, responseType: MessageType.error);
-  }
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
deleted file mode 100644
index cfe6602..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ /dev/null
@@ -1,466 +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 'dart:async';
-import 'dart:isolate';
-
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
-
-import '../api.dart';
-import '../executor_shared/introspection_impls.dart';
-import '../executor_shared/protocol.dart';
-import '../executor_shared/response_impls.dart';
-import '../executor_shared/serialization.dart';
-import '../executor.dart';
-
-/// Returns an instance of [_IsolatedMacroExecutor].
-///
-/// This is the only public api exposed by this library.
-Future<MacroExecutor> start() async => new _IsolatedMacroExecutor();
-
-/// A [MacroExecutor] implementation which spawns a separate isolate for each
-/// macro that is loaded. Each of these is wrapped in its own
-/// [_SingleIsolatedMacroExecutor] which requests are delegated to.
-///
-/// This implementation requires precompiled kernel files when loading macros,
-/// (you must pass a `precompiledKernelUri` to [loadMacro]).
-///
-/// Spawned isolates are not ran in the same isolate group, so objects are
-/// serialized between isolates.
-class _IsolatedMacroExecutor implements MacroExecutor {
-  /// Individual executors indexed by [MacroClassIdentifier] or
-  /// [MacroInstanceIdentifier].
-  final _executors = <Object, _SingleIsolatedMacroExecutor>{};
-
-  @override
-  Future<String> buildAugmentationLibrary(
-      Iterable<MacroExecutionResult> macroResults) {
-    // TODO: implement buildAugmentationLibrary
-    throw new UnimplementedError();
-  }
-
-  @override
-  void close() {
-    for (_SingleIsolatedMacroExecutor executor in _executors.values) {
-      executor.close();
-    }
-  }
-
-  @override
-  Future<MacroExecutionResult> executeDeclarationsPhase(
-          MacroInstanceIdentifier macro,
-          DeclarationImpl declaration,
-          TypeResolver typeResolver,
-          ClassIntrospector classIntrospector) =>
-      _executors[macro]!.executeDeclarationsPhase(
-          macro, declaration, typeResolver, classIntrospector);
-
-  @override
-  Future<MacroExecutionResult> executeDefinitionsPhase(
-          MacroInstanceIdentifier macro,
-          DeclarationImpl declaration,
-          TypeResolver typeResolver,
-          ClassIntrospector classIntrospector,
-          TypeDeclarationResolver typeDeclarationResolver) =>
-      _executors[macro]!.executeDefinitionsPhase(macro, declaration,
-          typeResolver, classIntrospector, typeDeclarationResolver);
-
-  @override
-  Future<MacroExecutionResult> executeTypesPhase(
-          MacroInstanceIdentifier macro, DeclarationImpl declaration) =>
-      _executors[macro]!.executeTypesPhase(macro, declaration);
-
-  @override
-  Future<MacroInstanceIdentifier> instantiateMacro(
-      MacroClassIdentifier macroClass,
-      String constructor,
-      Arguments arguments) async {
-    _SingleIsolatedMacroExecutor executor = _executors[macroClass]!;
-    MacroInstanceIdentifier instance =
-        await executor.instantiateMacro(macroClass, constructor, arguments);
-    _executors[instance] = executor;
-    return instance;
-  }
-
-  @override
-  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
-      {Uri? precompiledKernelUri}) async {
-    if (precompiledKernelUri == null) {
-      throw new UnsupportedError(
-          'This environment requires a non-null `precompiledKernelUri` to be '
-          'passed when loading macros.');
-    }
-    MacroClassIdentifier identifier =
-        new MacroClassIdentifierImpl(library, name);
-    _executors.remove(identifier)?.close();
-
-    _SingleIsolatedMacroExecutor executor =
-        await _SingleIsolatedMacroExecutor.start(
-            library, name, precompiledKernelUri);
-    _executors[identifier] = executor;
-    return identifier;
-  }
-}
-
-class _SingleIsolatedMacroExecutor extends MacroExecutor {
-  /// The stream on which we receive responses.
-  final Stream<Object> messageStream;
-
-  /// The send port where we should send requests.
-  final SendPort sendPort;
-
-  /// A function that should be invoked when shutting down this executor
-  /// to perform any necessary cleanup.
-  final void Function() onClose;
-
-  /// A map of response completers by request id.
-  final responseCompleters = <int, Completer<Response>>{};
-
-  /// We need to know which serialization zone to deserialize objects in, so
-  /// that we read them from the correct cache. Each request creates its own
-  /// zone which it stores here by ID and then responses are deserialized in
-  /// the same zone.
-  static final serializationZones = <int, Zone>{};
-
-  /// Incrementing identifier for the serialization zone ids.
-  static int _nextSerializationZoneId = 0;
-
-  _SingleIsolatedMacroExecutor(
-      {required this.onClose,
-      required this.messageStream,
-      required this.sendPort}) {
-    messageStream.listen((message) {
-      withSerializationMode(SerializationMode.server, () {
-        JsonDeserializer deserializer =
-            new JsonDeserializer(message as List<Object?>);
-        // Every object starts with a zone ID which dictates the zone in which
-        // we should deserialize the message.
-        deserializer.moveNext();
-        int zoneId = deserializer.expectNum();
-        Zone zone = serializationZones[zoneId]!;
-        zone.run(() async {
-          deserializer.moveNext();
-          MessageType messageType =
-              MessageType.values[deserializer.expectNum()];
-          switch (messageType) {
-            case MessageType.response:
-              SerializableResponse response =
-                  new SerializableResponse.deserialize(deserializer, zoneId);
-              Completer<Response>? completer =
-                  responseCompleters.remove(response.requestId);
-              if (completer == null) {
-                throw new StateError(
-                    'Got a response for an unrecognized request id '
-                    '${response.requestId}');
-              }
-              completer.complete(response);
-              break;
-            case MessageType.instantiateTypeRequest:
-              InstantiateTypeRequest request =
-                  new InstantiateTypeRequest.deserialize(deserializer, zoneId);
-              StaticType instance =
-                  await (request.typeResolver.instance as TypeResolver)
-                      .instantiateType(request.typeAnnotation);
-              SerializableResponse response = new SerializableResponse(
-                  response: new RemoteInstanceImpl(
-                      id: RemoteInstance.uniqueId,
-                      instance: instance,
-                      kind: instance is NamedStaticType
-                          ? RemoteInstanceKind.namedStaticType
-                          : RemoteInstanceKind.staticType),
-                  requestId: request.id,
-                  responseType: instance is NamedStaticType
-                      ? MessageType.namedStaticType
-                      : MessageType.staticType,
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.isExactlyTypeRequest:
-              IsExactlyTypeRequest request =
-                  new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
-              StaticType leftType = request.leftType.instance as StaticType;
-              StaticType rightType = request.rightType.instance as StaticType;
-              SerializableResponse response = new SerializableResponse(
-                  response:
-                      new BooleanValue(await leftType.isExactly(rightType)),
-                  requestId: request.id,
-                  responseType: MessageType.boolean,
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.isSubtypeOfRequest:
-              IsSubtypeOfRequest request =
-                  new IsSubtypeOfRequest.deserialize(deserializer, zoneId);
-              StaticType leftType = request.leftType.instance as StaticType;
-              StaticType rightType = request.rightType.instance as StaticType;
-              SerializableResponse response = new SerializableResponse(
-                  response:
-                      new BooleanValue(await leftType.isSubtypeOf(rightType)),
-                  requestId: request.id,
-                  responseType: MessageType.boolean,
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.declarationOfRequest:
-              DeclarationOfRequest request =
-                  new DeclarationOfRequest.deserialize(deserializer, zoneId);
-              TypeDeclarationResolver resolver = request
-                  .typeDeclarationResolver.instance as TypeDeclarationResolver;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.remoteInstance,
-                  response: (await resolver.declarationOf(request.identifier)
-                      // TODO: Consider refactoring to avoid the need for this.
-                      as TypeDeclarationImpl),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.constructorsOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.declarationList,
-                  response: new DeclarationList((await classIntrospector
-                          .constructorsOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      .cast<ConstructorDeclarationImpl>()),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.fieldsOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.declarationList,
-                  response: new DeclarationList((await classIntrospector
-                          .fieldsOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      .cast<FieldDeclarationImpl>()),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.interfacesOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.declarationList,
-                  response: new DeclarationList((await classIntrospector
-                          .interfacesOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      .cast<ClassDeclarationImpl>()),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.methodsOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.declarationList,
-                  response: new DeclarationList((await classIntrospector
-                          .methodsOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      .cast<MethodDeclarationImpl>()),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.mixinsOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.declarationList,
-                  response: new DeclarationList((await classIntrospector
-                          .mixinsOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      .cast<ClassDeclarationImpl>()),
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            case MessageType.superclassOfRequest:
-              ClassIntrospectionRequest request =
-                  new ClassIntrospectionRequest.deserialize(
-                      deserializer, messageType, zoneId);
-              ClassIntrospector classIntrospector =
-                  request.classIntrospector.instance as ClassIntrospector;
-              SerializableResponse response = new SerializableResponse(
-                  requestId: request.id,
-                  responseType: MessageType.remoteInstance,
-                  response: (await classIntrospector
-                          .superclassOf(request.classDeclaration))
-                      // TODO: Consider refactoring to avoid the need for this.
-                      as ClassDeclarationImpl?,
-                  serializationZoneId: zoneId);
-              JsonSerializer serializer = new JsonSerializer();
-              response.serialize(serializer);
-              sendPort.send(serializer.result);
-              break;
-            default:
-              throw new StateError('Unexpected message type $messageType');
-          }
-        });
-      });
-    });
-  }
-
-  static Future<_SingleIsolatedMacroExecutor> start(
-      Uri library, String name, Uri precompiledKernelUri) async {
-    ReceivePort receivePort = new ReceivePort();
-    Isolate isolate =
-        await Isolate.spawnUri(precompiledKernelUri, [], receivePort.sendPort);
-    Completer<SendPort> sendPortCompleter = new Completer();
-    StreamController<Object> messageStreamController =
-        new StreamController(sync: true);
-    receivePort.listen((message) {
-      if (!sendPortCompleter.isCompleted) {
-        sendPortCompleter.complete(message as SendPort);
-      } else {
-        messageStreamController.add(message);
-      }
-    }).onDone(messageStreamController.close);
-
-    return new _SingleIsolatedMacroExecutor(
-        onClose: () {
-          receivePort.close();
-          isolate.kill();
-        },
-        messageStream: messageStreamController.stream,
-        sendPort: await sendPortCompleter.future);
-  }
-
-  @override
-  void close() => onClose();
-
-  /// These calls are handled by the higher level executor.
-  @override
-  Future<String> buildAugmentationLibrary(
-          Iterable<MacroExecutionResult> macroResults) =>
-      throw new StateError('Unreachable');
-
-  @override
-  Future<MacroExecutionResult> executeDeclarationsPhase(
-          MacroInstanceIdentifier macro,
-          DeclarationImpl declaration,
-          TypeResolver typeResolver,
-          ClassIntrospector classIntrospector) =>
-      _sendRequest((zoneId) => new ExecuteDeclarationsPhaseRequest(
-          macro,
-          declaration,
-          new RemoteInstanceImpl(
-              instance: typeResolver,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.typeResolver),
-          new RemoteInstanceImpl(
-              instance: classIntrospector,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.classIntrospector),
-          serializationZoneId: zoneId));
-
-  @override
-  Future<MacroExecutionResult> executeDefinitionsPhase(
-          MacroInstanceIdentifier macro,
-          DeclarationImpl declaration,
-          TypeResolver typeResolver,
-          ClassIntrospector classIntrospector,
-          TypeDeclarationResolver typeDeclarationResolver) =>
-      _sendRequest((zoneId) => new ExecuteDefinitionsPhaseRequest(
-          macro,
-          declaration,
-          new RemoteInstanceImpl(
-              instance: typeResolver,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.typeResolver),
-          new RemoteInstanceImpl(
-              instance: classIntrospector,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.classIntrospector),
-          new RemoteInstanceImpl(
-              instance: typeDeclarationResolver,
-              id: RemoteInstance.uniqueId,
-              kind: RemoteInstanceKind.typeDeclarationResolver),
-          serializationZoneId: zoneId));
-
-  @override
-  Future<MacroExecutionResult> executeTypesPhase(
-          MacroInstanceIdentifier macro, DeclarationImpl declaration) =>
-      _sendRequest((zoneId) => new ExecuteTypesPhaseRequest(macro, declaration,
-          serializationZoneId: zoneId));
-
-  @override
-  Future<MacroInstanceIdentifier> instantiateMacro(
-          MacroClassIdentifier macroClass,
-          String constructor,
-          Arguments arguments) =>
-      _sendRequest((zoneId) => new InstantiateMacroRequest(
-          macroClass, constructor, arguments,
-          serializationZoneId: zoneId));
-
-  /// These calls are handled by the higher level executor.
-  @override
-  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
-          {Uri? precompiledKernelUri}) =>
-      throw new StateError('Unreachable');
-
-  /// Creates a [Request] with a given serialization zone ID, and handles the
-  /// response, casting it to the expected type or throwing the error provided.
-  Future<T> _sendRequest<T>(Request Function(int) requestFactory) =>
-      withSerializationMode(SerializationMode.server, () async {
-        int zoneId = _nextSerializationZoneId++;
-        serializationZones[zoneId] = Zone.current;
-        Request request = requestFactory(zoneId);
-        JsonSerializer serializer = new JsonSerializer();
-        // It is our responsibility to add the zone ID header.
-        serializer.addNum(zoneId);
-        request.serialize(serializer);
-        sendPort.send(serializer.result);
-        Completer<Response> completer = new Completer<Response>();
-        responseCompleters[request.id] = completer;
-        try {
-          Response response = await completer.future;
-          T? result = response.response as T?;
-          if (result != null) return result;
-          throw new RemoteException(
-              response.error!.toString(), response.stackTrace);
-        } finally {
-          // Clean up the zone after the request is done.
-          serializationZones.remove(zoneId);
-        }
-      });
-}
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 027c7bb..a9ec81e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -1902,15 +1902,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeContinueLabelNotTarget = messageContinueLabelNotTarget;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageContinueLabelNotTarget = const MessageCode(
-    "ContinueLabelNotTarget",
-    analyzerCodes: <String>["LABEL_UNDEFINED"],
-    problemMessage: r"""Target of continue must be a label.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeContinueOutsideOfLoop = messageContinueOutsideOfLoop;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2770,6 +2761,33 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumConstructorSuperInitializer =
+    messageEnumConstructorSuperInitializer;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumConstructorSuperInitializer = const MessageCode(
+    "EnumConstructorSuperInitializer",
+    problemMessage: r"""Enum constructors can't contain super-initializers.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumConstructorTearoff = messageEnumConstructorTearoff;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumConstructorTearoff = const MessageCode(
+    "EnumConstructorTearoff",
+    problemMessage: r"""Enum constructors can't be torn off.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumContainsValuesDeclaration =
+    messageEnumContainsValuesDeclaration;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumContainsValuesDeclaration = const MessageCode(
+    "EnumContainsValuesDeclaration",
+    problemMessage:
+        r"""Enums can't contain declarations of members with the name 'values'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeEnumDeclarationEmpty = messageEnumDeclarationEmpty;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2799,6 +2817,41 @@
             r"""Missing arguments in enum constructor invocation.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumFactoryRedirectsToConstructor =
+    messageEnumFactoryRedirectsToConstructor;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumFactoryRedirectsToConstructor = const MessageCode(
+    "EnumFactoryRedirectsToConstructor",
+    problemMessage:
+        r"""Enum factory constructors can't redirect to generative constructors.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateEnumImplementerContainsValuesDeclaration =
+    const Template<Message Function(String name)>(
+        problemMessageTemplate:
+            r"""'#name' has 'Enum' as a superinterface and can't contain non-static member with name 'values'.""",
+        withArguments: _withArgumentsEnumImplementerContainsValuesDeclaration);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeEnumImplementerContainsValuesDeclaration =
+    const Code<Message Function(String name)>(
+  "EnumImplementerContainsValuesDeclaration",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsEnumImplementerContainsValuesDeclaration(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeEnumImplementerContainsValuesDeclaration,
+      problemMessage:
+          """'${name}' has 'Enum' as a superinterface and can't contain non-static member with name 'values'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeEnumInClass = messageEnumInClass;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2817,6 +2870,15 @@
     problemMessage: r"""Enums can't be instantiated.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumNonConstConstructor = messageEnumNonConstConstructor;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumNonConstConstructor = const MessageCode(
+    "EnumNonConstConstructor",
+    problemMessage:
+        r"""Generative enum constructors must be marked as 'const'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)>
     templateEnumSupertypeOfNonAbstractClass =
     const Template<Message Function(String name)>(
@@ -6940,6 +7002,34 @@
     problemMessage: r"""'loadLibrary' takes no arguments.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateMacroClassNotDeclaredMacro = const Template<
+        Message Function(String name)>(
+    problemMessageTemplate:
+        r"""Non-abstract class '#name' implements 'Macro' but isn't declared as a macro class.""",
+    correctionMessageTemplate: r"""Try adding the 'macro' class modifier.""",
+    withArguments: _withArgumentsMacroClassNotDeclaredMacro);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeMacroClassNotDeclaredMacro =
+    const Code<Message Function(String name)>(
+  "MacroClassNotDeclaredMacro",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMacroClassNotDeclaredMacro(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeMacroClassNotDeclaredMacro,
+      problemMessage:
+          """Non-abstract class '${name}' implements 'Macro' but isn't declared as a macro class.""",
+      correctionMessage: """Try adding the 'macro' class modifier.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMainNotFunctionDeclaration =
     messageMainNotFunctionDeclaration;
 
@@ -7378,6 +7468,37 @@
     problemMessage: r"""Can't have more than one 'super' initializer.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        String
+            string2)> templateMultipleClauses = const Template<
+        Message Function(String string, String string2)>(
+    problemMessageTemplate:
+        r"""Each '#string' definition can have at most one '#string2' clause.""",
+    correctionMessageTemplate:
+        r"""Try combining all of the '#string2' clauses into a single clause.""",
+    withArguments: _withArgumentsMultipleClauses);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+    codeMultipleClauses =
+    const Code<Message Function(String string, String string2)>(
+        "MultipleClauses",
+        index: 121);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMultipleClauses(String string, String string2) {
+  if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
+  return new Message(codeMultipleClauses,
+      problemMessage:
+          """Each '${string}' definition can have at most one '${string2}' clause.""",
+      correctionMessage: """Try combining all of the '${string2}' clauses into a single clause.""",
+      arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMultipleExtends = messageMultipleExtends;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7685,6 +7806,46 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateNonAugmentationClassMemberConflict = const Template<
+        Message Function(String name)>(
+    problemMessageTemplate:
+        r"""Member '#name' conflicts with an existing member of the same name in the augmented class.""",
+    correctionMessageTemplate:
+        r"""Try changing the name to an existing member or adding an 'augment' modifier.""",
+    withArguments: _withArgumentsNonAugmentationClassMemberConflict);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeNonAugmentationClassMemberConflict =
+    const Code<Message Function(String name)>(
+  "NonAugmentationClassMemberConflict",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNonAugmentationClassMemberConflict(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNonAugmentationClassMemberConflict,
+      problemMessage:
+          """Member '${name}' conflicts with an existing member of the same name in the augmented class.""",
+      correctionMessage: """Try changing the name to an existing member or adding an 'augment' modifier.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeNonAugmentationClassMemberConflictCause =
+    messageNonAugmentationClassMemberConflictCause;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageNonAugmentationClassMemberConflictCause =
+    const MessageCode("NonAugmentationClassMemberConflictCause",
+        severity: Severity.context,
+        problemMessage: r"""This is the existing member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeNonConstConstructor = messageNonConstConstructor;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -8271,6 +8432,37 @@
     correctionMessage: r"""Try removing the type parameters.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        String
+            string2)> templateOutOfOrderClauses = const Template<
+        Message Function(String string, String string2)>(
+    problemMessageTemplate:
+        r"""The '#string' clause must come before the '#string2' clause.""",
+    correctionMessageTemplate:
+        r"""Try moving the '#string' clause before the '#string2' clause.""",
+    withArguments: _withArgumentsOutOfOrderClauses);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+    codeOutOfOrderClauses =
+    const Code<Message Function(String string, String string2)>(
+        "OutOfOrderClauses",
+        index: 122);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOutOfOrderClauses(String string, String string2) {
+  if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
+  return new Message(codeOutOfOrderClauses,
+      problemMessage:
+          """The '${string}' clause must come before the '${string2}' clause.""",
+      correctionMessage: """Try moving the '${string}' clause before the '${string2}' clause.""",
+      arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateOverriddenMethodCause =
     const Template<Message Function(String name)>(
         problemMessageTemplate: r"""This is the overridden method ('#name').""",
@@ -10225,6 +10417,44 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeUnexpectedTokens = messageUnexpectedTokens;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageUnexpectedTokens = const MessageCode(
+    "UnexpectedTokens",
+    index: 123,
+    problemMessage: r"""Unexpected tokens.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateUnmatchedAugmentationClassMember = const Template<
+        Message Function(String name)>(
+    problemMessageTemplate:
+        r"""Augmentation member '#name' doesn't match a member in the augmented class.""",
+    correctionMessageTemplate:
+        r"""Try changing the name to an existing member or removing the 'augment' modifier.""",
+    withArguments: _withArgumentsUnmatchedAugmentationClassMember);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeUnmatchedAugmentationClassMember =
+    const Code<Message Function(String name)>(
+  "UnmatchedAugmentationClassMember",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUnmatchedAugmentationClassMember(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeUnmatchedAugmentationClassMember,
+      problemMessage:
+          """Augmentation member '${name}' doesn't match a member in the augmented class.""",
+      correctionMessage: """Try changing the name to an existing member or removing the 'augment' modifier.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string, Token token)>
     templateUnmatchedToken =
     const Template<Message Function(String string, Token token)>(
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 9741d8c..cf3476b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -61,9 +61,10 @@
   }
 
   @override
-  void beginClassDeclaration(
-      Token begin, Token? abstractToken, Token? macroToken, Token name) {
-    listener?.beginClassDeclaration(begin, abstractToken, macroToken, name);
+  void beginClassDeclaration(Token begin, Token? abstractToken,
+      Token? macroToken, Token? augmentToken, Token name) {
+    listener?.beginClassDeclaration(
+        begin, abstractToken, macroToken, augmentToken, name);
   }
 
   @override
@@ -318,19 +319,21 @@
   @override
   void beginMethod(
       DeclarationKind declarationKind,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
       Token? varFinalOrConst,
       Token? getOrSet,
       Token name) {
-    listener?.beginMethod(declarationKind, externalToken, staticToken,
-        covariantToken, varFinalOrConst, getOrSet, name);
+    listener?.beginMethod(declarationKind, augmentToken, externalToken,
+        staticToken, covariantToken, varFinalOrConst, getOrSet, name);
   }
 
   @override
-  void beginMixinDeclaration(Token mixinKeyword, Token name) {
-    listener?.beginMixinDeclaration(mixinKeyword, name);
+  void beginMixinDeclaration(
+      Token? augmentToken, Token mixinKeyword, Token name) {
+    listener?.beginMixinDeclaration(augmentToken, mixinKeyword, name);
   }
 
   @override
@@ -339,10 +342,10 @@
   }
 
   @override
-  void beginNamedMixinApplication(
-      Token begin, Token? abstractToken, Token? macroToken, Token name) {
+  void beginNamedMixinApplication(Token begin, Token? abstractToken,
+      Token? macroToken, Token? augmentToken, Token name) {
     listener?.beginNamedMixinApplication(
-        begin, abstractToken, macroToken, name);
+        begin, abstractToken, macroToken, augmentToken, name);
   }
 
   @override
@@ -416,8 +419,9 @@
   }
 
   @override
-  void beginTopLevelMethod(Token lastConsumed, Token? externalToken) {
-    listener?.beginTopLevelMethod(lastConsumed, externalToken);
+  void beginTopLevelMethod(
+      Token lastConsumed, Token? augmentToken, Token? externalToken) {
+    listener?.beginTopLevelMethod(lastConsumed, augmentToken, externalToken);
   }
 
   @override
@@ -545,6 +549,7 @@
   @override
   void endClassFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -555,6 +560,7 @@
       Token endToken) {
     listener?.endClassFields(
         abstractToken,
+        augmentToken,
         externalToken,
         staticToken,
         covariantToken,
@@ -673,6 +679,7 @@
   @override
   void endEnumFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -683,6 +690,7 @@
       Token endToken) {
     listener?.endClassFields(
         abstractToken,
+        augmentToken,
         externalToken,
         staticToken,
         covariantToken,
@@ -728,6 +736,7 @@
   @override
   void endExtensionFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -738,6 +747,7 @@
       Token endToken) {
     listener?.endExtensionFields(
         abstractToken,
+        augmentToken,
         externalToken,
         staticToken,
         covariantToken,
@@ -883,8 +893,8 @@
   }
 
   @override
-  void endImport(Token importKeyword, Token? semicolon) {
-    listener?.endImport(importKeyword, semicolon);
+  void endImport(Token importKeyword, Token? augmentToken, Token? semicolon) {
+    listener?.endImport(importKeyword, augmentToken, semicolon);
   }
 
   @override
@@ -976,6 +986,7 @@
   @override
   void endMixinFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -986,6 +997,7 @@
       Token endToken) {
     listener?.endMixinFields(
         abstractToken,
+        augmentToken,
         externalToken,
         staticToken,
         covariantToken,
@@ -1095,14 +1107,23 @@
   void beginFields(
       DeclarationKind declarationKind,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
       Token? lateToken,
       Token? varFinalOrConst,
       Token lastConsumed) {
-    listener?.beginFields(declarationKind, abstractToken, externalToken,
-        staticToken, covariantToken, lateToken, varFinalOrConst, lastConsumed);
+    listener?.beginFields(
+        declarationKind,
+        abstractToken,
+        augmentToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        lastConsumed);
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
index 6e4c96b..4621543 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
@@ -124,8 +124,12 @@
     }
 
     // Recovery
-    if (isOneOfOrEof(identifier, followingValues) ||
-        looksLikeStartOfNextTopLevelDeclaration(identifier)) {
+    if (isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
@@ -603,8 +607,12 @@
         isOneOfOrEof(identifier.next!, followingValues)) {
       parser.reportRecoverableErrorWithToken(
           identifier, codes.templateBuiltInIdentifierInDeclaration);
-    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
-        isOneOfOrEof(identifier, followingValues)) {
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (isOneOfOrEof(identifier, followingValues)) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
@@ -802,8 +810,12 @@
     }
 
     // Recovery
-    if (isOneOfOrEof(identifier, followingValues) ||
-        looksLikeStartOfNextTopLevelDeclaration(identifier)) {
+    if (isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 2f5e2a4..d31bac8b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -126,8 +126,8 @@
   /// (or extraneous modifiers in the case of recovery) preceding [name].
   ///
   /// At this point we have parsed the name and type parameter declarations.
-  void beginClassDeclaration(
-      Token begin, Token? abstractToken, Token? macroToken, Token name) {}
+  void beginClassDeclaration(Token begin, Token? abstractToken,
+      Token? macroToken, Token? augmentToken, Token name) {}
 
   /// Handle an extends clause in a class declaration. Substructures:
   /// - supertype (may be a mixin application)
@@ -186,7 +186,8 @@
   }
 
   /// Handle the beginning of a mixin declaration.
-  void beginMixinDeclaration(Token mixinKeyword, Token name) {}
+  void beginMixinDeclaration(
+      Token? augmentToken, Token mixinKeyword, Token name) {}
 
   /// Handle an on clause in a mixin declaration. Substructures:
   /// - implemented types
@@ -436,6 +437,7 @@
   /// Started by [beginFields].
   void endClassFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -456,6 +458,7 @@
   /// Started by [beginFields].
   void endMixinFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -465,8 +468,17 @@
       Token beginToken,
       Token endToken) {
     // TODO(danrubel): push implementation into subclasses
-    endClassFields(abstractToken, externalToken, staticToken, covariantToken,
-        lateToken, varFinalOrConst, count, beginToken, endToken);
+    endClassFields(
+        abstractToken,
+        augmentToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        count,
+        beginToken,
+        endToken);
   }
 
   /// Handle the end of a extension field declaration.  Substructures:
@@ -478,6 +490,7 @@
   /// Started by [beginFields].
   void endExtensionFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -487,8 +500,17 @@
       Token beginToken,
       Token endToken) {
     // TODO(danrubel): push implementation into subclasses
-    endClassFields(abstractToken, externalToken, staticToken, covariantToken,
-        lateToken, varFinalOrConst, count, beginToken, endToken);
+    endClassFields(
+        abstractToken,
+        augmentToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        count,
+        beginToken,
+        endToken);
   }
 
   /// Handle the end of an enum field declaration.  Substructures:
@@ -500,6 +522,7 @@
   /// Started by [beginFields].
   void endEnumFields(
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -508,8 +531,17 @@
       int count,
       Token beginToken,
       Token endToken) {
-    endClassFields(abstractToken, externalToken, staticToken, covariantToken,
-        lateToken, varFinalOrConst, count, beginToken, endToken);
+    endClassFields(
+        abstractToken,
+        augmentToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        count,
+        beginToken,
+        endToken);
   }
 
   /// Handle the end of an enum method declaration.  Substructures:
@@ -720,8 +752,8 @@
   /// (or extraneous modifiers in the case of recovery) preceding [name].
   ///
   /// At this point we have parsed the name and type parameter declarations.
-  void beginNamedMixinApplication(
-      Token begin, Token? abstractToken, Token? macroToken, Token name) {}
+  void beginNamedMixinApplication(Token begin, Token? abstractToken,
+      Token? macroToken, Token? augmentToken, Token name) {}
 
   /// Handle a named mixin application with clause (e.g. "A with B, C").
   /// Substructures:
@@ -801,7 +833,7 @@
   /// - conditional uris
   /// - prefix identifier
   /// - combinators
-  void endImport(Token importKeyword, Token? semicolon) {
+  void endImport(Token importKeyword, Token? augmentToken, Token? semicolon) {
     logEvent("Import");
   }
 
@@ -977,6 +1009,7 @@
   /// [endMixinMethod].
   void beginMethod(
       DeclarationKind declarationKind,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -1249,6 +1282,7 @@
   void beginFields(
       DeclarationKind declarationKind,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -1276,7 +1310,8 @@
     logEvent("TopLevelFields");
   }
 
-  void beginTopLevelMethod(Token lastConsumed, Token? externalToken) {}
+  void beginTopLevelMethod(
+      Token lastConsumed, Token? augmentToken, Token? externalToken) {}
 
   /// Handle the end of a top level method.  Substructures:
   /// - metadata
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart b/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart
index a062b38..99e4582 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart
@@ -34,9 +34,10 @@
 
 /// This class is used to parse modifiers in most locations where modifiers
 /// can occur, but does not call handleModifier or handleModifiers.
-class ModifierRecoveryContext {
+class ModifierContext {
   final Parser parser;
   Token? abstractToken;
+  Token? augmentToken;
   Token? constToken;
   Token? covariantToken;
   Token? externalToken;
@@ -47,12 +48,9 @@
   Token? varToken;
 
   // Set `true` when parsing modifiers after the `factory` token.
-  bool afterFactory = false;
+  bool _afterFactory = false;
 
-  // TODO(danrubel): Replace [ModifierRecoveryContext] and [ModifierContext]
-  // with this class.
-
-  ModifierRecoveryContext(this.parser);
+  ModifierContext(this.parser);
 
   set staticOrCovariant(Token? staticOrCovariant) {
     if (staticOrCovariant == null) {
@@ -94,9 +92,76 @@
     }
   }
 
+  /// Parse modifiers for class declarations.
+  Token parseClassModifiers(Token token, Token keyword) {
+    token = _parseModifiers(token);
+    if (constToken != null) {
+      reportTopLevelModifierError(constToken!, keyword);
+    }
+    if (externalToken != null) {
+      reportTopLevelModifierError(externalToken!, keyword);
+    }
+    reportExtraneousModifier(covariantToken);
+    reportExtraneousModifier(finalToken);
+    reportExtraneousModifier(lateToken);
+    reportExtraneousModifier(requiredToken);
+    reportExtraneousModifier(staticToken);
+    reportExtraneousModifier(varToken);
+    return token;
+  }
+
+  /// Parse modifiers for enum declarations.
+  Token parseEnumModifiers(Token token, Token keyword) {
+    token = _parseModifiers(token);
+    reportTopLevelModifierError(constToken, keyword);
+    reportTopLevelModifierError(externalToken, keyword);
+    reportExtraneousModifier(abstractToken);
+    // TODO(johnniwinther): Should we support 'augment' on enums.
+    reportExtraneousModifier(augmentToken);
+    reportExtraneousModifier(covariantToken);
+    reportExtraneousModifier(finalToken);
+    reportExtraneousModifier(lateToken);
+    reportExtraneousModifier(requiredToken);
+    reportExtraneousModifier(staticToken);
+    reportExtraneousModifier(varToken);
+    return token;
+  }
+
+  /// Parse modifiers for mixin declarations.
+  Token parseMixinModifiers(Token token, Token keyword) {
+    token = _parseModifiers(token);
+    reportTopLevelModifierError(constToken, keyword);
+    reportTopLevelModifierError(externalToken, keyword);
+    reportExtraneousModifier(abstractToken);
+    reportExtraneousModifier(covariantToken);
+    reportExtraneousModifier(finalToken);
+    reportExtraneousModifier(lateToken);
+    reportExtraneousModifier(requiredToken);
+    reportExtraneousModifier(staticToken);
+    reportExtraneousModifier(varToken);
+    return token;
+  }
+
+  /// Parse modifiers for library, import, export, part (of) directives and
+  /// typedef and extension declarations.
+  Token parseTopLevelKeywordModifiers(Token token, Token keyword) {
+    token = _parseModifiers(token);
+    reportTopLevelModifierError(constToken, keyword);
+    reportTopLevelModifierError(externalToken, keyword);
+    reportExtraneousModifier(abstractToken);
+    reportExtraneousModifier(augmentToken);
+    reportExtraneousModifier(covariantToken);
+    reportExtraneousModifier(finalToken);
+    reportExtraneousModifier(lateToken);
+    reportExtraneousModifier(requiredToken);
+    reportExtraneousModifier(staticToken);
+    reportExtraneousModifier(varToken);
+    return token;
+  }
+
   /// Parse modifiers for class methods and fields.
   Token parseClassMemberModifiers(Token token) {
-    token = parseModifiers(token);
+    token = _parseModifiers(token);
     reportExtraneousModifier(requiredToken);
     return token;
   }
@@ -104,7 +169,7 @@
   /// Parse modifiers for formal parameters.
   Token parseFormalParameterModifiers(
       Token token, FormalParameterKind parameterKind, MemberKind memberKind) {
-    token = parseModifiers(token);
+    token = _parseModifiers(token);
 
     if (parameterKind != FormalParameterKind.optionalNamed) {
       reportExtraneousModifier(requiredToken);
@@ -133,8 +198,8 @@
 
   /// Parse modifiers after the `factory` token.
   Token parseModifiersAfterFactory(Token token) {
-    afterFactory = true;
-    token = parseModifiers(token);
+    _afterFactory = true;
+    token = _parseModifiers(token);
     if (abstractToken != null) {
       parser.reportRecoverableError(
           abstractToken!, codes.messageAbstractClassMember);
@@ -145,8 +210,8 @@
   }
 
   /// Parse modifiers for top level functions and fields.
-  Token parseTopLevelModifiers(Token token) {
-    token = parseModifiers(token);
+  Token parseTopLevelMemberModifiers(Token token) {
+    token = _parseModifiers(token);
     reportExtraneousModifier(abstractToken);
     reportExtraneousModifier(covariantToken);
     reportExtraneousModifier(requiredToken);
@@ -156,7 +221,7 @@
 
   /// Parse modifiers for variable declarations.
   Token parseVariableDeclarationModifiers(Token token) {
-    token = parseModifiers(token);
+    token = _parseModifiers(token);
     reportExtraneousModifier(abstractToken);
     reportExtraneousModifier(covariantToken);
     reportExtraneousModifier(externalToken);
@@ -176,34 +241,36 @@
   /// `static` or `covariant`. The first non-null parameter of
   /// [staticOrCovariant], [staticToken], or [covariantToken] will be used,
   /// in that order, and the others ignored.
-  Token parseModifiers(Token token) {
+  Token _parseModifiers(Token token) {
     // Process invalid and out-of-order modifiers
     Token next = token.next!;
     while (true) {
       final String? value = next.stringValue;
       if (isModifier(next)) {
         if (identical('abstract', value)) {
-          token = parseAbstract(token);
+          token = _parseAbstract(token);
+        } else if (identical('augment', value)) {
+          token = _parseAugment(token);
         } else if (identical('const', value)) {
-          token = parseConst(token);
+          token = _parseConst(token);
         } else if (identical('covariant', value)) {
-          token = parseCovariant(token);
+          token = _parseCovariant(token);
         } else if (identical('external', value)) {
-          token = parseExternal(token);
+          token = _parseExternal(token);
         } else if (identical('final', value)) {
-          token = parseFinal(token);
+          token = _parseFinal(token);
         } else if (identical('late', value)) {
-          token = parseLate(token);
+          token = _parseLate(token);
         } else if (identical('required', value)) {
-          token = parseRequired(token);
+          token = _parseRequired(token);
         } else if (identical('static', value)) {
-          token = parseStatic(token);
+          token = _parseStatic(token);
         } else if (identical('var', value)) {
-          token = parseVar(token);
+          token = _parseVar(token);
         } else {
           throw 'Internal Error: Unhandled modifier: $value';
         }
-      } else if (afterFactory && identical('factory', value)) {
+      } else if (_afterFactory && identical('factory', value)) {
         parser.reportRecoverableErrorWithToken(
             next, codes.templateDuplicatedModifier);
         token = next;
@@ -215,7 +282,7 @@
     return token;
   }
 
-  Token parseAbstract(Token token) {
+  Token _parseAbstract(Token token) {
     Token next = token.next!;
     assert(optional('abstract', next));
     if (abstractToken == null) {
@@ -235,13 +302,45 @@
     return next;
   }
 
-  Token parseConst(Token token) {
+  Token _parseAugment(Token token) {
+    Token next = token.next!;
+    assert(optional('augment', next));
+    if (augmentToken == null) {
+      augmentToken = next;
+
+      if (varFinalOrConst != null) {
+        reportModifierOutOfOrder(next, varFinalOrConst!.lexeme);
+      } else if (abstractToken != null) {
+        reportModifierOutOfOrder(next, abstractToken!.lexeme);
+      } else if (constToken != null) {
+        reportModifierOutOfOrder(next, constToken!.lexeme);
+      } else if (covariantToken != null) {
+        reportModifierOutOfOrder(next, covariantToken!.lexeme);
+      } else if (finalToken != null) {
+        reportModifierOutOfOrder(next, finalToken!.lexeme);
+      } else if (lateToken != null) {
+        reportModifierOutOfOrder(next, lateToken!.lexeme);
+      } else if (staticToken != null) {
+        reportModifierOutOfOrder(next, staticToken!.lexeme);
+      } else if (externalToken != null) {
+        reportConflictingModifiers(next, externalToken!);
+      }
+      return next;
+    }
+
+    // Recovery
+    parser.reportRecoverableErrorWithToken(
+        next, codes.templateDuplicatedModifier);
+    return next;
+  }
+
+  Token _parseConst(Token token) {
     Token next = token.next!;
     assert(optional('const', next));
     if (varFinalOrConst == null && covariantToken == null) {
       constToken = next;
 
-      if (afterFactory) {
+      if (_afterFactory) {
         reportModifierOutOfOrder(next, 'factory');
       } else if (lateToken != null) {
         reportConflictingModifiers(next, lateToken!);
@@ -265,13 +364,13 @@
     return next;
   }
 
-  Token parseCovariant(Token token) {
+  Token _parseCovariant(Token token) {
     Token next = token.next!;
     assert(optional('covariant', next));
     if (constToken == null &&
         covariantToken == null &&
         staticToken == null &&
-        !afterFactory) {
+        !_afterFactory) {
       covariantToken = next;
 
       if (varToken != null) {
@@ -288,7 +387,7 @@
     if (covariantToken != null) {
       parser.reportRecoverableErrorWithToken(
           next, codes.templateDuplicatedModifier);
-    } else if (afterFactory) {
+    } else if (_afterFactory) {
       reportExtraneousModifier(next);
     } else if (constToken != null) {
       reportConflictingModifiers(next, constToken!);
@@ -300,13 +399,13 @@
     return next;
   }
 
-  Token parseExternal(Token token) {
+  Token _parseExternal(Token token) {
     Token next = token.next!;
     assert(optional('external', next));
     if (externalToken == null) {
       externalToken = next;
 
-      if (afterFactory) {
+      if (_afterFactory) {
         reportModifierOutOfOrder(next, 'factory');
       } else if (constToken != null) {
         reportModifierOutOfOrder(next, constToken!.lexeme);
@@ -318,6 +417,8 @@
         reportModifierOutOfOrder(next, varFinalOrConst!.lexeme);
       } else if (covariantToken != null) {
         reportModifierOutOfOrder(next, covariantToken!.lexeme);
+      } else if (augmentToken != null) {
+        reportConflictingModifiers(next, augmentToken!);
       }
       return next;
     }
@@ -328,10 +429,10 @@
     return next;
   }
 
-  Token parseFinal(Token token) {
+  Token _parseFinal(Token token) {
     Token next = token.next!;
     assert(optional('final', next));
-    if (varFinalOrConst == null && !afterFactory) {
+    if (varFinalOrConst == null && !_afterFactory) {
       finalToken = next;
       return next;
     }
@@ -340,7 +441,7 @@
     if (finalToken != null) {
       parser.reportRecoverableErrorWithToken(
           next, codes.templateDuplicatedModifier);
-    } else if (afterFactory) {
+    } else if (_afterFactory) {
       reportExtraneousModifier(next);
     } else if (constToken != null) {
       parser.reportRecoverableError(next, codes.messageConstAndFinal);
@@ -354,7 +455,7 @@
     return next;
   }
 
-  Token parseLate(Token token) {
+  Token _parseLate(Token token) {
     Token next = token.next!;
     assert(optional('late', next));
     if (lateToken == null) {
@@ -376,7 +477,7 @@
     return next;
   }
 
-  Token parseRequired(Token token) {
+  Token _parseRequired(Token token) {
     Token next = token.next!;
     assert(optional('required', next));
     if (requiredToken == null) {
@@ -400,10 +501,10 @@
     return next;
   }
 
-  Token parseStatic(Token token) {
+  Token _parseStatic(Token token) {
     Token next = token.next!;
     assert(optional('static', next));
-    if (covariantToken == null && staticToken == null && !afterFactory) {
+    if (covariantToken == null && staticToken == null && !_afterFactory) {
       staticToken = next;
 
       if (constToken != null) {
@@ -424,7 +525,7 @@
     } else if (staticToken != null) {
       parser.reportRecoverableErrorWithToken(
           next, codes.templateDuplicatedModifier);
-    } else if (afterFactory) {
+    } else if (_afterFactory) {
       reportExtraneousModifier(next);
     } else {
       throw 'Internal Error: Unhandled recovery: $next';
@@ -432,10 +533,10 @@
     return next;
   }
 
-  Token parseVar(Token token) {
+  Token _parseVar(Token token) {
     Token next = token.next!;
     assert(optional('var', next));
-    if (varFinalOrConst == null && !afterFactory) {
+    if (varFinalOrConst == null && !_afterFactory) {
       varToken = next;
       return next;
     }
@@ -444,7 +545,7 @@
     if (varToken != null) {
       parser.reportRecoverableErrorWithToken(
           next, codes.templateDuplicatedModifier);
-    } else if (afterFactory) {
+    } else if (_afterFactory) {
       reportExtraneousModifier(next);
     } else if (constToken != null) {
       reportConflictingModifiers(next, constToken!);
@@ -470,6 +571,30 @@
     }
   }
 
+  // Report an error for the given modifier preceding a top level keyword
+  // such as `import` or `class`.
+  void reportTopLevelModifierError(Token? modifier, Token afterModifiers) {
+    if (modifier != null) {
+      if (optional('const', modifier) && optional('class', afterModifiers)) {
+        parser.reportRecoverableError(modifier, codes.messageConstClass);
+      } else if (optional('external', modifier)) {
+        if (optional('class', afterModifiers)) {
+          parser.reportRecoverableError(modifier, codes.messageExternalClass);
+        } else if (optional('enum', afterModifiers)) {
+          parser.reportRecoverableError(modifier, codes.messageExternalEnum);
+        } else if (optional('typedef', afterModifiers)) {
+          parser.reportRecoverableError(modifier, codes.messageExternalTypedef);
+        } else {
+          parser.reportRecoverableErrorWithToken(
+              modifier, codes.templateExtraneousModifier);
+        }
+      } else {
+        parser.reportRecoverableErrorWithToken(
+            modifier, codes.templateExtraneousModifier);
+      }
+    }
+  }
+
   void reportExtraneousModifierInExtension(Token? modifier) {
     if (modifier != null) {
       parser.reportRecoverableErrorWithToken(
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 a441a40..b8da52c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -76,6 +76,9 @@
         looksLikeExpressionStart,
         okNextValueInFormalParameter;
 
+import 'identifier_context_impl.dart'
+    show looksLikeStartOfNextTopLevelDeclaration;
+
 import 'listener.dart' show Listener;
 
 import 'literal_entry_info.dart'
@@ -89,7 +92,7 @@
 
 import 'member_kind.dart' show MemberKind;
 
-import 'modifier_context.dart' show ModifierRecoveryContext, isModifier;
+import 'modifier_context.dart' show ModifierContext, isModifier;
 
 import 'recovery_listeners.dart'
     show
@@ -549,55 +552,6 @@
     return parseInvalidTopLevelDeclaration(token);
   }
 
-  /// Parse the modifiers before the `class` keyword.
-  /// Return the first `abstract` modifier or `null` if not found.
-  Token? parseClassDeclarationModifiers(Token start, Token keyword) {
-    Token modifier = start.next!;
-    while (modifier != keyword) {
-      if (optional('abstract', modifier)) {
-        parseTopLevelKeywordModifiers(modifier, keyword);
-        return modifier;
-      } else {
-        // Recovery
-        reportTopLevelModifierError(modifier, keyword);
-      }
-      modifier = modifier.next!;
-    }
-    return null;
-  }
-
-  /// Report errors on any modifiers before the specified keyword.
-  void parseTopLevelKeywordModifiers(Token start, Token keyword) {
-    Token modifier = start.next!;
-    while (modifier != keyword) {
-      // Recovery
-      reportTopLevelModifierError(modifier, keyword);
-      modifier = modifier.next!;
-    }
-  }
-
-  // Report an error for the given modifier preceding a top level keyword
-  // such as `import` or `class`.
-  void reportTopLevelModifierError(Token modifier, Token afterModifiers) {
-    if (optional('const', modifier) && optional('class', afterModifiers)) {
-      reportRecoverableError(modifier, codes.messageConstClass);
-    } else if (optional('external', modifier)) {
-      if (optional('class', afterModifiers)) {
-        reportRecoverableError(modifier, codes.messageExternalClass);
-      } else if (optional('enum', afterModifiers)) {
-        reportRecoverableError(modifier, codes.messageExternalEnum);
-      } else if (optional('typedef', afterModifiers)) {
-        reportRecoverableError(modifier, codes.messageExternalTypedef);
-      } else {
-        reportRecoverableErrorWithToken(
-            modifier, codes.templateExtraneousModifier);
-      }
-    } else {
-      reportRecoverableErrorWithToken(
-          modifier, codes.templateExtraneousModifier);
-    }
-  }
-
   /// Parse any top-level declaration that begins with a keyword.
   /// [start] is the token before any modifiers preceding [keyword].
   Token parseTopLevelKeywordDeclaration(Token start, Token keyword,
@@ -606,13 +560,16 @@
     final String? value = keyword.stringValue;
     if (identical(value, 'class')) {
       directiveState?.checkDeclaration();
-      Token? abstractToken =
-          parseClassDeclarationModifiers(start, macroToken ?? keyword);
+      ModifierContext context = new ModifierContext(this);
+      context.parseClassModifiers(start, keyword);
+      Token? abstractToken = context.abstractToken;
+      Token? augmentToken = context.augmentToken;
       return parseClassOrNamedMixinApplication(
-          abstractToken, macroToken, keyword);
+          abstractToken, macroToken, augmentToken, keyword);
     } else if (identical(value, 'enum')) {
       directiveState?.checkDeclaration();
-      parseTopLevelKeywordModifiers(start, keyword);
+      ModifierContext context = new ModifierContext(this);
+      context.parseEnumModifiers(start, keyword);
       return parseEnum(keyword);
     } else {
       // The remaining top level keywords are built-in keywords
@@ -636,25 +593,32 @@
         directiveState?.checkDeclaration();
         return parseTopLevelMemberImpl(start);
       } else {
-        parseTopLevelKeywordModifiers(start, keyword);
+        ModifierContext context = new ModifierContext(this);
         if (identical(value, 'import')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           directiveState?.checkImport(this, keyword);
           return parseImport(keyword);
         } else if (identical(value, 'export')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           directiveState?.checkExport(this, keyword);
           return parseExport(keyword);
         } else if (identical(value, 'typedef')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           directiveState?.checkDeclaration();
           return parseTypedef(keyword);
         } else if (identical(value, 'mixin')) {
+          context.parseMixinModifiers(start, keyword);
           directiveState?.checkDeclaration();
-          return parseMixin(keyword);
+          return parseMixin(context.augmentToken, keyword);
         } else if (identical(value, 'extension')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           directiveState?.checkDeclaration();
           return parseExtension(keyword);
         } else if (identical(value, 'part')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           return parsePartOrPartOf(keyword, directiveState);
         } else if (identical(value, 'library')) {
+          context.parseTopLevelKeywordModifiers(start, keyword);
           directiveState?.checkLibrary(this, keyword);
           return parseLibraryName(keyword);
         }
@@ -715,17 +679,22 @@
     assert(optional('import', importKeyword));
     listener.beginUncategorizedTopLevelDeclaration(importKeyword);
     listener.beginImport(importKeyword);
-    Token token = ensureLiteralString(importKeyword);
+    Token start = importKeyword;
+    Token? augmentToken;
+    if (start.next!.isIdentifier && start.next!.lexeme == 'augment') {
+      start = augmentToken = start.next!;
+    }
+    Token token = ensureLiteralString(start);
     Token uri = token;
     token = parseConditionalUriStar(token);
     token = parseImportPrefixOpt(token);
     token = parseCombinatorStar(token).next!;
     if (optional(';', token)) {
-      listener.endImport(importKeyword, token);
+      listener.endImport(importKeyword, augmentToken, token);
       return token;
     } else {
       // Recovery
-      listener.endImport(importKeyword, /* semicolon = */ null);
+      listener.endImport(importKeyword, augmentToken, /* semicolon = */ null);
       return parseImportRecovery(uri);
     }
   }
@@ -1585,7 +1554,7 @@
 
           if (isModifier(next)) {
             // Recovery
-            ModifierRecoveryContext context = new ModifierRecoveryContext(this)
+            ModifierContext context = new ModifierContext(this)
               ..covariantToken = covariantToken
               ..requiredToken = requiredToken
               ..varFinalOrConst = varFinalOrConst;
@@ -2044,11 +2013,140 @@
     token = computeTypeParamOrArg(
             token, /* inDeclaration = */ true, /* allowsVariance = */ true)
         .parseVariables(token, this);
+    List<String> lookForNext = const ['{', 'with', 'implements'];
+    if (!isOneOf(token.next!, lookForNext)) {
+      // Recovery: Possible unexpected tokens before any clauses.
+      Token? skipToken = recoverySmallLookAheadSkipTokens(token, lookForNext);
+      if (skipToken != null) {
+        token = skipToken;
+      }
+    }
+
+    Token beforeWith = token;
     token = parseEnumWithClauseOpt(token);
+
+    while (!isOneOf(token.next!, const ['{', 'implements'])) {
+      // Recovery: Skip unexpected tokens and more with clauses.
+      // Note that if we find a "with" we've seen one already (otherwise the
+      // parseEnumWithClauseOpt call above would have found this 'with').
+      Token? skipToken = recoveryEnumWith(token,
+              codes.templateMultipleClauses.withArguments("enum", "with")) ??
+          recoverySmallLookAheadSkipTokens(token, lookForNext);
+
+      if (skipToken != null) {
+        // Skipped tokens.
+        token = skipToken;
+      } else {
+        break;
+      }
+    }
+
     token = parseClassOrMixinOrEnumImplementsOpt(token);
+
+    bool? hasWithClauses;
+    while (!optional('{', token.next!)) {
+      if (hasWithClauses == null) {
+        hasWithClauses = optional('with', beforeWith.next!);
+      }
+
+      // Recovery: Skip unexpected tokens and more with/implements clauses.
+      Token? skipToken = recoveryEnumWith(
+          token,
+          hasWithClauses
+              ? codes.templateMultipleClauses.withArguments("enum", "with")
+              : codes.templateOutOfOrderClauses
+                  .withArguments("with", "implements"));
+      if (skipToken != null) {
+        hasWithClauses = true;
+      }
+      if (skipToken == null) {
+        // Note that if we find a "implements" we've seen one already (otherwise
+        // the parseClassOrMixinOrEnumImplementsOpt call above would have found
+        // this 'implements').
+        skipToken = recoveryEnumImplements(token,
+            codes.templateMultipleClauses.withArguments("enum", "implements"));
+      }
+      if (skipToken == null) {
+        skipToken = recoverySmallLookAheadSkipTokens(token, lookForNext);
+      }
+
+      if (skipToken != null) {
+        // Skipped tokens.
+        token = skipToken;
+      } else {
+        break;
+      }
+    }
+
     return token;
   }
 
+  Token? recoveryEnumWith(Token token, codes.Message message) {
+    if (optional('with', token.next!)) {
+      reportRecoverableError(token.next!, message);
+      Listener originalListener = listener;
+      listener = new NullListener();
+      token = parseEnumWithClauseOpt(token);
+      listener = originalListener;
+      return token;
+    }
+    return null;
+  }
+
+  Token? recoveryEnumImplements(Token token, codes.Message message) {
+    if (optional('implements', token.next!)) {
+      reportRecoverableError(token.next!, message);
+      Listener originalListener = listener;
+      listener = new NullListener();
+      token = parseClassOrMixinOrEnumImplementsOpt(token);
+      listener = originalListener;
+      return token;
+    }
+    return null;
+  }
+
+  /// Allow a small lookahead (currently up to 3 tokens) trying to find any in
+  /// [lookFor].
+  ///
+  /// If any wanted token is found an error is issued about unexpected tokens,
+  /// and the last skipped token is returned.
+  /// Otherwise null is returned.
+  Token? recoverySmallLookAheadSkipTokens(
+      final Token token, Iterable<String> lookFor) {
+    // Recovery: Allow a small lookahead for '{'. E.g. the user might be in
+    // the middle of writing 'with' or 'implements'.
+    Token skipToken = token.next!;
+    bool foundWanted = false;
+
+    if (looksLikeStartOfNextTopLevelDeclaration(skipToken)) return null;
+
+    int skipped = 0;
+    while (skipped < 3) {
+      skipped++;
+      if (isOneOf(skipToken.next!, lookFor)) {
+        foundWanted = true;
+        break;
+      }
+
+      skipToken = skipToken.next!;
+      if (looksLikeStartOfNextTopLevelDeclaration(skipToken)) return null;
+    }
+
+    if (foundWanted) {
+      // Give error and skip the tokens.
+      if (skipped == 1) {
+        reportRecoverableError(
+            skipToken, codes.templateUnexpectedToken.withArguments(skipToken));
+      } else {
+        reportRecoverableErrorWithEnd(
+            token.next!, skipToken, codes.messageUnexpectedTokens);
+      }
+      return skipToken;
+    }
+
+    return null;
+  }
+
   Token parseEnumElement(Token token) {
     Token beginToken = token;
     token = parseMetadataStar(token);
@@ -2065,8 +2163,8 @@
     return token;
   }
 
-  Token parseClassOrNamedMixinApplication(
-      Token? abstractToken, Token? macroToken, Token classKeyword) {
+  Token parseClassOrNamedMixinApplication(Token? abstractToken,
+      Token? macroToken, Token? augmentToken, Token classKeyword) {
     assert(optional('class', classKeyword));
     Token begin = abstractToken ?? classKeyword;
     listener.beginClassOrMixinOrNamedMixinApplicationPrelude(begin);
@@ -2077,10 +2175,11 @@
         .parseVariables(name, this);
     if (optional('=', token.next!)) {
       listener.beginNamedMixinApplication(
-          begin, abstractToken, macroToken, name);
+          begin, abstractToken, macroToken, augmentToken, name);
       return parseNamedMixinApplication(token, begin, classKeyword);
     } else {
-      listener.beginClassDeclaration(begin, abstractToken, macroToken, name);
+      listener.beginClassDeclaration(
+          begin, abstractToken, macroToken, augmentToken, name);
       return parseClass(token, begin, classKeyword, name.lexeme);
     }
   }
@@ -2294,11 +2393,11 @@
   ///
   /// ```
   /// mixinDeclaration:
-  ///   metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
+  ///   metadata? 'augment'? 'mixin' [SimpleIdentifier] [TypeParameterList]?
   ///        [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
   /// ;
   /// ```
-  Token parseMixin(Token mixinKeyword) {
+  Token parseMixin(Token? augmentToken, Token mixinKeyword) {
     assert(optional('mixin', mixinKeyword));
     listener.beginClassOrMixinOrNamedMixinApplicationPrelude(mixinKeyword);
     Token name = ensureIdentifier(
@@ -2306,7 +2405,7 @@
     Token headerStart = computeTypeParamOrArg(
             name, /* inDeclaration = */ true, /* allowsVariance = */ true)
         .parseVariables(name, this);
-    listener.beginMixinDeclaration(mixinKeyword, name);
+    listener.beginMixinDeclaration(augmentToken, mixinKeyword, name);
     Token token = parseMixinHeaderOpt(headerStart, mixinKeyword);
     if (!optional('{', token.next!)) {
       // Recovery
@@ -2745,6 +2844,7 @@
     }
 
     Token? externalToken;
+    Token? augmentToken;
     Token? lateToken;
     Token? varFinalOrConst;
 
@@ -2752,6 +2852,9 @@
       if (optional('external', next)) {
         externalToken = token = next;
         next = token.next!;
+      } else if (optional('augment', next)) {
+        augmentToken = token = next;
+        next = token.next!;
       }
       if (isModifier(next)) {
         if (optional('final', next)) {
@@ -2780,14 +2883,16 @@
             // If another `var`, `final`, or `const` then fall through
             // to parse that as part of the next top level declaration.
           } else {
-            ModifierRecoveryContext context = new ModifierRecoveryContext(this)
+            ModifierContext context = new ModifierContext(this)
               ..externalToken = externalToken
+              ..augmentToken = augmentToken
               ..lateToken = lateToken
               ..varFinalOrConst = varFinalOrConst;
 
-            token = context.parseTopLevelModifiers(token);
+            token = context.parseTopLevelMemberModifiers(token);
             next = token.next!;
 
+            augmentToken = context.augmentToken;
             externalToken = context.externalToken;
             lateToken = context.lateToken;
             varFinalOrConst = context.varFinalOrConst;
@@ -2912,8 +3017,8 @@
         reportRecoverableErrorWithToken(
             lateToken, codes.templateExtraneousModifier);
       }
-      return parseTopLevelMethod(beforeStart, externalToken, beforeType,
-          typeInfo, getOrSet, token.next!, nameIsRecovered);
+      return parseTopLevelMethod(beforeStart, augmentToken, externalToken,
+          beforeType, typeInfo, getOrSet, token.next!, nameIsRecovered);
     }
 
     if (getOrSet != null) {
@@ -2923,6 +3028,7 @@
     return parseFields(
         beforeStart,
         /* abstractToken = */ null,
+        augmentToken,
         externalToken,
         /* staticToken = */ null,
         /* covariantToken = */ null,
@@ -2939,6 +3045,7 @@
   Token parseFields(
       Token beforeStart,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -2950,8 +3057,8 @@
       DeclarationKind kind,
       String? enclosingDeclarationName,
       bool nameIsRecovered) {
-    listener.beginFields(kind, abstractToken, externalToken, staticToken,
-        covariantToken, lateToken, varFinalOrConst, beforeStart);
+    listener.beginFields(kind, abstractToken, augmentToken, externalToken,
+        staticToken, covariantToken, lateToken, varFinalOrConst, beforeStart);
 
     // Covariant affects only the setter and final fields do not have a setter,
     // unless it's a late field (dartbug.com/40805).
@@ -2998,12 +3105,28 @@
     }
 
     int fieldCount = 1;
-    token = parseFieldInitializerOpt(name, name, lateToken, abstractToken,
-        externalToken, varFinalOrConst, kind, enclosingDeclarationName);
+    token = parseFieldInitializerOpt(
+        name,
+        name,
+        lateToken,
+        abstractToken,
+        augmentToken,
+        externalToken,
+        varFinalOrConst,
+        kind,
+        enclosingDeclarationName);
     while (optional(',', token.next!)) {
       name = ensureIdentifier(token.next!, context);
-      token = parseFieldInitializerOpt(name, name, lateToken, abstractToken,
-          externalToken, varFinalOrConst, kind, enclosingDeclarationName);
+      token = parseFieldInitializerOpt(
+          name,
+          name,
+          lateToken,
+          abstractToken,
+          augmentToken,
+          externalToken,
+          varFinalOrConst,
+          kind,
+          enclosingDeclarationName);
       ++fieldCount;
     }
     Token semicolon = token.next!;
@@ -3036,6 +3159,7 @@
       case DeclarationKind.Class:
         listener.endClassFields(
             abstractToken,
+            augmentToken,
             externalToken,
             staticToken,
             covariantToken,
@@ -3048,6 +3172,7 @@
       case DeclarationKind.Mixin:
         listener.endMixinFields(
             abstractToken,
+            augmentToken,
             externalToken,
             staticToken,
             covariantToken,
@@ -3068,6 +3193,7 @@
         }
         listener.endExtensionFields(
             abstractToken,
+            augmentToken,
             externalToken,
             staticToken,
             covariantToken,
@@ -3080,6 +3206,7 @@
       case DeclarationKind.Enum:
         listener.endEnumFields(
             abstractToken,
+            augmentToken,
             externalToken,
             staticToken,
             covariantToken,
@@ -3095,13 +3222,14 @@
 
   Token parseTopLevelMethod(
       Token beforeStart,
+      Token? augmentToken,
       Token? externalToken,
       Token beforeType,
       TypeInfo typeInfo,
       Token? getOrSet,
       Token name,
       bool nameIsRecovered) {
-    listener.beginTopLevelMethod(beforeStart, externalToken);
+    listener.beginTopLevelMethod(beforeStart, augmentToken, externalToken);
 
     Token token = typeInfo.parseType(beforeType, this);
     assert(token.next == (getOrSet ?? name) || token.next!.isEof);
@@ -3178,6 +3306,7 @@
       Token name,
       Token? lateToken,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? varFinalOrConst,
       DeclarationKind kind,
@@ -3262,26 +3391,22 @@
           if (!optional('(', next)) {
             break;
           }
-          // Looks like assert expression ... fall through to insert comma
-        } else if (!next.isIdentifier && !optional('this', next)) {
-          // An identifier that wasn't an initializer. Break.
-          break;
-        } else {
-          if (optional('this', next)) {
-            next = next.next!;
-            if (!optional('.', next)) {
-              break;
-            }
-            next = next.next!;
-            if (!next.isIdentifier && !optional('assert', next)) {
-              break;
-            }
+          // Looks like assert expression ... fall through to insert comma.
+        } else if (optional('this', next) || optional('super', next)) {
+          next = next.next!;
+          if (!optional('(', next) && !optional('.', next)) {
+            break;
           }
+          // `this` or `super` followed by either `.` or `(`.
+          // Fall through to insert comma.
+        } else if (next.isIdentifier) {
           next = next.next!;
           if (!optional('=', next)) {
             break;
           }
-          // Looks like field assignment... fall through to insert comma
+          // Looks like field assignment... fall through to insert comma.
+        } else {
+          break;
         }
         // TODO(danrubel): Consider enhancing this to indicate that we are
         // expecting one of `,` or `;` or `{`
@@ -3737,6 +3862,7 @@
 
     Token? covariantToken;
     Token? abstractToken;
+    Token? augmentToken;
     Token? externalToken;
     Token? lateToken;
     Token? staticToken;
@@ -3747,6 +3873,9 @@
       if (optional('external', next)) {
         externalToken = token = next;
         next = token.next!;
+      } else if (optional('augment', next)) {
+        augmentToken = token = next;
+        next = token.next!;
       } else if (optional('abstract', next)) {
         abstractToken = token = next;
         next = token.next!;
@@ -3778,8 +3907,9 @@
             }
           }
           if (isModifier(next)) {
-            ModifierRecoveryContext context = new ModifierRecoveryContext(this)
+            ModifierContext context = new ModifierContext(this)
               ..covariantToken = covariantToken
+              ..augmentToken = augmentToken
               ..externalToken = externalToken
               ..lateToken = lateToken
               ..staticToken = staticToken
@@ -3859,6 +3989,7 @@
           token = parseMethod(
               beforeStart,
               abstractToken,
+              augmentToken,
               externalToken,
               staticToken,
               covariantToken,
@@ -3882,6 +4013,7 @@
           return parseInvalidOperatorDeclaration(
               beforeStart,
               abstractToken,
+              augmentToken,
               externalToken,
               staticToken,
               covariantToken,
@@ -3895,6 +4027,7 @@
           token = parseMethod(
               beforeStart,
               abstractToken,
+              augmentToken,
               externalToken,
               staticToken,
               covariantToken,
@@ -3924,6 +4057,7 @@
             token,
             beforeStart,
             abstractToken,
+            augmentToken,
             externalToken,
             staticToken,
             covariantToken,
@@ -3946,6 +4080,7 @@
           return parseInvalidOperatorDeclaration(
               beforeStart,
               abstractToken,
+              augmentToken,
               externalToken,
               staticToken,
               covariantToken,
@@ -3981,6 +4116,7 @@
       token = parseMethod(
           beforeStart,
           abstractToken,
+          augmentToken,
           externalToken,
           staticToken,
           covariantToken,
@@ -4001,6 +4137,7 @@
       token = parseFields(
           beforeStart,
           abstractToken,
+          augmentToken,
           externalToken,
           staticToken,
           covariantToken,
@@ -4020,6 +4157,7 @@
   Token parseMethod(
       Token beforeStart,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -4093,8 +4231,8 @@
 
     // TODO(danrubel): Consider parsing the name before calling beginMethod
     // rather than passing the name token into beginMethod.
-    listener.beginMethod(kind, externalToken, staticToken, covariantToken,
-        varFinalOrConst, getOrSet, name);
+    listener.beginMethod(kind, augmentToken, externalToken, staticToken,
+        covariantToken, varFinalOrConst, getOrSet, name);
 
     Token token = typeInfo.parseType(beforeType, this);
     assert(token.next == (getOrSet ?? name) ||
@@ -4294,7 +4432,7 @@
 
     if (!isValidTypeReference(token.next!)) {
       // Recovery
-      ModifierRecoveryContext context = new ModifierRecoveryContext(this)
+      ModifierContext context = new ModifierContext(this)
         ..externalToken = externalToken
         ..staticOrCovariant = staticOrCovariant
         ..varFinalOrConst = varFinalOrConst;
@@ -6786,7 +6924,7 @@
 
       if (isModifier(next)) {
         // Recovery
-        ModifierRecoveryContext context = new ModifierRecoveryContext(this)
+        ModifierContext context = new ModifierContext(this)
           ..lateToken = lateToken
           ..varFinalOrConst = varFinalOrConst;
 
@@ -6827,7 +6965,7 @@
       beforeType = start = beforeType.next!;
 
       // The below doesn't parse modifiers, so we need to do it here.
-      ModifierRecoveryContext context = new ModifierRecoveryContext(this);
+      ModifierContext context = new ModifierContext(this);
       beforeType =
           start = context.parseVariableDeclarationModifiers(beforeType);
       varFinalOrConst = context.varFinalOrConst;
@@ -6874,7 +7012,7 @@
         typeInfo.couldBeExpression) {
       assert(optional('?', token));
       assert(next.isKeywordOrIdentifier);
-      if (!next.isIdentifier) {
+      if (!looksLikeName(next)) {
         reportRecoverableError(
             next, codes.templateExpectedIdentifier.withArguments(next));
         next = rewriter.insertSyntheticIdentifier(next);
@@ -7488,19 +7626,33 @@
 
     String? value = token.stringValue;
     while (identical(value, 'catch') || identical(value, 'on')) {
-      listener.beginCatchClause(token);
+      bool didBeginCatchClause = false;
       Token? onKeyword = null;
       if (identical(value, 'on')) {
         // 'on' type catchPart?
         onKeyword = token;
-        lastConsumed = computeType(token, /* required = */ true)
-            .ensureTypeNotVoid(token, this);
+        TypeInfo typeInfo = computeType(token, /* required = */ true);
+        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
+          // some actual catch/on as that could be a valid method call, local
+          // function, assignment etc.
+          break;
+        }
+        listener.beginCatchClause(token);
+        didBeginCatchClause = true;
+        lastConsumed = typeInfo.ensureTypeNotVoid(token, this);
         token = lastConsumed.next!;
         value = token.stringValue;
       }
       Token? catchKeyword = null;
       Token? comma = null;
       if (identical(value, 'catch')) {
+        if (!didBeginCatchClause) {
+          listener.beginCatchClause(token);
+          didBeginCatchClause = true;
+        }
         catchKeyword = token;
 
         Token openParens = catchKeyword.next!;
@@ -7895,6 +8047,7 @@
   Token parseInvalidOperatorDeclaration(
       Token beforeStart,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -7943,6 +8096,7 @@
     Token token = parseMethod(
         beforeStart,
         abstractToken,
+        augmentToken,
         externalToken,
         staticToken,
         covariantToken,
@@ -7966,6 +8120,7 @@
       Token token,
       Token beforeStart,
       Token? abstractToken,
+      Token? augmentToken,
       Token? externalToken,
       Token? staticToken,
       Token? covariantToken,
@@ -7989,6 +8144,7 @@
       return parseInvalidOperatorDeclaration(
           beforeStart,
           abstractToken,
+          augmentToken,
           externalToken,
           staticToken,
           covariantToken,
@@ -8006,6 +8162,7 @@
       token = parseMethod(
           beforeStart,
           abstractToken,
+          augmentToken,
           externalToken,
           staticToken,
           covariantToken,
@@ -8030,6 +8187,7 @@
       token = parseFields(
           beforeStart,
           abstractToken,
+          augmentToken,
           externalToken,
           staticToken,
           covariantToken,
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 fbc3ab3..4f5ad4e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -42,6 +42,7 @@
   ContinueTarget,
   Deferred,
   DocumentationComment,
+  EnumConstantInfo,
   Expression,
   ExtendsClause,
   FieldInitializer,
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 9e76440..90c69c8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
@@ -252,17 +252,6 @@
   assert(typeParamOrArg == noTypeParamOrArg);
   next = next.next!;
 
-  // TODO(scheglov) This is a hack to partially fix.
-  // https://github.com/dart-lang/sdk/issues/47951
-  if (optional('?', next) &&
-      optional('super', next.next!) &&
-      optional('.', next.next!.next!)) {
-    return simpleNullableType;
-  }
-  if (optional('super', next) && optional('.', next.next!)) {
-    return simpleType;
-  }
-
   if (optional('.', next)) {
     next = next.next!;
     if (isValidTypeReference(next)) {
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 099319f..07d1752 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
@@ -451,6 +451,7 @@
 bool looksLikeName(Token token) {
   return token.kind == IDENTIFIER_TOKEN ||
       optional('this', token) ||
+      optional('super', token) ||
       (token.isIdentifier &&
           // Although `typedef` is a legal identifier,
           // type `typedef` identifier is not legal and in this situation
@@ -794,7 +795,9 @@
         if (optional('?', next)) {
           next = next.next!;
         }
-        if (!(next.isIdentifier || optional('this', next))) {
+        if (!(next.isIdentifier ||
+            optional('this', next) ||
+            optional('super', next))) {
           break; // `Function` used as the name in a function declaration.
         }
       }
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index 7f70b75..8c6a343 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -73,6 +73,9 @@
   /// and https://github.com/dart-lang/language/issues/60
   bool _enableTripleShift = false;
 
+  /// If `true`, 'augment' is treated as a built-in identifier.
+  bool _forAugmentationLibrary = false;
+
   /**
    * The string offset for the next token that will be created.
    *
@@ -159,6 +162,7 @@
       _enableExtensionMethods = config.enableExtensionMethods;
       _enableNonNullable = config.enableNonNullable;
       _enableTripleShift = config.enableTripleShift;
+      _forAugmentationLibrary = config.forAugmentationLibrary;
     }
   }
 
@@ -1619,6 +1623,9 @@
         (keyword == Keyword.LATE || keyword == Keyword.REQUIRED)) {
       return tokenizeIdentifier(next, start, allowDollar);
     }
+    if (!_forAugmentationLibrary && keyword == Keyword.AUGMENT) {
+      return tokenizeIdentifier(next, start, allowDollar);
+    }
     if (($A <= next && next <= $Z) ||
         ($0 <= next && next <= $9) ||
         identical(next, $_) ||
@@ -2055,13 +2062,18 @@
   /// and https://github.com/dart-lang/language/issues/60
   final bool enableTripleShift;
 
+  /// If `true`, 'augment' is treated as a built-in identifier.
+  final bool forAugmentationLibrary;
+
   const ScannerConfiguration({
     bool enableExtensionMethods = false,
     bool enableNonNullable = false,
     bool enableTripleShift = false,
+    bool forAugmentationLibrary = false,
   })  : this.enableExtensionMethods = enableExtensionMethods,
         this.enableNonNullable = enableNonNullable,
-        this.enableTripleShift = enableTripleShift;
+        this.enableTripleShift = enableTripleShift,
+        this.forAugmentationLibrary = forAugmentationLibrary;
 }
 
 bool _isIdentifierChar(int next, bool allowDollar) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
index 63fd51c..35a6386 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
@@ -72,7 +72,7 @@
     bool includeComments: false,
     LanguageVersionChanged? languageVersionChanged}) {
   if (bytes.last != 0) {
-    throw new ArgumentError("[bytes]: the last byte must be null.");
+    throw new ArgumentError("[bytes]: the last byte must be 0.");
   }
   Scanner scanner = new Utf8BytesScanner(bytes,
       configuration: configuration,
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index 0a6ab6c..d4225fb 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -144,6 +144,10 @@
   static const Keyword ASYNC =
       const Keyword("async", "ASYNC", KeywordStyle.pseudo);
 
+  static const Keyword AUGMENT = const Keyword(
+      "augment", "AUGMENT", KeywordStyle.builtIn,
+      isModifier: true);
+
   static const Keyword AWAIT =
       const Keyword("await", "AWAIT", KeywordStyle.pseudo);
 
@@ -345,6 +349,7 @@
     AS,
     ASSERT,
     ASYNC,
+    AUGMENT,
     AWAIT,
     BREAK,
     CASE,
@@ -734,6 +739,9 @@
       : super(type, offset, precedingComment);
 
   @override
+  Token? beforeSynthetic;
+
+  @override
   Token copy() =>
       new SyntheticBeginToken(type, offset, copyComments(precedingComments));
 
@@ -755,6 +763,9 @@
   SyntheticKeywordToken(Keyword keyword, int offset) : super(keyword, offset);
 
   @override
+  Token? beforeSynthetic;
+
+  @override
   int get length => 0;
 
   @override
@@ -1085,7 +1096,8 @@
    * Return the token with the smallest offset, or `null` if all of the
    * tokens are `null`.
    */
-  static Token? lexicallyFirst([Token? t1, Token? t2, Token? t3, Token? t4]) {
+  static Token? lexicallyFirst(
+      [Token? t1, Token? t2, Token? t3, Token? t4, Token? t5]) {
     Token? result = t1;
     if (result == null || t2 != null && t2.offset < result.offset) {
       result = t2;
@@ -1096,6 +1108,9 @@
     if (result == null || t4 != null && t4.offset < result.offset) {
       result = t4;
     }
+    if (result == null || t5 != null && t5.offset < result.offset) {
+      result = t5;
+    }
     return result;
   }
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
index 896c670..a1bbadb 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
@@ -65,13 +65,13 @@
     Map<Id, Map<String, IdValue>> idValuePerId = idValuePerUri[uri] ?? {};
     Map<Id, Map<String, ActualData<T>>> actualDataPerId =
         actualDataPerUri[uri] ?? {};
-    AnnotatedCode code = annotatedCode[uri]!;
-    assert(
-        // ignore: unnecessary_null_comparison
-        code != null, "No annotated code for ${uri} in ${annotatedCode.keys}");
-    result[uri] = _computeAnnotations(code, expectedMaps.keys, actualMarkers,
+    AnnotatedCode? code = annotatedCode[uri];
+    if (code != null) {
+      // Annotations are not computed from synthesized code.
+      result[uri] = _computeAnnotations(code, expectedMaps.keys, actualMarkers,
         idValuePerId, actualDataPerId, dataInterpreter,
         sortMarkers: false, createDiff: createDiff, forceUpdate: forceUpdate);
+    }
   }
   return result;
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
index 68ad3ab..f29fc9f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -771,7 +771,9 @@
   List<FileSystemEntity> entities = dataDir
       .listSync()
       .where((entity) =>
-          !entity.path.endsWith('~') && !entity.path.endsWith('marker.options'))
+          !entity.path.endsWith('~') &&
+          !entity.path.endsWith('marker.options') &&
+          !entity.path.endsWith('.expect'))
       .toList();
   if (shards > 1) {
     entities.sort((a, b) => getTestName(a).compareTo(getTestName(b)));
@@ -842,9 +844,11 @@
               actualData[marker] = {};
 
           void addActualData(Uri uri, Map<Id, ActualData<T>> actualData) {
-            // ignore: unnecessary_null_comparison
-            assert(uri != null && testData.code.containsKey(uri) ||
-                actualData.isEmpty);
+            assert(
+                // ignore: unnecessary_null_comparison
+                uri != null && testData.code.containsKey(uri) ||
+                    actualData.isEmpty,
+                "Unexpected data ${actualData} for $uri");
             // ignore: unnecessary_null_comparison
             if (uri == null || actualData.isEmpty) {
               // TODO(johnniwinther): Avoid collecting data without
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
index 4e453145..a25f8e8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
@@ -238,7 +238,7 @@
               _reportError(messageIncludePathIsNotAString(targetName, specUri));
             }
             Uri uri = Uri.parse(path);
-            if (uri.scheme != '' && uri.scheme != 'file') {
+            if (uri.hasScheme && !uri.isScheme('file')) {
               return _reportError(messageUnsupportedUriScheme(path, specUri));
             }
             LibrariesSpecification specification =
@@ -269,7 +269,7 @@
                 uriString, libraryName, targetName, specUri));
           }
           Uri uri = Uri.parse(uriString);
-          if (uri.scheme != '' && uri.scheme != 'file') {
+          if (uri.hasScheme && !uri.isScheme('file')) {
             return _reportError(
                 messageUnsupportedUriScheme(uriString, specUri));
           }
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart b/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
index 2600d6d..39ce9d4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
@@ -18,7 +18,7 @@
 
 Uri parseUri(String path) {
   if (path.startsWith("file:")) {
-    if (Uri.base.scheme == "file") {
+    if (Uri.base.isScheme("file")) {
       // The Uri class doesn't handle relative file URIs correctly, the
       // following works around that issue.
       return new Uri(path: Uri.parse("x-$path").path);
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index cfc2267..e4718a0 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 34.0.0
+version: 36.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
new file mode 100644
index 0000000..5a96c10
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.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.
+
+import 'api_test_macro.dart';
+
+main() {}
+
+var field;
+get getter => null;
+set setter(_) => null;
+
+@ClassMacro()
+class Class1 {}
+
+@ClassMacro()
+abstract class Class2 {}
+
+@ClassMacro()
+class Class3 extends Class2 {}
+
+mixin Mixin {}
+
+@ClassMacro()
+class Class4 extends Class1 with Mixin {}
+
+@FunctionMacro()
+void topLevelFunction1(Class1 a, {Class1? b, required Class2? c}) {}
+
+@FunctionMacro()
+external Class2 topLevelFunction2(Class1 a, [Class2? b]);
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
new file mode 100644
index 0000000..c826563
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
@@ -0,0 +1,220 @@
+// 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/macros/api.dart';
+
+const Map<String, ClassData> expectedClassData = {
+  'Class1': ClassData(superclassOf: 'Object'),
+  'Class2': ClassData(isAbstract: true, superclassOf: 'Object'),
+  'Class3': ClassData(superclassOf: 'Class2', superSuperclassOf: 'Object'),
+  'Class4': ClassData(superclassOf: 'Class1', superSuperclassOf: 'Object'),
+};
+
+const Map<String, FunctionData> expectedFunctionData = {
+  'topLevelFunction1': FunctionData(
+      returnType: NamedTypeData(name: 'void'),
+      positionalParameters: [
+        ParameterData('a',
+            type: NamedTypeData(name: 'Class1'), isRequired: true),
+      ],
+      namedParameters: [
+        ParameterData('b',
+            type: NamedTypeData(name: 'Class1', isNullable: true),
+            isNamed: true,
+            isRequired: false),
+        ParameterData('c',
+            type: NamedTypeData(name: 'Class2', isNullable: true),
+            isNamed: true,
+            isRequired: true),
+      ]),
+  'topLevelFunction2': FunctionData(
+    isExternal: true,
+    returnType: NamedTypeData(name: 'Class2'),
+    positionalParameters: [
+      ParameterData('a', type: NamedTypeData(name: 'Class1'), isRequired: true),
+      ParameterData('b', type: NamedTypeData(name: 'Class2', isNullable: true)),
+    ],
+  ),
+};
+
+expect(expected, actual, property) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual on $property';
+  }
+}
+
+Future<void> throws(Future<void> Function() f, property) async {
+  try {
+    await f();
+  } catch (_) {
+    return;
+  }
+  throw 'Expected throws on $property';
+}
+
+void checkTypeAnnotation(
+    TypeData expected, TypeAnnotation typeAnnotation, String context) {
+  expect(expected.isNullable, typeAnnotation.isNullable, '$context.isNullable');
+  expect(expected is NamedTypeData, typeAnnotation is NamedTypeAnnotation,
+      '$context is NamedTypeAnnotation');
+  if (expected is NamedTypeData && typeAnnotation is NamedTypeAnnotation) {
+    expect(expected.name, typeAnnotation.identifier.name, '$context.name');
+    // TODO(johnniwinther): Test more properties.
+  }
+}
+
+void checkParameterDeclaration(
+    ParameterData expected, ParameterDeclaration declaration, String context) {
+  expect(expected.name, declaration.identifier.name, '$context.identifer.name');
+  expect(expected.isNamed, declaration.isNamed, '$context.isNamed');
+  expect(expected.isRequired, declaration.isRequired, '$context.isRequired');
+  checkTypeAnnotation(expected.type, declaration.type, '$context.type');
+}
+
+Future<void> checkClassDeclaration(ClassDeclaration declaration,
+    {ClassIntrospector? classIntrospector}) async {
+  String name = declaration.identifier.name;
+  ClassData? expected = expectedClassData[name];
+  if (expected != null) {
+    expect(expected.isAbstract, declaration.isAbstract, '$name.isAbstract');
+    expect(expected.isExternal, declaration.isExternal, '$name.isExternal');
+    if (classIntrospector != null) {
+      ClassDeclaration? superclassOf =
+          await classIntrospector.superclassOf(declaration);
+      expect(expected.superclassOf, superclassOf?.identifier.name,
+          '$name.superclassOf');
+      if (superclassOf != null) {
+        ClassDeclaration? superSuperclassOf =
+            await classIntrospector.superclassOf(superclassOf);
+        expect(expected.superSuperclassOf, superSuperclassOf?.identifier.name,
+            '$name.superSuperclassOf');
+      }
+    }
+    // TODO(johnniwinther): Test more properties when there are supported.
+  } else {
+    throw 'Unexpected class declaration "${name}"';
+  }
+}
+
+void checkFunctionDeclaration(FunctionDeclaration actual) {
+  String name = actual.identifier.name;
+  FunctionData? expected = expectedFunctionData[name];
+  if (expected != null) {
+    expect(expected.isAbstract, actual.isAbstract, '$name.isAbstract');
+    expect(expected.isExternal, actual.isExternal, '$name.isExternal');
+    expect(expected.isOperator, actual.isOperator, '$name.isOperator');
+    expect(expected.isGetter, actual.isGetter, '$name.isGetter');
+    expect(expected.isSetter, actual.isSetter, '$name.isSetter');
+    checkTypeAnnotation(
+        expected.returnType, actual.returnType, '$name.returnType');
+    expect(
+        expected.positionalParameters.length,
+        actual.positionalParameters.length,
+        '$name.positionalParameters.length');
+    for (int i = 0; i < expected.positionalParameters.length; i++) {
+      checkParameterDeclaration(
+          expected.positionalParameters[i],
+          actual.positionalParameters.elementAt(i),
+          '$name.positionalParameters[$i]');
+    }
+    expect(expected.namedParameters.length, actual.namedParameters.length,
+        '$name.namedParameters.length');
+    for (int i = 0; i < expected.namedParameters.length; i++) {
+      checkParameterDeclaration(expected.namedParameters[i],
+          actual.namedParameters.elementAt(i), '$name.namedParameters[$i]');
+    }
+    // TODO(johnniwinther): Test more properties.
+  } else {
+    throw 'Unexpected function declaration "${name}"';
+  }
+}
+
+Future<void> checkIdentifierResolver(
+    IdentifierResolver identifierResolver) async {
+  Uri dartCore = Uri.parse('dart:core');
+  Uri macroApiData = Uri.parse('package:macro_api_test/api_test_data.dart');
+
+  Future<void> check(Uri uri, String name, {bool expectThrows: false}) async {
+    if (expectThrows) {
+      await throws(() async {
+        await identifierResolver.resolveIdentifier(uri, name);
+      }, '$name from $uri');
+    } else {
+      Identifier result = await identifierResolver.resolveIdentifier(uri, name);
+      expect(name, result.name, '$name from $uri');
+    }
+  }
+
+  await check(dartCore, 'Object');
+  await check(dartCore, 'String');
+  await check(dartCore, 'override');
+
+  await check(macroApiData, 'Class1');
+  await check(macroApiData, 'getter');
+  await check(macroApiData, 'setter=');
+  await check(macroApiData, 'field');
+
+  await check(macroApiData, 'non-existing', expectThrows: true);
+  await check(macroApiData, 'getter=', expectThrows: true);
+  await check(macroApiData, 'setter', expectThrows: true);
+  await check(macroApiData, 'field=', expectThrows: true);
+}
+
+class ClassData {
+  final bool isAbstract;
+  final bool isExternal;
+  final String superclassOf;
+  final String? superSuperclassOf;
+
+  const ClassData(
+      {this.isAbstract: false,
+      this.isExternal: false,
+      required this.superclassOf,
+      this.superSuperclassOf});
+}
+
+class FunctionData {
+  final bool isAbstract;
+  final bool isExternal;
+  final bool isOperator;
+  final bool isGetter;
+  final bool isSetter;
+  final TypeData returnType;
+  final List<ParameterData> positionalParameters;
+  final List<ParameterData> namedParameters;
+
+  const FunctionData(
+      {this.isAbstract: false,
+      this.isExternal: false,
+      this.isOperator: false,
+      this.isGetter: false,
+      this.isSetter: false,
+      required this.returnType,
+      this.positionalParameters: const [],
+      this.namedParameters: const []});
+}
+
+class TypeData {
+  final bool isNullable;
+
+  const TypeData({this.isNullable: false});
+}
+
+class NamedTypeData extends TypeData {
+  final String? name;
+  final List<TypeData>? typeArguments;
+
+  const NamedTypeData({bool isNullable: false, this.name, this.typeArguments})
+      : super(isNullable: isNullable);
+}
+
+class ParameterData {
+  final String name;
+  final TypeData type;
+  final bool isRequired;
+  final bool isNamed;
+
+  const ParameterData(this.name,
+      {required this.type, this.isNamed: false, this.isRequired: false});
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart
new file mode 100644
index 0000000..d54db3b
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart
@@ -0,0 +1,55 @@
+// 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:_fe_analyzer_shared/src/macros/api.dart';
+import 'api_test_expectations.dart';
+
+
+
+macro class ClassMacro
+    implements ClassTypesMacro, ClassDeclarationsMacro, ClassDefinitionMacro {
+  const ClassMacro();
+
+  FutureOr<void> buildTypesForClass(
+      ClassDeclaration clazz, TypeBuilder builder) async {
+    await checkClassDeclaration(clazz);
+  }
+
+  FutureOr<void> buildDeclarationsForClass(
+      ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
+    await checkClassDeclaration(clazz, classIntrospector: builder);
+  }
+
+  FutureOr<void> buildDefinitionForClass(
+      ClassDeclaration clazz, ClassDefinitionBuilder builder) async {
+    await checkClassDeclaration(clazz, classIntrospector: builder);
+  }
+}
+
+macro class FunctionMacro
+    implements
+        FunctionTypesMacro,
+        FunctionDeclarationsMacro,
+        FunctionDefinitionMacro {
+  const FunctionMacro();
+
+  FutureOr<void> buildTypesForFunction(
+      FunctionDeclaration function, TypeBuilder builder) async {
+    checkFunctionDeclaration(function);
+    await checkIdentifierResolver(builder);
+  }
+
+  FutureOr<void> buildDeclarationsForFunction(
+      FunctionDeclaration function, DeclarationBuilder builder) async {
+    checkFunctionDeclaration(function);
+    await checkIdentifierResolver(builder);
+  }
+
+  FutureOr<void> buildDefinitionForFunction(
+      FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+    checkFunctionDeclaration(function);
+    await checkIdentifierResolver(builder);
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/package_config.json b/pkg/_fe_analyzer_shared/test/macros/api/package_config.json
new file mode 100644
index 0000000..8fa0595
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/api/package_config.json
@@ -0,0 +1,18 @@
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "macro_api_test",
+      "rootUri": "../../../../_fe_analyzer_shared/test/macros/api/"
+    },
+    {
+      "name": "meta",
+      "rootUri": "../../../../meta/",
+      "packageUri": "lib/"
+    },
+    {
+      "name": "_fe_analyzer_shared",
+      "rootUri": "../../../../_fe_analyzer_shared/lib/"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor/augmentation_library_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor/augmentation_library_test.dart
new file mode 100644
index 0000000..af3d9d7
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/executor/augmentation_library_test.dart
@@ -0,0 +1,150 @@
+// 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/macros/executor/remote_instance.dart';
+import 'package:test/fake.dart';
+import 'package:test/test.dart';
+
+import 'package:_fe_analyzer_shared/src/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/augmentation_library.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/response_impls.dart';
+
+import '../util.dart';
+
+void main() {
+  group('AugmentationLibraryBuilder', () {
+    test('can combine multiple execution results', () {
+      var results = [
+        for (var i = 0; i < 2; i++)
+          MacroExecutionResultImpl(classAugmentations: {
+            for (var j = 0; j < 3; j++)
+              'Foo$i$j': [
+                DeclarationCode.fromString('int get i => $i;\n'),
+                DeclarationCode.fromString('int get j => $j;\n'),
+              ]
+          }, libraryAugmentations: [
+            for (var j = 0; j < 3; j++)
+              DeclarationCode.fromString('int get i${i}j$j => ${i + j};\n'),
+          ], newTypeNames: [
+            'Foo${i}0',
+            'Foo${i}1',
+            'Foo${i}2',
+          ]),
+      ];
+      var library = _TestExecutor().buildAugmentationLibrary(
+          results, (Identifier i) => (i as TestIdentifier).resolved);
+      expect(library, equalsIgnoringWhitespace('''
+        int get i0j0 => 0;
+        int get i0j1 => 1;
+        int get i0j2 => 2;
+        int get i1j0 => 1;
+        int get i1j1 => 2;
+        int get i1j2 => 3;
+        augment class Foo00 {
+          int get i => 0;
+          int get j => 0;
+        }
+        augment class Foo01 {
+          int get i => 0;
+          int get j => 1;
+        }
+        augment class Foo02 {
+          int get i => 0;
+          int get j => 2;
+        }
+        augment class Foo10 {
+          int get i => 1;
+          int get j => 0;
+        }
+        augment class Foo11 {
+          int get i => 1;
+          int get j => 1;
+        }
+        augment class Foo12 {
+          int get i => 1;
+          int get j => 2;
+        }
+      '''));
+    });
+
+    test('can add imports for identifiers', () {
+      var fooIdentifier = TestIdentifier(
+          id: RemoteInstance.uniqueId,
+          name: 'Foo',
+          kind: IdentifierKind.topLevelMember,
+          staticScope: null,
+          uri: Uri.parse('package:foo/foo.dart'));
+      var barIdentifier = TestIdentifier(
+          id: RemoteInstance.uniqueId,
+          name: 'Bar',
+          kind: IdentifierKind.topLevelMember,
+          staticScope: null,
+          uri: Uri.parse('package:bar/bar.dart'));
+      var builderIdentifier = TestIdentifier(
+          id: RemoteInstance.uniqueId,
+          name: 'Builder',
+          kind: IdentifierKind.topLevelMember,
+          staticScope: null,
+          uri: Uri.parse('package:builder/builder.dart'));
+      var barInstanceMember = TestIdentifier(
+          id: RemoteInstance.uniqueId,
+          name: 'baz',
+          kind: IdentifierKind.instanceMember,
+          staticScope: null,
+          uri: Uri.parse('package:bar/bar.dart'));
+      var barStaticMember = TestIdentifier(
+          id: RemoteInstance.uniqueId,
+          name: 'zap',
+          kind: IdentifierKind.staticInstanceMember,
+          staticScope: 'Bar',
+          uri: Uri.parse('package:bar/bar.dart'));
+      var results = [
+        MacroExecutionResultImpl(
+          classAugmentations: {},
+          libraryAugmentations: [
+            DeclarationCode.fromParts([
+              'class FooBuilder<T extends ',
+              fooIdentifier,
+              '> implements ',
+              builderIdentifier,
+              '<',
+              barIdentifier,
+              '<T>> {\n',
+              'late int ${barInstanceMember.name};\n',
+              barIdentifier,
+              '<T> build() => new ',
+              barIdentifier,
+              '()..',
+              barInstanceMember,
+              ' = ',
+              barStaticMember,
+              ';',
+              '\n}',
+            ]),
+          ],
+          newTypeNames: [
+            'FooBuilder',
+          ],
+        )
+      ];
+      var library = _TestExecutor().buildAugmentationLibrary(
+          results, (Identifier i) => (i as TestIdentifier).resolved);
+      expect(library, equalsIgnoringWhitespace('''
+        import 'package:foo/foo.dart' as i0;
+        import 'package:builder/builder.dart' as i1;
+        import 'package:bar/bar.dart' as i2;
+
+        class FooBuilder<T extends i0.Foo> implements i1.Builder<i2.Bar<T>> {
+          late int baz;
+
+          i2.Bar<T> build() => new i2.Bar()..baz = i2.Bar.zap;
+        }
+      '''));
+    });
+  });
+}
+
+class _TestExecutor extends MacroExecutor
+    with AugmentationLibraryBuilder, Fake {}
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
new file mode 100644
index 0000000..13b54ac
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
@@ -0,0 +1,545 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/isolated_executor.dart'
+    as isolatedExecutor;
+import 'package:_fe_analyzer_shared/src/macros/executor/process_executor.dart'
+    as processExecutor;
+
+import 'package:test/test.dart';
+
+import '../util.dart';
+
+void main() {
+  late MacroExecutor executor;
+  late File kernelOutputFile;
+  final macroName = 'SimpleMacro';
+  late MacroInstanceIdentifier instanceId;
+  late Uri macroUri;
+  late File simpleMacroFile;
+  late Directory tmpDir;
+
+  for (var executorKind in ['Isolated', 'Process']) {
+    group('$executorKind executor', () {
+      for (var mode in [
+        SerializationMode.byteDataServer,
+        SerializationMode.jsonServer
+      ]) {
+        final clientMode = mode == SerializationMode.byteDataServer
+            ? SerializationMode.byteDataClient
+            : SerializationMode.jsonClient;
+
+        group('$mode', () {
+          setUpAll(() async {
+            simpleMacroFile =
+                File(Platform.script.resolve('simple_macro.dart').toFilePath());
+            executor = executorKind == 'Isolated'
+                ? await isolatedExecutor.start(mode)
+                : await processExecutor.start(mode);
+            tmpDir = Directory.systemTemp.createTempSync('executor_test');
+            macroUri = simpleMacroFile.absolute.uri;
+
+            var bootstrapContent = bootstrapMacroIsolate({
+              macroUri.toString(): {
+                macroName: ['', 'named']
+              }
+            }, clientMode);
+            var bootstrapFile =
+                File(tmpDir.uri.resolve('main.dart').toFilePath())
+                  ..writeAsStringSync(bootstrapContent);
+            kernelOutputFile =
+                File(tmpDir.uri.resolve('main.dart.dill').toFilePath());
+            var packageConfigPath = (await Isolate.packageConfig)!.toFilePath();
+            var buildSnapshotResult =
+                await Process.run(Platform.resolvedExecutable, [
+              if (executorKind == 'Isolated') ...[
+                '--snapshot=${kernelOutputFile.uri.toFilePath()}',
+                '--snapshot-kind=kernel',
+              ] else ...[
+                'compile',
+                'exe',
+                '-o',
+                kernelOutputFile.uri.toFilePath(),
+              ],
+              '--packages=${packageConfigPath}',
+              bootstrapFile.uri.toFilePath(),
+            ]);
+            expect(buildSnapshotResult.exitCode, 0,
+                reason: 'stdout: ${buildSnapshotResult.stdout}\n'
+                    'stderr: ${buildSnapshotResult.stderr}');
+
+            var clazzId = await executor.loadMacro(macroUri, macroName,
+                precompiledKernelUri: kernelOutputFile.uri);
+            expect(clazzId, isNotNull, reason: 'Can load a macro.');
+
+            instanceId =
+                await executor.instantiateMacro(clazzId, '', Arguments([], {}));
+            expect(instanceId, isNotNull,
+                reason: 'Can create an instance with no arguments.');
+
+            instanceId = await executor.instantiateMacro(
+                clazzId, '', Arguments([1, 2], {}));
+            expect(instanceId, isNotNull,
+                reason: 'Can create an instance with positional arguments.');
+
+            instanceId = await executor.instantiateMacro(
+                clazzId, 'named', Arguments([], {'x': 1, 'y': 2}));
+            expect(instanceId, isNotNull,
+                reason: 'Can create an instance with named arguments.');
+          });
+
+          tearDownAll(() {
+            if (tmpDir.existsSync()) {
+              try {
+                // Fails flakily on windows if a process still has the file open
+                tmpDir.deleteSync(recursive: true);
+              } catch (_) {}
+            }
+            executor.close();
+          });
+
+          group('run macros', () {
+            group('in the types phase', () {
+              test('on functions', () async {
+                var result = await executor.executeTypesPhase(
+                    instanceId, Fixtures.myFunction, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('class GeneratedByMyFunction {}'));
+              });
+
+              test('on methods', () async {
+                var result = await executor.executeTypesPhase(
+                    instanceId, Fixtures.myMethod, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('class GeneratedByMyMethod {}'));
+              });
+
+              test('on getters', () async {
+                var result = await executor.executeTypesPhase(instanceId,
+                    Fixtures.myVariableGetter, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'class GeneratedByMyVariableGetter {}'));
+              });
+
+              test('on setters', () async {
+                var result = await executor.executeTypesPhase(instanceId,
+                    Fixtures.myVariableSetter, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'class GeneratedByMyVariableSetter {}'));
+              });
+
+              test('on variables', () async {
+                var result = await executor.executeTypesPhase(
+                    instanceId, Fixtures.myVariable, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'class GeneratedBy_myVariable {}'));
+              });
+
+              test('on constructors', () async {
+                var result = await executor.executeTypesPhase(instanceId,
+                    Fixtures.myConstructor, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'class GeneratedByMyConstructor {}'));
+              });
+
+              test('on fields', () async {
+                var result = await executor.executeTypesPhase(
+                    instanceId, Fixtures.myField, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('class GeneratedByMyField {}'));
+              });
+
+              test('on classes', () async {
+                var result = await executor.executeTypesPhase(
+                    instanceId, Fixtures.myClass, FakeIdentifierResolver());
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'class MyClassBuilder implements Builder<MyClass> {}'));
+              });
+            });
+
+            group('in the declaration phase', () {
+              test('on functions', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myFunction,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'String delegateMyFunction() => myFunction();'));
+              });
+
+              test('on methods', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myMethod,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace(
+                        'String delegateMemberMyMethod() => myMethod();'));
+              });
+
+              test('on constructors', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myConstructor,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, hasLength(1));
+                expect(
+                    result.classAugmentations['MyClass']!.single
+                        .debugString()
+                        .toString(),
+                    equalsIgnoringWhitespace('''
+                factory MyClass.myConstructorDelegate() => MyClass.myConstructor();
+              '''));
+                expect(result.libraryAugmentations, isEmpty);
+              });
+
+              test('on getters', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myVariableGetter,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                String get delegateMyVariable => myVariable;'''));
+              });
+
+              test('on setters', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myVariableSetter,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                void set delegateMyVariable(String value) => myVariable = value;'''));
+              });
+
+              test('on variables', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myVariable,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                String get delegate_myVariable => _myVariable;'''));
+              });
+
+              test('on fields', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myField,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, hasLength(1));
+                expect(
+                    result.classAugmentations['MyClass']!.single
+                        .debugString()
+                        .toString(),
+                    equalsIgnoringWhitespace('''
+                String get delegateMyField => myField;
+              '''));
+                expect(result.libraryAugmentations, isEmpty);
+              });
+
+              test('on classes', () async {
+                var result = await executor.executeDeclarationsPhase(
+                    instanceId,
+                    Fixtures.myClass,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector);
+                expect(result.classAugmentations, hasLength(1));
+                expect(
+                    result.classAugmentations['MyClass']!.single
+                        .debugString()
+                        .toString(),
+                    equalsIgnoringWhitespace('''
+                static const List<String> fieldNames = ['myField',];
+              '''));
+                expect(result.libraryAugmentations, isEmpty);
+              });
+            });
+
+            group('in the definition phase', () {
+              test('on functions', () async {
+                var result = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myFunction,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                augment String myFunction() {
+                  print('isAbstract: false');
+                  print('isExternal: false');
+                  print('isGetter: false');
+                  print('isSetter: false');
+                  print('returnType: String');
+                  return augment super();
+                }'''));
+              });
+
+              test('on methods', () async {
+                var definitionResult = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myMethod,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(definitionResult.classAugmentations, hasLength(1));
+                var augmentationStrings = definitionResult
+                    .classAugmentations['MyClass']!
+                    .map((a) => a.debugString().toString())
+                    .toList();
+                expect(augmentationStrings,
+                    unorderedEquals(methodDefinitionMatchers));
+                expect(definitionResult.libraryAugmentations, isEmpty);
+              });
+
+              test('on constructors', () async {
+                var definitionResult = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myConstructor,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(definitionResult.classAugmentations, hasLength(1));
+                expect(
+                    definitionResult.classAugmentations['MyClass']!.first
+                        .debugString()
+                        .toString(),
+                    constructorDefinitionMatcher);
+                expect(definitionResult.libraryAugmentations, isEmpty);
+              });
+
+              test('on getters', () async {
+                var result = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myVariableGetter,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                augment String myVariable() {
+                  print('isAbstract: false');
+                  print('isExternal: false');
+                  print('isGetter: true');
+                  print('isSetter: false');
+                  print('returnType: String');
+                  return augment super;
+                }'''));
+              });
+
+              test('on setters', () async {
+                var result = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myVariableSetter,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations.single.debugString().toString(),
+                    equalsIgnoringWhitespace('''
+                augment void myVariable(String value, ) {
+                  print('isAbstract: false');
+                  print('isExternal: false');
+                  print('isGetter: false');
+                  print('isSetter: true');
+                  print('returnType: void');
+                  print('positionalParam: String value');
+                  return augment super = value;
+                }'''));
+              });
+
+              test('on variables', () async {
+                var result = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myVariable,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(result.classAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations
+                        .map((a) => a.debugString().toString()),
+                    unorderedEquals([
+                      equalsIgnoringWhitespace('''
+                augment String get _myVariable {
+                  print('parentClass: ');
+                  print('isExternal: false');
+                  print('isFinal: true');
+                  print('isLate: false');
+                  return augment super;
+                }'''),
+                      equalsIgnoringWhitespace('''
+                augment set _myVariable(String value) {
+                  augment super = value;
+                }'''),
+                      equalsIgnoringWhitespace('''
+                augment final String _myVariable = 'new initial value' + augment super;
+                '''),
+                    ]));
+              });
+
+              test('on fields', () async {
+                var definitionResult = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myField,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(definitionResult.classAugmentations, hasLength(1));
+                expect(
+                    definitionResult.classAugmentations['MyClass']!
+                        .map((a) => a.debugString().toString()),
+                    unorderedEquals(fieldDefinitionMatchers));
+                expect(definitionResult.libraryAugmentations, isEmpty);
+              });
+
+              test('on classes', () async {
+                var definitionResult = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.myClass,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeResolver,
+                    Fixtures.testClassIntrospector,
+                    Fixtures.testTypeDeclarationResolver);
+                expect(definitionResult.classAugmentations, hasLength(1));
+                var augmentationStrings = definitionResult
+