Version 2.17.0-161.0.dev

Merge commit '3d01c968e32bd78059ff61648c218f2ad48f75ec' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
new file mode 100644
index 0000000..51bc8f5
--- /dev/null
+++ b/.dart_tool/package_config.json
@@ -0,0 +1,825 @@
+{
+  "copyright": [
+    "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."
+  ],
+  "comment": [
+    "Package configuration for all packages in /pkg, and checked out by DEPS",
+    "into /third_party/pkg and /third_party/pkg_tested.",
+    "If you add a package to DEPS or /pkg or change a package's SDK",
+    "constraint, update this by running tools/generate_package_config.dart."
+  ],
+  "configVersion": 2,
+  "generator": "tools/generate_package_config.dart",
+  "packages": [
+    {
+      "name": "_fe_analyzer_shared",
+      "rootUri": "../pkg/_fe_analyzer_shared",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "_fe_analyzer_shared_assigned_variables",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_definite_assignment",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_definite_unassignment",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_inheritance",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/inheritance",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_nullability",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/nullability",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_reachability",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/reachability",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_type_promotion",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_fe_analyzer_shared_why_not_promoted",
+      "rootUri": "../pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "_js_interop_checks",
+      "rootUri": "../pkg/_js_interop_checks",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "analysis_server",
+      "rootUri": "../pkg/analysis_server",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "analysis_server_client",
+      "rootUri": "../pkg/analysis_server_client",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "analyzer",
+      "rootUri": "../pkg/analyzer",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "analyzer_cli",
+      "rootUri": "../pkg/analyzer_cli",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "analyzer_plugin",
+      "rootUri": "../pkg/analyzer_plugin",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "analyzer_utilities",
+      "rootUri": "../pkg/analyzer_utilities",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "args",
+      "rootUri": "../third_party/pkg/args",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "async",
+      "rootUri": "../third_party/pkg/async",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "async_helper",
+      "rootUri": "../pkg/async_helper",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "bazel_worker",
+      "rootUri": "../third_party/pkg/bazel_worker",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "benchmark_harness",
+      "rootUri": "../third_party/pkg/benchmark_harness",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "boolean_selector",
+      "rootUri": "../third_party/pkg/boolean_selector",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "browser_launcher",
+      "rootUri": "../third_party/pkg/browser_launcher",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "build_integration",
+      "rootUri": "../pkg/build_integration",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "characters",
+      "rootUri": "../third_party/pkg/characters",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "charcode",
+      "rootUri": "../third_party/pkg/charcode",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "cli_util",
+      "rootUri": "../third_party/pkg/cli_util",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "clock",
+      "rootUri": "../third_party/pkg/clock",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "collection",
+      "rootUri": "../third_party/pkg/collection",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "compiler",
+      "rootUri": "../pkg/compiler",
+      "packageUri": "lib/",
+      "languageVersion": "2.6"
+    },
+    {
+      "name": "convert",
+      "rootUri": "../third_party/pkg/convert",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "crypto",
+      "rootUri": "../third_party/pkg/crypto",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "csslib",
+      "rootUri": "../third_party/pkg/csslib",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dart2js_info",
+      "rootUri": "../pkg/dart2js_info",
+      "packageUri": "lib/",
+      "languageVersion": "2.11"
+    },
+    {
+      "name": "dart2js_runtime_metrics",
+      "rootUri": "../pkg/dart2js_runtime_metrics",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "dart2js_tools",
+      "rootUri": "../pkg/dart2js_tools",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dart2native",
+      "rootUri": "../pkg/dart2native",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dart2wasm",
+      "rootUri": "../pkg/dart2wasm",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dart_internal",
+      "rootUri": "../pkg/dart_internal",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dart_style",
+      "rootUri": "../third_party/pkg_tested/dart_style",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dartdev",
+      "rootUri": "../pkg/dartdev",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "dartdoc",
+      "rootUri": "../third_party/pkg/dartdoc",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "dds",
+      "rootUri": "../pkg/dds",
+      "packageUri": "lib/",
+      "languageVersion": "2.13"
+    },
+    {
+      "name": "dds_service_extensions",
+      "rootUri": "../pkg/dds_service_extensions",
+      "packageUri": "lib/",
+      "languageVersion": "2.13"
+    },
+    {
+      "name": "dev_compiler",
+      "rootUri": "../pkg/dev_compiler",
+      "packageUri": "lib/",
+      "languageVersion": "2.15"
+    },
+    {
+      "name": "devtools_shared",
+      "rootUri": "../third_party/devtools/devtools_shared",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "expect",
+      "rootUri": "../pkg/expect",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "ffi",
+      "rootUri": "../third_party/pkg/ffi",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "file",
+      "rootUri": "../third_party/pkg/file/packages/file",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "file_testing",
+      "rootUri": "../third_party/pkg/file/packages/file_testing",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "fixnum",
+      "rootUri": "../third_party/pkg/fixnum",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "front_end",
+      "rootUri": "../pkg/front_end",
+      "packageUri": "lib/",
+      "languageVersion": "2.13"
+    },
+    {
+      "name": "front_end_testcases",
+      "rootUri": "../pkg/front_end/testcases",
+      "packageUri": ".nonexisting/"
+    },
+    {
+      "name": "frontend_server",
+      "rootUri": "../pkg/frontend_server",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    },
+    {
+      "name": "frontend_server_client",
+      "rootUri": "../third_party/pkg/webdev/frontend_server_client",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "glob",
+      "rootUri": "../third_party/pkg/glob",
+      "packageUri": "lib/",
+      "languageVersion": "2.15"
+    },
+    {
+      "name": "html",
+      "rootUri": "../third_party/pkg/html",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "http",
+      "rootUri": "../third_party/pkg/http",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "http_io",
+      "rootUri": "../third_party/pkg_tested/http_io",
+      "packageUri": "lib/",
+      "languageVersion": "2.5"
+    },
+    {
+      "name": "http_multi_server",
+      "rootUri": "../third_party/pkg/http_multi_server",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "http_parser",
+      "rootUri": "../third_party/pkg/http_parser",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "intl",
+      "rootUri": "../third_party/pkg/intl",
+      "packageUri": "lib/",
+      "languageVersion": "2.11"
+    },
+    {
+      "name": "js",
+      "rootUri": "../pkg/js",
+      "packageUri": "lib/",
+      "languageVersion": "2.16"
+    },
+    {
+      "name": "js_ast",
+      "rootUri": "../pkg/js_ast",
+      "packageUri": "lib/",
+      "languageVersion": "2.10"
+    },
+    {
+      "name": "js_runtime",
+      "rootUri": "../pkg/js_runtime",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "json_rpc_2",
+      "rootUri": "../third_party/pkg/json_rpc_2",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "kernel",
+      "rootUri": "../pkg/kernel",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "language_versioning_2.7_test",
+      "rootUri": "../pkg/language_versioning_2.7_test",
+      "languageVersion": "2.7"
+    },
+    {
+      "name": "linter",
+      "rootUri": "../third_party/pkg/linter",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "lints",
+      "rootUri": "../third_party/pkg/lints",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "logging",
+      "rootUri": "../third_party/pkg/logging",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "markdown",
+      "rootUri": "../third_party/pkg/markdown",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "matcher",
+      "rootUri": "../third_party/pkg/matcher",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "meta",
+      "rootUri": "../pkg/meta",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "mime",
+      "rootUri": "../third_party/pkg/mime",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "mockito",
+      "rootUri": "../third_party/pkg/mockito",
+      "packageUri": "lib/",
+      "languageVersion": "2.0"
+    },
+    {
+      "name": "modular_test",
+      "rootUri": "../pkg/modular_test",
+      "packageUri": "lib/",
+      "languageVersion": "2.2"
+    },
+    {
+      "name": "native_stack_traces",
+      "rootUri": "../pkg/native_stack_traces",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "nnbd_migration",
+      "rootUri": "../pkg/nnbd_migration",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "oauth2",
+      "rootUri": "../third_party/pkg/oauth2",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "observatory",
+      "rootUri": "../runtime/observatory",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "observatory_2",
+      "rootUri": "../runtime/observatory_2",
+      "packageUri": "lib/",
+      "languageVersion": "2.6"
+    },
+    {
+      "name": "observatory_test_package",
+      "rootUri": "../runtime/observatory/tests/service/observatory_test_package",
+      "languageVersion": "2.9"
+    },
+    {
+      "name": "observatory_test_package_2",
+      "rootUri": "../runtime/observatory_2/tests/service_2/observatory_test_package_2",
+      "languageVersion": "2.7"
+    },
+    {
+      "name": "package_config",
+      "rootUri": "../third_party/pkg_tested/package_config",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "package_deps",
+      "rootUri": "../tools/package_deps",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "path",
+      "rootUri": "../third_party/pkg/path",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "pedantic",
+      "rootUri": "../third_party/pkg/pedantic",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "platform",
+      "rootUri": "../third_party/pkg/platform",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "pool",
+      "rootUri": "../third_party/pkg/pool",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "process",
+      "rootUri": "../third_party/pkg/process",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "protobuf",
+      "rootUri": "../third_party/pkg/protobuf/protobuf",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "pub",
+      "rootUri": "../third_party/pkg/pub",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "pub_semver",
+      "rootUri": "../third_party/pkg/pub_semver",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "scrape",
+      "rootUri": "../pkg/scrape",
+      "packageUri": "lib/",
+      "languageVersion": "2.13"
+    },
+    {
+      "name": "sdk_library_metadata",
+      "rootUri": "../sdk/lib/_internal/sdk_library_metadata",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "shelf",
+      "rootUri": "../third_party/pkg/shelf",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "shelf_packages_handler",
+      "rootUri": "../third_party/pkg/shelf_packages_handler",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "shelf_proxy",
+      "rootUri": "../third_party/pkg/shelf_proxy",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "shelf_static",
+      "rootUri": "../third_party/pkg/shelf_static",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "shelf_web_socket",
+      "rootUri": "../third_party/pkg/shelf_web_socket",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "smith",
+      "rootUri": "../pkg/smith",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "source_map_stack_trace",
+      "rootUri": "../third_party/pkg/source_map_stack_trace",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "source_maps",
+      "rootUri": "../third_party/pkg/source_maps",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "source_span",
+      "rootUri": "../third_party/pkg/source_span",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "sourcemap_testing",
+      "rootUri": "../pkg/sourcemap_testing",
+      "packageUri": "lib/",
+      "languageVersion": "2.1"
+    },
+    {
+      "name": "sse",
+      "rootUri": "../third_party/pkg/sse",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "stack_trace",
+      "rootUri": "../third_party/pkg/stack_trace",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "status_file",
+      "rootUri": "../pkg/status_file",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "stream_channel",
+      "rootUri": "../third_party/pkg/stream_channel",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "string_scanner",
+      "rootUri": "../third_party/pkg/string_scanner",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "sync_http",
+      "rootUri": "../third_party/pkg/sync_http",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "telemetry",
+      "rootUri": "../pkg/telemetry",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "term_glyph",
+      "rootUri": "../third_party/pkg/term_glyph",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test",
+      "rootUri": "../third_party/pkg/test/pkgs/test",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_api",
+      "rootUri": "../third_party/pkg/test/pkgs/test_api",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_core",
+      "rootUri": "../third_party/pkg/test/pkgs/test_core",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_descriptor",
+      "rootUri": "../third_party/pkg/test_descriptor",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_package",
+      "rootUri": "../pkg/vm_service/test/test_package",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_process",
+      "rootUri": "../third_party/pkg/test_process",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_reflective_loader",
+      "rootUri": "../third_party/pkg/test_reflective_loader",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "test_runner",
+      "rootUri": "../pkg/test_runner",
+      "packageUri": "lib/",
+      "languageVersion": "2.3"
+    },
+    {
+      "name": "testing",
+      "rootUri": "../pkg/testing",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "typed_data",
+      "rootUri": "../third_party/pkg/typed_data",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "usage",
+      "rootUri": "../third_party/pkg/usage",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "vector_math",
+      "rootUri": "../third_party/pkg/vector_math",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "vm",
+      "rootUri": "../pkg/vm",
+      "packageUri": "lib/",
+      "languageVersion": "2.15"
+    },
+    {
+      "name": "vm_service",
+      "rootUri": "../pkg/vm_service",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "vm_snapshot_analysis",
+      "rootUri": "../pkg/vm_snapshot_analysis",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "wasm_builder",
+      "rootUri": "../pkg/wasm_builder",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "watcher",
+      "rootUri": "../third_party/pkg/watcher",
+      "packageUri": "lib/",
+      "languageVersion": "2.14"
+    },
+    {
+      "name": "web_components",
+      "rootUri": "../third_party/pkg/web_components",
+      "packageUri": "lib/",
+      "languageVersion": "1.9"
+    },
+    {
+      "name": "web_socket_channel",
+      "rootUri": "../third_party/pkg/web_socket_channel",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "webdriver",
+      "rootUri": "../third_party/pkg/webdriver",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "webkit_inspection_protocol",
+      "rootUri": "../third_party/pkg/webkit_inspection_protocol",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "yaml",
+      "rootUri": "../third_party/pkg/yaml",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "yaml_edit",
+      "rootUri": "../third_party/pkg/yaml_edit",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    }
+  ]
+}
diff --git a/.gitignore b/.gitignore
index 9c674bd..1f4ccc7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,10 +75,6 @@
 packages
 pubspec.lock
 
-# The top level package files (these are auto-generated per checkout)
-/.dart_tool/package_config.json
-/.packages
-
 # Local pub storage
 .pub
 
diff --git a/.packages b/.packages
new file mode 100644
index 0000000..646a631
--- /dev/null
+++ b/.packages
@@ -0,0 +1,130 @@
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# 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
+analysis_server_client:pkg/analysis_server_client/lib
+analyzer:pkg/analyzer/lib
+analyzer_cli:pkg/analyzer_cli/lib
+analyzer_plugin:pkg/analyzer_plugin/lib
+analyzer_utilities:pkg/analyzer_utilities/lib
+args:third_party/pkg/args/lib
+async:third_party/pkg/async/lib
+async_helper:pkg/async_helper/lib
+bazel_worker:third_party/pkg/bazel_worker/lib
+benchmark_harness:third_party/pkg/benchmark_harness/lib
+boolean_selector:third_party/pkg/boolean_selector/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
+crypto:third_party/pkg/crypto/lib
+csslib:third_party/pkg/csslib/lib
+dart2js_info:pkg/dart2js_info/lib
+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
+dartdoc:third_party/pkg/dartdoc/lib
+dds:pkg/dds/lib
+dds_service_extensions:pkg/dds_service_extensions/lib
+dev_compiler:pkg/dev_compiler/lib
+devtools_shared:third_party/devtools/devtools_shared/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
+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
+http_io:third_party/pkg_tested/http_io/lib
+http_multi_server:third_party/pkg/http_multi_server/lib
+http_parser:third_party/pkg/http_parser/lib
+intl:third_party/pkg/intl/lib
+js:pkg/js/lib
+js_ast:pkg/js_ast/lib
+js_runtime:pkg/js_runtime/lib
+json_rpc_2:third_party/pkg/json_rpc_2/lib
+kernel:pkg/kernel/lib
+linter:third_party/pkg/linter/lib
+lints:third_party/pkg/lints/lib
+logging:third_party/pkg/logging/lib
+markdown:third_party/pkg/markdown/lib
+matcher:third_party/pkg/matcher/lib
+meta:pkg/meta/lib
+mime:third_party/pkg/mime/lib
+mockito:third_party/pkg/mockito/lib
+modular_test:pkg/modular_test/lib
+native_stack_traces:pkg/native_stack_traces/lib
+nnbd_migration:pkg/nnbd_migration/lib
+oauth2:third_party/pkg/oauth2/lib
+observatory:runtime/observatory/lib
+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
+platform:third_party/pkg/platform/lib
+pool:third_party/pkg/pool/lib
+process:third_party/pkg/process/lib
+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
+shelf_proxy:third_party/pkg/shelf_proxy/lib
+shelf_static:third_party/pkg/shelf_static/lib
+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
+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
+stream_channel:third_party/pkg/stream_channel/lib
+string_scanner:third_party/pkg/string_scanner/lib
+sync_http:third_party/pkg/sync_http/lib
+telemetry:pkg/telemetry/lib
+term_glyph:third_party/pkg/term_glyph/lib
+test:third_party/pkg/test/pkgs/test/lib
+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_process:third_party/pkg/test_process/lib
+test_reflective_loader:third_party/pkg/test_reflective_loader/lib
+test_runner:pkg/test_runner/lib
+testing:pkg/testing/lib
+typed_data:third_party/pkg/typed_data/lib
+usage:third_party/pkg/usage/lib
+vector_math:third_party/pkg/vector_math/lib
+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
+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/DEPS b/DEPS
index 783aa7b..276e2bd 100644
--- a/DEPS
+++ b/DEPS
@@ -698,12 +698,6 @@
 
 hooks = [
   {
-    # Generate the .dart_tool/package_confg.json file.
-    'name': 'Generate .dart_tool/package_confg.json',
-    'pattern': '.',
-    'action': ['python3', 'sdk/tools/generate_package_config.py'],
-  },
-  {
     # Pull Debian sysroot for i386 Linux
     'name': 'sysroot_i386',
     'pattern': '.',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6a47593..fc93703 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -237,6 +237,31 @@
     return []
 
 
+def _CheckPackageConfigUpToDate(input_api, output_api):
+    """Checks that .dart_tool/package_config.json is up to date."""
+    # Run only if DEPS file or package_config.json have been modified.
+    if not any(p == 'DEPS' or p == '.dart_tool/package_config.json' or
+               p.endswith('pubspec.yaml') for p in input_api.LocalPaths()):
+        return []
+    local_root = input_api.change.RepositoryRoot()
+    utils = imp.load_source('utils',
+                            os.path.join(local_root, 'tools', 'utils.py'))
+
+    dart = utils.CheckedInSdkExecutable()
+    generate = os.path.join(local_root, 'tools', 'generate_package_config.dart')
+    cmd = [dart, generate, '--check']
+    result = subprocess.run(cmd, shell=utils.IsWindows())
+    if result.returncode != 0:
+        return [
+            output_api.PresubmitError(
+                'File .dart_tool/package_config.json is out of date.\n'
+                'Fix these issues with:\n'
+                'gclient sync -D && %s tools/generate_package_config.dart' %
+                (dart))
+        ]
+    return []
+
+
 def _CheckValidHostsInDEPS(input_api, output_api):
     """Checks that DEPS file deps are from allowed_hosts."""
     # Run only if DEPS file has been modified to annoy fewer bystanders.
@@ -357,6 +382,7 @@
     results.extend(_CheckLayering(input_api, output_api))
     results.extend(_CheckClangTidy(input_api, output_api))
     results.extend(_CheckTestMatrixValid(input_api, output_api))
+    results.extend(_CheckPackageConfigUpToDate(input_api, output_api))
     results.extend(
         input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
     return results
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index d58a335..d0f199e 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -68,7 +68,7 @@
 CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER:
   status: needsEvaluation
 CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE:
-  status: needsEvaluation
+  status: hasFix
 CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR:
   status: needsEvaluation
 CompileTimeErrorCode.ASSIGNMENT_TO_CONST:
@@ -318,6 +318,11 @@
   status: needsFix
   since: 2.17
   issue: https://github.com/dart-lang/sdk/issues/48478
+CompileTimeErrorCode.ENUM_WITH_NAME_VALUES:
+  status: noFix
+  since: 2.17
+  notes: |-
+    Requires a rename.
 CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET:
   status: needsEvaluation
 CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP:
@@ -417,6 +422,20 @@
   status: hasFix
 CompileTimeErrorCode.ILLEGAL_ASYNC_RETURN_TYPE:
   status: hasFix
+CompileTimeErrorCode.ILLEGAL_CONCRETE_ENUM_MEMBER_DECLARATION:
+  status: noFix
+  since: 2.17
+  notes: |-
+    We could potentially offer to remove the member, but the user probably needs
+    to think about what they were trying to do and it seems more likely that the
+    right fix is to rename the member.
+CompileTimeErrorCode.ILLEGAL_CONCRETE_ENUM_MEMBER_INHERITANCE:
+  status: noFix
+  since: 2.17
+  notes: |-
+    We could potentially offer to remove the member, but the user probably needs
+    to think about what they were trying to do and it seems more likely that the
+    right fix is to rename the member.
 CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_DECLARATION:
   status: noFix
   since: 2.17
@@ -433,13 +452,6 @@
     We could potentially offer to remove the override, or to update it to the
     lowest legal value, but it isn't clear that either of these is the right
     fix without knowing why the language override was added.
-CompileTimeErrorCode.ILLEGAL_NON_ABSTRACT_ENUM_INDEX:
-  status: noFix
-  since: 2.17
-  notes: |-
-    We could potentially offer to remove the member, but the user probably needs
-    to think about what they were trying to do and it seems more likely that the
-    right fix is to rename the member.
 CompileTimeErrorCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE:
   status: hasFix
 CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS:
@@ -933,7 +945,7 @@
 CompileTimeErrorCode.UNDEFINED_FUNCTION:
   status: hasFix
 CompileTimeErrorCode.UNDEFINED_GETTER:
-  status: has_fix(es)
+  status: hasFix
 CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE:
   status: needsFix
   since: 2.15
@@ -1127,7 +1139,7 @@
 FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH:
   status: needsEvaluation
 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE_TO_ERROR_HANDLER:
-  status: hasFix
+  status: needsEvaluation
 HintCode.ASSIGNMENT_OF_DO_NOT_STORE:
   status: needsEvaluation
 HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE:
@@ -1263,7 +1275,7 @@
 HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS:
   status: hasFix
 HintCode.MISSING_RETURN:
-  status: needsEvaluation
+  status: hasFix
 HintCode.MIXIN_ON_SEALED_CLASS:
   status: needsEvaluation
 HintCode.MUST_BE_IMMUTABLE:
@@ -1342,9 +1354,9 @@
 HintCode.UNDEFINED_HIDDEN_NAME:
   status: hasFix
 HintCode.UNDEFINED_REFERENCED_PARAMETER:
-  status: hasFix
-HintCode.UNDEFINED_SHOWN_NAME:
   status: needsEvaluation
+HintCode.UNDEFINED_SHOWN_NAME:
+  status: hasFix
 HintCode.UNIGNORABLE_IGNORE:
   status: needsEvaluation
 HintCode.UNNECESSARY_CAST:
@@ -1415,195 +1427,195 @@
   status: needsEvaluation
 LanguageCode.IMPLICIT_DYNAMIC_VARIABLE:
   status: needsEvaluation
-LintNames.always_declare_return_types:
+LintCode.always_declare_return_types:
   status: hasFix
-LintNames.always_put_control_body_on_new_line:
+LintCode.always_put_control_body_on_new_line:
   status: needsEvaluation
-LintNames.always_put_required_named_parameters_first:
+LintCode.always_put_required_named_parameters_first:
   status: needsEvaluation
-LintNames.always_require_non_null_named_parameters:
+LintCode.always_require_non_null_named_parameters:
   status: hasFix
-LintNames.always_specify_types:
+LintCode.always_specify_types:
   status: hasFix
-LintNames.always_use_package_imports:
+LintCode.always_use_package_imports:
   status: hasFix
-LintNames.annotate_overrides:
+LintCode.annotate_overrides:
   status: hasFix
-LintNames.avoid_annotating_with_dynamic:
+LintCode.avoid_annotating_with_dynamic:
   status: hasFix
-LintNames.avoid_as:
+LintCode.avoid_as:
   status: needsEvaluation
-LintNames.avoid_bool_literals_in_conditional_expressions:
+LintCode.avoid_bool_literals_in_conditional_expressions:
   status: needsEvaluation
-LintNames.avoid_catches_without_on_clauses:
+LintCode.avoid_catches_without_on_clauses:
   status: needsEvaluation
-LintNames.avoid_catching_errors:
+LintCode.avoid_catching_errors:
   status: needsEvaluation
-LintNames.avoid_classes_with_only_static_members:
+LintCode.avoid_classes_with_only_static_members:
   status: needsEvaluation
-LintNames.avoid_double_and_int_checks:
+LintCode.avoid_double_and_int_checks:
   status: needsEvaluation
-LintNames.avoid_dynamic_calls:
+LintCode.avoid_dynamic_calls:
   status: needsEvaluation
-LintNames.avoid_empty_else:
+LintCode.avoid_empty_else:
   status: hasFix
-LintNames.avoid_equals_and_hash_code_on_mutable_classes:
+LintCode.avoid_equals_and_hash_code_on_mutable_classes:
   status: needsEvaluation
-LintNames.avoid_escaping_inner_quotes:
+LintCode.avoid_escaping_inner_quotes:
   status: hasFix
-LintNames.avoid_field_initializers_in_const_classes:
+LintCode.avoid_field_initializers_in_const_classes:
   status: needsEvaluation
-LintNames.avoid_final_parameters:
+LintCode.avoid_final_parameters:
   status: needsEvaluation
-LintNames.avoid_function_literals_in_foreach_calls:
+LintCode.avoid_function_literals_in_foreach_calls:
   status: hasFix
-LintNames.avoid_implementing_value_types:
+LintCode.avoid_implementing_value_types:
   status: needsEvaluation
-LintNames.avoid_init_to_null:
+LintCode.avoid_init_to_null:
   status: hasFix
-LintNames.avoid_js_rounded_ints:
+LintCode.avoid_js_rounded_ints:
   status: needsEvaluation
-LintNames.avoid_multiple_declarations_per_line:
+LintCode.avoid_multiple_declarations_per_line:
   status: needsEvaluation
-LintNames.avoid_null_checks_in_equality_operators:
+LintCode.avoid_null_checks_in_equality_operators:
   status: hasFix
-LintNames.avoid_positional_boolean_parameters:
+LintCode.avoid_positional_boolean_parameters:
   status: needsEvaluation
-LintNames.avoid_print:
+LintCode.avoid_print:
   status: hasFix
-LintNames.avoid_private_typedef_functions:
+LintCode.avoid_private_typedef_functions:
   status: hasFix
-LintNames.avoid_redundant_argument_values:
+LintCode.avoid_redundant_argument_values:
   status: hasFix
-LintNames.avoid_relative_lib_imports:
+LintCode.avoid_relative_lib_imports:
   status: hasFix
-LintNames.avoid_renaming_method_parameters:
+LintCode.avoid_renaming_method_parameters:
   status: needsEvaluation
-LintNames.avoid_return_types_on_setters:
+LintCode.avoid_return_types_on_setters:
   status: hasFix
-LintNames.avoid_returning_null:
+LintCode.avoid_returning_null:
   status: needsEvaluation
-LintNames.avoid_returning_null_for_future:
+LintCode.avoid_returning_null_for_future:
   status: hasFix
-LintNames.avoid_returning_null_for_void:
+LintCode.avoid_returning_null_for_void:
   status: hasFix
-LintNames.avoid_returning_this:
+LintCode.avoid_returning_this:
   status: needsEvaluation
-LintNames.avoid_setters_without_getters:
+LintCode.avoid_setters_without_getters:
   status: needsEvaluation
-LintNames.avoid_shadowing_type_parameters:
+LintCode.avoid_shadowing_type_parameters:
   status: needsEvaluation
-LintNames.avoid_single_cascade_in_expression_statements:
+LintCode.avoid_single_cascade_in_expression_statements:
   status: hasFix
-LintNames.avoid_slow_async_io:
+LintCode.avoid_slow_async_io:
   status: needsEvaluation
-LintNames.avoid_type_to_string:
+LintCode.avoid_type_to_string:
   status: needsEvaluation
-LintNames.avoid_types_as_parameter_names:
+LintCode.avoid_types_as_parameter_names:
   status: hasFix
-LintNames.avoid_types_on_closure_parameters:
+LintCode.avoid_types_on_closure_parameters:
   status: hasFix
-LintNames.avoid_unnecessary_containers:
+LintCode.avoid_unnecessary_containers:
   status: hasFix
-LintNames.avoid_unused_constructor_parameters:
+LintCode.avoid_unused_constructor_parameters:
   status: hasFix
-LintNames.avoid_void_async:
-  status: needsEvaluation
-LintNames.avoid_web_libraries_in_flutter:
-  status: needsEvaluation
-LintNames.await_only_futures:
+LintCode.avoid_void_async:
   status: hasFix
-LintNames.camel_case_extensions:
+LintCode.avoid_web_libraries_in_flutter:
   status: needsEvaluation
-LintNames.camel_case_types:
-  status: needsEvaluation
-LintNames.cancel_subscriptions:
-  status: needsEvaluation
-LintNames.cascade_invocations:
-  status: needsEvaluation
-LintNames.cast_nullable_to_non_nullable:
-  status: needsEvaluation
-LintNames.close_sinks:
-  status: needsEvaluation
-LintNames.comment_references:
-  status: needsEvaluation
-LintNames.conditional_uri_does_not_exist:
-  status: needsEvaluation
-LintNames.constant_identifier_names:
-  status: needsEvaluation
-LintNames.control_flow_in_finally:
-  status: needsEvaluation
-LintNames.curly_braces_in_flow_control_structures:
+LintCode.await_only_futures:
   status: hasFix
-LintNames.depend_on_referenced_packages:
+LintCode.camel_case_extensions:
+  status: needsEvaluation
+LintCode.camel_case_types:
+  status: needsEvaluation
+LintCode.cancel_subscriptions:
+  status: needsEvaluation
+LintCode.cascade_invocations:
+  status: needsEvaluation
+LintCode.cast_nullable_to_non_nullable:
+  status: needsEvaluation
+LintCode.close_sinks:
+  status: needsEvaluation
+LintCode.comment_references:
+  status: needsEvaluation
+LintCode.conditional_uri_does_not_exist:
+  status: needsEvaluation
+LintCode.constant_identifier_names:
+  status: needsEvaluation
+LintCode.control_flow_in_finally:
+  status: needsEvaluation
+LintCode.curly_braces_in_flow_control_structures:
+  status: hasFix
+LintCode.depend_on_referenced_packages:
   status: needsFix
-LintNames.deprecated_consistency:
+LintCode.deprecated_consistency:
   status: needsEvaluation
-LintNames.diagnostic_describe_all_properties:
+LintCode.diagnostic_describe_all_properties:
   status: hasFix
-LintNames.directives_ordering:
+LintCode.directives_ordering:
   status: hasFix
-LintNames.do_not_use_environment:
+LintCode.do_not_use_environment:
   status: needsEvaluation
-LintNames.empty_catches:
+LintCode.empty_catches:
   status: hasFix
-LintNames.empty_constructor_bodies:
+LintCode.empty_constructor_bodies:
   status: hasFix
-LintNames.empty_statements:
+LintCode.empty_statements:
   status: hasFix
-LintNames.eol_at_end_of_file:
+LintCode.eol_at_end_of_file:
   status: hasFix
-LintNames.exhaustive_cases:
+LintCode.exhaustive_cases:
   status: hasFix
-LintNames.file_names:
+LintCode.file_names:
   status: needsEvaluation
-LintNames.flutter_style_todos:
+LintCode.flutter_style_todos:
   status: needsEvaluation
-LintNames.hash_and_equals:
+LintCode.hash_and_equals:
   status: hasFix
-LintNames.implementation_imports:
+LintCode.implementation_imports:
   status: needsEvaluation
-LintNames.invariant_booleans:
+LintCode.invariant_booleans:
   status: needsEvaluation
-LintNames.iterable_contains_unrelated_type:
+LintCode.iterable_contains_unrelated_type:
   status: needsEvaluation
-LintNames.join_return_with_assignment:
+LintCode.join_return_with_assignment:
   status: needsEvaluation
-LintNames.leading_newlines_in_multiline_strings:
+LintCode.leading_newlines_in_multiline_strings:
   status: hasFix
-LintNames.library_names:
+LintCode.library_names:
   status: needsEvaluation
-LintNames.library_prefixes:
+LintCode.library_prefixes:
   status: needsEvaluation
-LintNames.library_private_types_in_public_api:
+LintCode.library_private_types_in_public_api:
   status: needsEvaluation
-LintNames.lines_longer_than_80_chars:
+LintCode.lines_longer_than_80_chars:
   status: needsEvaluation
-LintNames.list_remove_unrelated_type:
+LintCode.list_remove_unrelated_type:
   status: needsEvaluation
-LintNames.literal_only_boolean_expressions:
+LintCode.literal_only_boolean_expressions:
   status: needsEvaluation
-LintNames.missing_whitespace_between_adjacent_strings:
+LintCode.missing_whitespace_between_adjacent_strings:
   status: needsEvaluation
-LintNames.no_adjacent_strings_in_list:
+LintCode.no_adjacent_strings_in_list:
   status: needsEvaluation
-LintNames.no_default_cases:
+LintCode.no_default_cases:
   status: needsEvaluation
-LintNames.no_duplicate_case_values:
+LintCode.no_duplicate_case_values:
   status: hasFix
-LintNames.no_leading_underscores_for_library_prefixes:
+LintCode.no_leading_underscores_for_library_prefixes:
   status: needsFix
-LintNames.no_leading_underscores_for_local_identifiers:
+LintCode.no_leading_underscores_for_local_identifiers:
   status: hasFix
-LintNames.no_logic_in_create_state:
+LintCode.no_logic_in_create_state:
   status: needsEvaluation
-LintNames.no_runtimeType_toString:
+LintCode.no_runtimeType_toString:
   status: needsEvaluation
-LintNames.non_constant_identifier_names:
+LintCode.non_constant_identifier_names:
   status: hasFix
-LintNames.noop_primitive_operations:
+LintCode.noop_primitive_operations:
   status: needsEvaluation
-LintNames.null_check_on_nullable_type_parameter:
+LintCode.null_check_on_nullable_type_parameter:
   status: hasFix
   notes: |-
     A second fix is possible, in which we make the type parameter not
@@ -1612,222 +1624,225 @@
     `T foo<T extends num>()`. This is particularly valuable in the first
     case, where the choice to implicitly bound the type to `dynamic` may not
     have been intentional.
-LintNames.null_closures:
+LintCode.null_closures:
   status: hasFix
-LintNames.omit_local_variable_types:
+LintCode.omit_local_variable_types:
   status: hasFix
-LintNames.one_member_abstracts:
+LintCode.one_member_abstracts:
   status: needsEvaluation
-LintNames.only_throw_errors:
+LintCode.only_throw_errors:
   status: needsEvaluation
-LintNames.overridden_fields:
+LintCode.overridden_fields:
   status: needsEvaluation
-LintNames.package_api_docs:
+LintCode.package_api_docs:
   status: needsEvaluation
-LintNames.package_prefixed_library_names:
+LintCode.package_names:
   status: needsEvaluation
-LintNames.parameter_assignments:
+LintCode.package_prefixed_library_names:
   status: needsEvaluation
-LintNames.prefer_adjacent_string_concatenation:
-  status: hasFix
-LintNames.prefer_asserts_in_initializer_lists:
+LintCode.parameter_assignments:
   status: needsEvaluation
-LintNames.prefer_asserts_with_message:
+LintCode.prefer_adjacent_string_concatenation:
+  status: hasFix
+LintCode.prefer_asserts_in_initializer_lists:
   status: needsEvaluation
-LintNames.prefer_bool_in_asserts:
+LintCode.prefer_asserts_with_message:
   status: needsEvaluation
-LintNames.prefer_collection_literals:
-  status: hasFix
-LintNames.prefer_conditional_assignment:
-  status: hasFix
-LintNames.prefer_const_constructors:
-  status: hasFix
-LintNames.prefer_const_constructors_in_immutables:
-  status: hasFix
-LintNames.prefer_const_declarations:
-  status: hasFix
-LintNames.prefer_const_literals_to_create_immutables:
-  status: hasFix
-LintNames.prefer_constructors_over_static_methods:
+LintCode.prefer_bool_in_asserts:
   status: needsEvaluation
-LintNames.prefer_contains:
+LintCode.prefer_collection_literals:
   status: hasFix
-LintNames.prefer_double_quotes:
+LintCode.prefer_conditional_assignment:
   status: hasFix
-LintNames.prefer_equal_for_default_values:
+LintCode.prefer_const_constructors:
   status: hasFix
-LintNames.prefer_expression_function_bodies:
+LintCode.prefer_const_constructors_in_immutables:
   status: hasFix
-LintNames.prefer_final_fields:
+LintCode.prefer_const_declarations:
   status: hasFix
-LintNames.prefer_final_in_for_each:
+LintCode.prefer_const_literals_to_create_immutables:
   status: hasFix
-LintNames.prefer_final_locals:
-  status: hasFix
-LintNames.prefer_final_parameters:
-  status: hasFix
-LintNames.prefer_for_elements_to_map_fromIterable:
-  status: hasFix
-LintNames.prefer_foreach:
+LintCode.prefer_constructors_over_static_methods:
   status: needsEvaluation
-LintNames.prefer_function_declarations_over_variables:
+LintCode.prefer_contains:
+  status: hasFix
+LintCode.prefer_double_quotes:
+  status: hasFix
+LintCode.prefer_equal_for_default_values:
+  status: hasFix
+LintCode.prefer_expression_function_bodies:
+  status: hasFix
+LintCode.prefer_final_fields:
+  status: hasFix
+LintCode.prefer_final_in_for_each:
+  status: hasFix
+LintCode.prefer_final_locals:
+  status: hasFix
+LintCode.prefer_final_parameters:
+  status: hasFix
+LintCode.prefer_for_elements_to_map_fromIterable:
+  status: hasFix
+LintCode.prefer_foreach:
   status: needsEvaluation
-LintNames.prefer_generic_function_type_aliases:
-  status: hasFix
-LintNames.prefer_if_elements_to_conditional_expressions:
-  status: hasFix
-LintNames.prefer_if_null_operators:
-  status: hasFix
-LintNames.prefer_initializing_formals:
-  status: hasFix
-LintNames.prefer_inlined_adds:
-  status: hasFix
-LintNames.prefer_int_literals:
-  status: hasFix
-LintNames.prefer_interpolation_to_compose_strings:
-  status: hasFix
-LintNames.prefer_is_empty:
-  status: hasFix
-LintNames.prefer_is_not_empty:
-  status: hasFix
-LintNames.prefer_is_not_operator:
-  status: hasFix
-LintNames.prefer_iterable_whereType:
-  status: hasFix
-LintNames.prefer_mixin:
+LintCode.prefer_function_declarations_over_variables:
   status: needsEvaluation
-LintNames.prefer_null_aware_method_calls:
+LintCode.prefer_generic_function_type_aliases:
+  status: hasFix
+LintCode.prefer_if_elements_to_conditional_expressions:
+  status: hasFix
+LintCode.prefer_if_null_operators:
+  status: hasFix
+LintCode.prefer_initializing_formals:
+  status: hasFix
+LintCode.prefer_inlined_adds:
+  status: hasFix
+LintCode.prefer_int_literals:
+  status: hasFix
+LintCode.prefer_interpolation_to_compose_strings:
+  status: hasFix
+LintCode.prefer_is_empty:
+  status: hasFix
+LintCode.prefer_is_not_empty:
+  status: hasFix
+LintCode.prefer_is_not_operator:
+  status: hasFix
+LintCode.prefer_iterable_whereType:
+  status: hasFix
+LintCode.prefer_mixin:
   status: needsEvaluation
-LintNames.prefer_null_aware_operators:
-  status: hasFix
-LintNames.prefer_relative_imports:
-  status: hasFix
-LintNames.prefer_single_quotes:
-  status: hasFix
-LintNames.prefer_spread_collections:
-  status: hasFix
-LintNames.prefer_typing_uninitialized_variables:
-  status: hasFix
-LintNames.prefer_void_to_null:
-  status: hasFix
-LintNames.provide_deprecation_message:
+LintCode.prefer_null_aware_method_calls:
   status: needsEvaluation
-LintNames.pub/package_names:
-  status: needsEvaluation
-LintNames.pub/secure_pubspec_urls:
-  status: needsEvaluation
-LintNames.pub/sort_pub_dependencies:
-  status: needsEvaluation
-LintNames.public_member_api_docs:
-  status: needsEvaluation
-LintNames.recursive_getters:
-  status: needsEvaluation
-LintNames.require_trailing_commas:
+LintCode.prefer_null_aware_operators:
   status: hasFix
-LintNames.sized_box_for_whitespace:
+LintCode.prefer_relative_imports:
   status: hasFix
-LintNames.sized_box_shrink_expand:
+LintCode.prefer_single_quotes:
+  status: hasFix
+LintCode.prefer_spread_collections:
+  status: hasFix
+LintCode.prefer_typing_uninitialized_variables:
+  status: hasFix
+LintCode.prefer_void_to_null:
+  status: hasFix
+LintCode.provide_deprecation_message:
   status: needsEvaluation
-LintNames.slash_for_doc_comments:
+LintCode.public_member_api_docs:
+  status: needsEvaluation
+LintCode.recursive_getters:
+  status: needsEvaluation
+LintCode.require_trailing_commas:
   status: hasFix
-LintNames.sort_child_properties_last:
+LintCode.secure_pubspec_urls:
+  status: needsEvaluation
+LintCode.sized_box_for_whitespace:
   status: hasFix
-LintNames.sort_constructors_first:
+LintCode.sized_box_shrink_expand:
+  status: needsEvaluation
+LintCode.slash_for_doc_comments:
+  status: hasFix
+LintCode.sort_child_properties_last:
+  status: hasFix
+LintCode.sort_constructors_first:
+  status: hasFix
+LintCode.sort_pub_dependencies:
+  status: needsEvaluation
+LintCode.sort_unnamed_constructors_first:
+  status: hasFix
+LintCode.super_goes_last:
+  status: needsEvaluation
+LintCode.test_types_in_equals:
+  status: needsEvaluation
+LintCode.throw_in_finally:
+  status: needsEvaluation
+LintCode.tighten_type_of_initializing_formals:
+  status: needsEvaluation
+LintCode.type_annotate_public_apis:
+  status: hasFix
+LintCode.type_init_formals:
+  status: hasFix
+LintCode.unawaited_futures:
+  status: hasFix
+LintCode.unnecessary_await_in_return:
+  status: needsEvaluation
+LintCode.unnecessary_brace_in_string_interps:
+  status: hasFix
+LintCode.unnecessary_const:
+  status: hasFix
+LintCode.unnecessary_constructor_name:
+  status: hasFix
+LintCode.unnecessary_final:
+  status: hasFix
+LintCode.unnecessary_getters_setters:
+  status: hasFix
+LintCode.unnecessary_lambdas:
+  status: hasFix
+LintCode.unnecessary_late:
   status: needsFix
-  issue: https://github.com/dart-lang/sdk/issues/47953
-LintNames.sort_unnamed_constructors_first:
-  status: needsEvaluation
-LintNames.super_goes_last:
-  status: needsEvaluation
-LintNames.test_types_in_equals:
-  status: needsEvaluation
-LintNames.throw_in_finally:
-  status: needsEvaluation
-LintNames.tighten_type_of_initializing_formals:
-  status: needsEvaluation
-LintNames.type_annotate_public_apis:
+LintCode.unnecessary_new:
   status: hasFix
-LintNames.type_init_formals:
-  status: hasFix
-LintNames.unawaited_futures:
-  status: hasFix
-LintNames.unnecessary_await_in_return:
-  status: needsEvaluation
-LintNames.unnecessary_brace_in_string_interps:
-  status: hasFix
-LintNames.unnecessary_const:
-  status: hasFix
-LintNames.unnecessary_constructor_name:
-  status: hasFix
-LintNames.unnecessary_final:
-  status: hasFix
-LintNames.unnecessary_getters_setters:
-  status: hasFix
-LintNames.unnecessary_lambdas:
-  status: hasFix
-LintNames.unnecessary_late:
+LintCode.unnecessary_null_aware_assignments:
   status: needsFix
-LintNames.unnecessary_new:
+LintCode.unnecessary_null_checks:
+  status: needsEvaluation
+LintCode.unnecessary_null_in_if_null_operators:
   status: hasFix
-LintNames.unnecessary_null_aware_assignments:
-  status: needsFix
-LintNames.unnecessary_null_checks:
-  status: needsEvaluation
-LintNames.unnecessary_null_in_if_null_operators:
+LintCode.unnecessary_nullable_for_final_variable_declarations:
   status: hasFix
-LintNames.unnecessary_nullable_for_final_variable_declarations:
+LintCode.unnecessary_overrides:
   status: hasFix
-LintNames.unnecessary_overrides:
+LintCode.unnecessary_parenthesis:
   status: hasFix
-LintNames.unnecessary_parenthesis:
+LintCode.unnecessary_raw_strings:
   status: hasFix
-LintNames.unnecessary_raw_strings:
+LintCode.unnecessary_statements:
+  status: needsEvaluation
+LintCode.unnecessary_string_escapes:
   status: hasFix
-LintNames.unnecessary_statements:
-  status: needsEvaluation
-LintNames.unnecessary_string_escapes:
+LintCode.unnecessary_string_interpolations:
   status: hasFix
-LintNames.unnecessary_string_interpolations:
+LintCode.unnecessary_this:
   status: hasFix
-LintNames.unnecessary_this:
+LintCode.unrelated_type_equality_checks:
+  status: needsEvaluation
+LintCode.unsafe_html_attribute:
+  status: needsEvaluation
+LintCode.unsafe_html_method:
+  status: needsEvaluation
+LintCode.unsafe_html_constructor:
+  status: needsEvaluation
+LintCode.use_build_context_synchronously:
+  status: needsEvaluation
+LintCode.use_decorated_box:
+  status: needsEvaluation
+LintCode.use_full_hex_values_for_flutter_colors:
   status: hasFix
-LintNames.unrelated_type_equality_checks:
-  status: needsEvaluation
-LintNames.unsafe_html:
-  status: needsEvaluation
-LintNames.use_build_context_synchronously:
-  status: needsEvaluation
-LintNames.use_decorated_box:
-  status: needsEvaluation
-LintNames.use_full_hex_values_for_flutter_colors:
+LintCode.use_function_type_syntax_for_parameters:
   status: hasFix
-LintNames.use_function_type_syntax_for_parameters:
+LintCode.use_if_null_to_convert_nulls_to_bools:
+  status: needsEvaluation
+LintCode.use_is_even_rather_than_modulo:
+  status: needsEvaluation
+LintCode.use_key_in_widget_constructors:
   status: hasFix
-LintNames.use_if_null_to_convert_nulls_to_bools:
+LintCode.use_late_for_private_fields_and_variables:
   status: needsEvaluation
-LintNames.use_is_even_rather_than_modulo:
+LintCode.use_named_constants:
   status: needsEvaluation
-LintNames.use_key_in_widget_constructors:
+LintCode.use_raw_strings:
   status: hasFix
-LintNames.use_late_for_private_fields_and_variables:
-  status: needsEvaluation
-LintNames.use_named_constants:
-  status: needsEvaluation
-LintNames.use_raw_strings:
-  status: needsEvaluation
-LintNames.use_rethrow_when_possible:
+LintCode.use_rethrow_when_possible:
   status: hasFix
-LintNames.use_setters_to_change_properties:
+LintCode.use_setters_to_change_properties:
   status: needsEvaluation
-LintNames.use_string_buffers:
+LintCode.use_string_buffers:
   status: needsEvaluation
-LintNames.use_test_throws_matchers:
+LintCode.use_test_throws_matchers:
   status: needsEvaluation
-LintNames.use_to_and_as_if_applicable:
+LintCode.use_to_and_as_if_applicable:
   status: needsEvaluation
-LintNames.valid_regexps:
+LintCode.valid_regexps:
   status: needsEvaluation
-LintNames.void_checks:
+LintCode.void_checks:
   status: needsEvaluation
 ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE:
   status: needsEvaluation
@@ -2152,6 +2167,8 @@
   status: needsEvaluation
 ParserErrorCode.MODIFIER_OUT_OF_ORDER:
   status: needsEvaluation
+ParserErrorCode.MULTIPLE_CLAUSES:
+  status: needsEvaluation
 ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES:
   status: needsEvaluation
 ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES:
@@ -2198,6 +2215,8 @@
   status: needsEvaluation
 ParserErrorCode.NULL_AWARE_CASCADE_OUT_OF_ORDER:
   status: needsEvaluation
+ParserErrorCode.OUT_OF_ORDER_CLAUSES:
+  status: needsEvaluation
 ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT:
   status: needsEvaluation
 ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP:
@@ -2244,6 +2263,8 @@
   status: needsEvaluation
 ParserErrorCode.UNEXPECTED_TOKEN:
   status: needsEvaluation
+ParserErrorCode.UNEXPECTED_TOKENS:
+  status: needsEvaluation
 ParserErrorCode.VAR_AND_TYPE:
   status: needsEvaluation
 ParserErrorCode.VAR_AS_TYPE_NAME:
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index d22c4da..0db91bd 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -2629,7 +2629,7 @@
 ''';
 
     await initializeWithSnippetSupportAndPreviewFlag();
-    final otherFileUri = Uri.file('/other/file.dart');
+    final otherFileUri = Uri.file(convertPath('/other/file.dart'));
     await openFile(otherFileUri, withoutMarkers(content));
     final res = await getCompletion(otherFileUri, positionFromMarker(content));
     final snippetItems = res.where((c) => c.kind == CompletionItemKind.Snippet);
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index 3e5769cc..bdc3ae4 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -26,6 +26,7 @@
 import 'socket_server_test.dart' as socket_server;
 import 'src/test_all.dart' as src;
 import 'tool/test_all.dart' as tool;
+import 'verify_error_fix_status_test.dart' as verify_error_fix_status;
 import 'verify_no_solo_test.dart' as verify_no_solo;
 import 'verify_sorted_test.dart' as verify_sorted;
 import 'verify_tests_test.dart' as verify_tests;
@@ -53,6 +54,7 @@
     socket_server.main();
     src.main();
     tool.main();
+    verify_error_fix_status.main();
     verify_no_solo.main();
     verify_sorted.main();
     verify_tests.main();
diff --git a/pkg/analysis_server/test/verify_error_fix_status_test.dart b/pkg/analysis_server/test/verify_error_fix_status_test.dart
new file mode 100644
index 0000000..9da6ca2
--- /dev/null
+++ b/pkg/analysis_server/test/verify_error_fix_status_test.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:linter/src/rules.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/yaml.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(VerifyErrorFixStatusTest);
+  });
+}
+
+@reflectiveTest
+class VerifyErrorFixStatusTest {
+  PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+
+  void test_statusFile() {
+    var statusInfo = _statusInfo();
+    var errorCodeNames = _errorCodeNames();
+    var lintRuleNames = _lintRuleNames();
+
+    var errorData = _ErrorData();
+    for (var code in errorCodeValues) {
+      var name = code.uniqueName;
+      if (name.startsWith('TodoCode.')) {
+        // To-do codes are ignored.
+      } else {
+        var info = statusInfo.nodes[name];
+        if (info == null) {
+          errorData.codesWithNoEntry.add(name);
+        } else if (info is YamlMap) {
+          var markedAsHavingFix = info['status'] == 'hasFix';
+          var hasFix = _hasCodeFix(code);
+          if (hasFix) {
+            if (!markedAsHavingFix) {
+              errorData.codesWithFixes.add(name);
+            }
+          } else {
+            if (markedAsHavingFix) {
+              errorData.codesWithoutFixes.add(name);
+            }
+          }
+        }
+      }
+    }
+    for (var name in lintRuleNames) {
+      var info = statusInfo.nodes[name];
+      if (info == null) {
+        errorData.codesWithNoEntry.add(name);
+      } else if (info is YamlMap) {
+        var markedAsHavingFix = info['status'] == 'hasFix';
+        var hasFix = _hasLintFix(name);
+        if (hasFix) {
+          if (!markedAsHavingFix) {
+            errorData.codesWithFixes.add(name);
+          }
+        } else {
+          if (markedAsHavingFix) {
+            errorData.codesWithoutFixes.add(name);
+          }
+        }
+      }
+    }
+
+    for (var key in statusInfo.keys) {
+      if (key is String) {
+        if (!errorCodeNames.contains(key) && !lintRuleNames.contains(key)) {
+          errorData.entriesWithNoCode.add(key);
+        }
+      }
+    }
+
+    if (errorData.isNotEmpty) {
+      fail(_failureMessage(errorData));
+    }
+  }
+
+  /// Return the unique names of the error codes.
+  Set<String> _errorCodeNames() {
+    var codes = errorCodeValues;
+    var codeNames = <String>{};
+    for (var code in codes) {
+      codeNames.add(code.uniqueName);
+    }
+    return codeNames;
+  }
+
+  /// Return a failure message composed from the given lists.
+  String _failureMessage(_ErrorData errorData) {
+    var buffer = StringBuffer();
+    var needsBlankLine = false;
+    if (errorData.codesWithNoEntry.isNotEmpty) {
+      buffer.writeln('Add the following entries:');
+      buffer.writeln();
+      for (var code in errorData.codesWithNoEntry) {
+        buffer.writeln('$code:');
+        buffer.writeln('  status: needsEvaluation');
+      }
+      needsBlankLine = true;
+    }
+    if (errorData.entriesWithNoCode.isNotEmpty) {
+      if (needsBlankLine) {
+        buffer.writeln();
+      }
+      buffer.writeln('Remove the following entries:');
+      for (var code in errorData.entriesWithNoCode) {
+        buffer.writeln('- $code');
+      }
+      needsBlankLine = true;
+    }
+    if (errorData.codesWithFixes.isNotEmpty) {
+      if (needsBlankLine) {
+        buffer.writeln();
+      }
+      buffer.writeln('Mark the following entries as having fixes:');
+      for (var code in errorData.codesWithFixes) {
+        buffer.writeln('- $code');
+      }
+      needsBlankLine = true;
+    }
+    if (errorData.codesWithoutFixes.isNotEmpty) {
+      if (needsBlankLine) {
+        buffer.writeln();
+      }
+      buffer.writeln('Mark the following entries as not having fixes:');
+      for (var code in errorData.codesWithoutFixes) {
+        buffer.writeln('- $code');
+      }
+      needsBlankLine = true;
+    }
+    return buffer.toString();
+  }
+
+  /// Return `true` if the given error [code] has a fix associated with it.
+  bool _hasCodeFix(ErrorCode code) {
+    var producers = FixProcessor.nonLintProducerMap[code];
+    if (producers != null) {
+      return true;
+    }
+    var multiProducers = FixProcessor.nonLintMultiProducerMap[code];
+    if (multiProducers != null) {
+      for (var producer in multiProducers) {
+        if (producer is! DataDriven) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /// Return `true` if the lint with the given name has a fix associated with
+  /// it.
+  bool _hasLintFix(String codeName) {
+    var name = codeName.substring('LintCode.'.length);
+    var producers = FixProcessor.lintProducerMap[name];
+    return producers != null;
+  }
+
+  /// Return the unique names of the lint rules.
+  Set<String> _lintRuleNames() {
+    registerLintRules();
+    var ruleNames = <String>{};
+    for (var rule in Registry.ruleRegistry.rules) {
+      for (var code in rule.lintCodes) {
+        ruleNames.add(code.uniqueName);
+      }
+    }
+    return ruleNames;
+  }
+
+  /// Return the path to the file containing the status information.
+  String _statusFilePath() {
+    var pathContext = resourceProvider.pathContext;
+    var packageRoot = pathContext.normalize(package_root.packageRoot);
+    return pathContext.join(packageRoot, 'analysis_server', 'lib', 'src',
+        'services', 'correction', 'error_fix_status.yaml');
+  }
+
+  /// Return the content of the file containing the status information, parsed
+  /// as a YAML map.
+  YamlMap _statusInfo() {
+    var statusFile = resourceProvider.getFile(_statusFilePath());
+    var document = loadYamlDocument(statusFile.readAsStringSync());
+    var statusInfo = document.contents;
+    if (statusInfo is! YamlMap) {
+      fail('Expected a YamlMap, found ${statusInfo.runtimeType}');
+    }
+    return statusInfo;
+  }
+}
+
+class _ErrorData {
+  final List<String> codesWithFixes = [];
+  final List<String> codesWithNoEntry = [];
+  final List<String> codesWithoutFixes = [];
+  final List<String> entriesWithNoCode = [];
+
+  bool get isNotEmpty =>
+      codesWithFixes.isNotEmpty ||
+      codesWithNoEntry.isNotEmpty ||
+      codesWithoutFixes.isNotEmpty ||
+      entriesWithNoCode.isNotEmpty;
+}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e57f2658..060903e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -269,11 +269,6 @@
     required List<DartType> typeArguments,
     required NullabilitySuffix nullabilitySuffix,
   }) {
-    if (typeArguments.length != typeParameters.length) {
-      var ta = 'typeArguments.length (${typeArguments.length})';
-      var tp = 'typeParameters.length (${typeParameters.length})';
-      throw ArgumentError('$ta != $tp');
-    }
     return InterfaceTypeImpl(
       element: this,
       typeArguments: typeArguments,
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index b367dd1..94ec607 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -454,10 +454,19 @@
     required this.typeArguments,
     required this.nullabilitySuffix,
     InstantiatedTypeAliasElement? alias,
-  }) : super(
-          element,
-          alias: alias,
-        );
+  }) : super(element, alias: alias) {
+    var typeParameters = element.typeParameters;
+    if (typeArguments.length != typeParameters.length) {
+      throw ArgumentError(
+        '[typeParameters.length: ${typeParameters.length}]'
+        '[typeArguments.length: ${typeArguments.length}]'
+        '[element: $element]'
+        '[reference: ${element is ClassElementImpl ? element.reference : null}]'
+        '[typeParameters: $typeParameters]'
+        '[typeArguments: $typeArguments]',
+      );
+    }
+  }
 
   @override
   List<PropertyAccessorElement> get accessors {
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 36bdc90..c1aa179 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -10,10 +10,11 @@
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:path/path.dart' as p;
-import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../util/feature_sets.dart';
+
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UtilitiesTest);
@@ -91,10 +92,7 @@
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: Version.parse('2.9.0'),
-      flags: [],
-    );
+    var featureSet = FeatureSets.language_2_9;
     expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
     ParseStringResult result = _withMemoryFile(
         content,
@@ -180,10 +178,7 @@
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: Version.parse('2.9.0'),
-      flags: [],
-    );
+    var featureSet = FeatureSets.language_2_9;
     expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
     ParseStringResult result = parseString(
         content: content, throwIfDiagnostics: false, featureSet: featureSet);
diff --git a/pkg/analyzer/test/generated/class_member_parser_test.dart b/pkg/analyzer/test/generated/class_member_parser_test.dart
index fe8509a..1917bae 100644
--- a/pkg/analyzer/test/generated/class_member_parser_test.dart
+++ b/pkg/analyzer/test/generated/class_member_parser_test.dart
@@ -23,8 +23,8 @@
     implements AbstractParserViaProxyTestCase {
   void test_parse_member_called_late() {
     var unit = parseCompilationUnit(
-        'class C { void late() { new C().late(); } }',
-        featureSet: nonNullable);
+      'class C { void late() { new C().late(); } }',
+    );
     var declaration = unit.declarations[0] as ClassDeclaration;
     var method = declaration.members[0] as MethodDeclaration;
 
@@ -380,7 +380,6 @@
   void test_parseClassMember_finalAndCovariantLateWithInitializer() {
     createParser(
       'covariant late final int f = 0;',
-      featureSet: nonNullable,
     );
     parser.parseClassMember('C');
     assertErrors(errors: [
@@ -1438,7 +1437,7 @@
   }
 
   void test_parseField_abstract() {
-    createParser('abstract int i;', featureSet: nonNullable);
+    createParser('abstract int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1448,7 +1447,7 @@
   }
 
   void test_parseField_abstract_external() {
-    createParser('abstract external int i;', featureSet: nonNullable);
+    createParser('abstract external int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1461,7 +1460,7 @@
   }
 
   void test_parseField_abstract_late() {
-    createParser('abstract late int? i;', featureSet: nonNullable);
+    createParser('abstract late int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1473,7 +1472,7 @@
   }
 
   void test_parseField_abstract_late_final() {
-    createParser('abstract late final int? i;', featureSet: nonNullable);
+    createParser('abstract late final int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1485,7 +1484,7 @@
   }
 
   void test_parseField_abstract_static() {
-    createParser('abstract static int? i;', featureSet: nonNullable);
+    createParser('abstract static int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1497,7 +1496,7 @@
   }
 
   void test_parseField_const_late() {
-    createParser('const late T f = 0;', featureSet: nonNullable);
+    createParser('const late T f = 0;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1523,7 +1522,7 @@
   }
 
   void test_parseField_external() {
-    createParser('external int i;', featureSet: nonNullable);
+    createParser('external int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1533,7 +1532,7 @@
   }
 
   void test_parseField_external_abstract() {
-    createParser('external abstract int i;', featureSet: nonNullable);
+    createParser('external abstract int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1546,7 +1545,7 @@
   }
 
   void test_parseField_external_late() {
-    createParser('external late int? i;', featureSet: nonNullable);
+    createParser('external late int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1558,7 +1557,7 @@
   }
 
   void test_parseField_external_late_final() {
-    createParser('external late final int? i;', featureSet: nonNullable);
+    createParser('external late final int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1570,7 +1569,7 @@
   }
 
   void test_parseField_external_static() {
-    createParser('external static int? i;', featureSet: nonNullable);
+    createParser('external static int? i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1580,7 +1579,7 @@
   }
 
   void test_parseField_final_late() {
-    createParser('final late T f;', featureSet: nonNullable);
+    createParser('final late T f;');
     ClassMember member = parser.parseClassMember('C');
     assertErrors(errors: [
       expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 6, 4),
@@ -1606,7 +1605,7 @@
   }
 
   void test_parseField_late() {
-    createParser('late T f;', featureSet: nonNullable);
+    createParser('late T f;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1630,7 +1629,7 @@
   }
 
   void test_parseField_late_const() {
-    createParser('late const T f = 0;', featureSet: nonNullable);
+    createParser('late const T f = 0;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
@@ -1656,7 +1655,7 @@
   }
 
   void test_parseField_late_final() {
-    createParser('late final T f;', featureSet: nonNullable);
+    createParser('late final T f;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1680,7 +1679,7 @@
   }
 
   void test_parseField_late_var() {
-    createParser('late var f;', featureSet: nonNullable);
+    createParser('late var f;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     expect(member, isFieldDeclaration);
@@ -1703,7 +1702,7 @@
   }
 
   void test_parseField_non_abstract() {
-    createParser('int i;', featureSet: nonNullable);
+    createParser('int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1713,7 +1712,7 @@
   }
 
   void test_parseField_non_external() {
-    createParser('int i;', featureSet: nonNullable);
+    createParser('int i;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertNoErrors();
@@ -1723,7 +1722,7 @@
   }
 
   void test_parseField_var_late() {
-    createParser('var late f;', featureSet: nonNullable);
+    createParser('var late f;');
     ClassMember member = parser.parseClassMember('C');
     expect(member, isNotNull);
     assertErrors(errors: [
diff --git a/pkg/analyzer/test/generated/expression_parser_test.dart b/pkg/analyzer/test/generated/expression_parser_test.dart
index ec3df10..5749b4d 100644
--- a/pkg/analyzer/test/generated/expression_parser_test.dart
+++ b/pkg/analyzer/test/generated/expression_parser_test.dart
@@ -4,14 +4,12 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
     show AbstractScanner;
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast.dart'
     show InstanceCreationExpressionImpl;
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:pub_semver/src/version.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -27,11 +25,6 @@
 /// Tests of the fasta parser based on [ExpressionParserTestMixin].
 @reflectiveTest
 class ExpressionParserTest extends FastaParserTestCase {
-  final beforeUiAsCode = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: Version.parse('2.2.0'),
-    flags: [],
-  );
-
   void test_binaryExpression_allOperators() {
     // https://github.com/dart-lang/sdk/issues/36255
     for (TokenType type in TokenType.all) {
diff --git a/pkg/analyzer/test/generated/extension_methods_parser_test.dart b/pkg/analyzer/test/generated/extension_methods_parser_test.dart
index a7409c6..5c2a5c1 100644
--- a/pkg/analyzer/test/generated/extension_methods_parser_test.dart
+++ b/pkg/analyzer/test/generated/extension_methods_parser_test.dart
@@ -2,13 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:pub_semver/src/version.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 
 main() {
@@ -153,8 +152,7 @@
   }
 
   void test_parse_toplevel_member_called_late_calling_self() {
-    var unit = parseCompilationUnit('void late() { late(); }',
-        featureSet: nonNullable);
+    var unit = parseCompilationUnit('void late() { late(); }');
     var method = unit.declarations[0] as FunctionDeclaration;
 
     expect(method.documentationComment, isNull);
@@ -228,10 +226,7 @@
         expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 0, 9),
         expectedError(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 15, 1)
       ],
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: Version.parse('2.3.0'),
-        flags: [],
-      ),
+      featureSet: FeatureSets.language_2_3,
     );
   }
 
diff --git a/pkg/analyzer/test/generated/formal_parameter_parser_test.dart b/pkg/analyzer/test/generated/formal_parameter_parser_test.dart
index 0b5d7b9..64b9988 100644
--- a/pkg/analyzer/test/generated/formal_parameter_parser_test.dart
+++ b/pkg/analyzer/test/generated/formal_parameter_parser_test.dart
@@ -9,6 +9,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../util/ast_type_matchers.dart';
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 import 'test_support.dart';
 
@@ -34,7 +35,7 @@
     } else {
       fail('$kind');
     }
-    createParser(parametersCode, featureSet: nonNullable);
+    createParser(parametersCode);
     FormalParameterList list =
         parserProxy.parseFormalParameterList(inFunctionType: false);
     assertErrors(errors: errors);
@@ -77,7 +78,7 @@
   void test_functionTyped_named_nullable_disabled() {
     ParameterKind kind = ParameterKind.NAMED;
     var defaultParameter = parseFormalParameter('a()? : null', kind,
-            featureSet: preNonNullable,
+            featureSet: FeatureSets.language_2_9,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as DefaultFormalParameter;
     var functionParameter =
@@ -96,7 +97,7 @@
   void test_functionTyped_positional_nullable_disabled() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     var defaultParameter = parseFormalParameter('a()? = null', kind,
-            featureSet: preNonNullable,
+            featureSet: FeatureSets.language_2_9,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as DefaultFormalParameter;
     var functionParameter =
@@ -115,7 +116,7 @@
   void test_functionTyped_required_nullable_disabled() {
     ParameterKind kind = ParameterKind.REQUIRED;
     var functionParameter = parseFormalParameter('a()?', kind,
-            featureSet: preNonNullable,
+            featureSet: FeatureSets.language_2_9,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as FunctionTypedFormalParameter;
     expect(functionParameter.returnType, isNull);
diff --git a/pkg/analyzer/test/generated/function_reference_parser_test.dart b/pkg/analyzer/test/generated/function_reference_parser_test.dart
index 07f8755..6fd9460 100644
--- a/pkg/analyzer/test/generated/function_reference_parser_test.dart
+++ b/pkg/analyzer/test/generated/function_reference_parser_test.dart
@@ -7,6 +7,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 
 main() {
@@ -36,68 +37,54 @@
   }
 
   void test_feature_disabled() {
-    expect_f_a_b((parseStatement('f<a, b>;', featureSet: preConstructorTearoffs)
-            as ExpressionStatement)
-        .expression);
+    expect_f_a_b(
+        (parseStatement('f<a, b>;', featureSet: FeatureSets.language_2_13)
+                as ExpressionStatement)
+            .expression);
     listener.assertErrors([
       expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 1, 6),
     ]);
   }
 
   void test_followingToken_accepted_closeBrace() {
-    expect_f_a_b((parseExpression('{f<a, b>}', featureSet: constructorTearoffs)
-            as SetOrMapLiteral)
-        .elements[0]);
+    expect_f_a_b((parseExpression('{f<a, b>}') as SetOrMapLiteral).elements[0]);
   }
 
   void test_followingToken_accepted_closeBracket() {
-    expect_f_a_b((parseExpression('[f<a, b>]', featureSet: constructorTearoffs)
-            as ListLiteral)
-        .elements[0]);
+    expect_f_a_b((parseExpression('[f<a, b>]') as ListLiteral).elements[0]);
   }
 
   void test_followingToken_accepted_closeParen() {
-    expect_f_a_b((parseExpression('g(f<a, b>)', featureSet: constructorTearoffs)
-            as MethodInvocation)
+    expect_f_a_b((parseExpression('g(f<a, b>)') as MethodInvocation)
         .argumentList
         .arguments[0]);
   }
 
   void test_followingToken_accepted_colon() {
-    expect_f_a_b(
-        ((parseExpression('{f<a, b>: null}', featureSet: constructorTearoffs)
-                    as SetOrMapLiteral)
-                .elements[0] as MapLiteralEntry)
-            .key);
+    expect_f_a_b(((parseExpression('{f<a, b>: null}') as SetOrMapLiteral)
+            .elements[0] as MapLiteralEntry)
+        .key);
   }
 
   void test_followingToken_accepted_comma() {
     expect_f_a_b(
-        (parseExpression('[f<a, b>, null]', featureSet: constructorTearoffs)
-                as ListLiteral)
-            .elements[0]);
+        (parseExpression('[f<a, b>, null]') as ListLiteral).elements[0]);
   }
 
   void test_followingToken_accepted_equals() {
     expect_f_a_b(
-        (parseExpression('f<a, b> == null', featureSet: constructorTearoffs)
-                as BinaryExpression)
-            .leftOperand);
+        (parseExpression('f<a, b> == null') as BinaryExpression).leftOperand);
   }
 
   void test_followingToken_accepted_not_equals() {
     expect_f_a_b(
-        (parseExpression('f<a, b> != null', featureSet: constructorTearoffs)
-                as BinaryExpression)
-            .leftOperand);
+        (parseExpression('f<a, b> != null') as BinaryExpression).leftOperand);
   }
 
   void test_followingToken_accepted_openParen() {
     // This is a special case because when a `(` follows `<typeArguments>` it is
     // parsed as a MethodInvocation rather than a GenericInstantiation.
-    var methodInvocation =
-        parseExpression('f<a, b>()', featureSet: constructorTearoffs)
-            as MethodInvocation;
+    var methodInvocation = parseExpression('f<a, b>()') as MethodInvocation;
     expect(methodInvocation.methodName.name, 'f');
     var typeArgs = methodInvocation.typeArguments!.arguments;
     expect(typeArgs, hasLength(2));
@@ -110,8 +97,7 @@
     // This is a special case because `f<a, b>.methodName(...)` is parsed as an
     // InstanceCreationExpression.
     var instanceCreationExpression =
-        parseExpression('f<a, b>.toString()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('f<a, b>.toString()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var type = constructorName.type;
     expect((type.name as SimpleIdentifier).name, 'f');
@@ -125,81 +111,60 @@
 
   void test_followingToken_accepted_period_methodInvocation_generic() {
     expect_f_a_b(
-        (parseExpression('f<a, b>.foo<c>()', featureSet: constructorTearoffs)
-                as MethodInvocation)
-            .target!);
+        (parseExpression('f<a, b>.foo<c>()') as MethodInvocation).target!);
   }
 
   void test_followingToken_accepted_period_propertyAccess() {
     expect_f_a_b(
-        (parseExpression('f<a, b>.hashCode', featureSet: constructorTearoffs)
-                as PropertyAccess)
-            .target!);
+        (parseExpression('f<a, b>.hashCode') as PropertyAccess).target!);
   }
 
   void test_followingToken_accepted_semicolon() {
-    expect_f_a_b((parseStatement('f<a, b>;', featureSet: constructorTearoffs)
-            as ExpressionStatement)
-        .expression);
+    expect_f_a_b(
+        (parseStatement('f<a, b>;') as ExpressionStatement).expression);
     listener.assertNoErrors();
   }
 
   void test_followingToken_rejected_ampersand() {
-    expect_two_args(parseExpression('f(a<b,c>&d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>&d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_as() {
-    expect_two_args(
-        parseExpression('f(a<b,c>as)', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>as)') as MethodInvocation);
   }
 
   void test_followingToken_rejected_asterisk() {
-    expect_two_args(parseExpression('f(a<b,c>*d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>*d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_bang_openBracket() {
-    expect_two_args(
-        parseExpression('f(a<b,c>![d])', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>![d])') as MethodInvocation);
   }
 
   void test_followingToken_rejected_bang_paren() {
-    expect_two_args(
-        parseExpression('f(a<b,c>!(d))', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>!(d))') as MethodInvocation);
   }
 
   void test_followingToken_rejected_bar() {
-    expect_two_args(parseExpression('f(a<b,c>|d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>|d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_caret() {
-    expect_two_args(parseExpression('f(a<b,c>^d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>^d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_is() {
-    var methodInvocation = parseExpression('f(a<b,c> is int)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression('f(a<b,c> is int)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
+    ]) as MethodInvocation;
     var arguments = methodInvocation.argumentList.arguments;
     expect(arguments, hasLength(2));
     expect(arguments[0], TypeMatcher<BinaryExpression>());
@@ -210,22 +175,18 @@
     // Note: in principle we could parse this as a generic instantiation of a
     // generic instantiation, but such an expression would be meaningless so we
     // reject it at the parser level.
-    parseExpression('f<a><b>', featureSet: constructorTearoffs, errors: [
+    parseExpression('f<a><b>', errors: [
       expectedError(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, 3, 1),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 0),
     ]);
   }
 
   void test_followingToken_rejected_minus() {
-    expect_two_args(
-        parseExpression('f(a<b,c>-d)', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>-d)') as MethodInvocation);
   }
 
   void test_followingToken_rejected_openBracket() {
-    expect_two_args(
-        parseExpression('f(a<b,c>[d])', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>[d])') as MethodInvocation);
   }
 
   void test_followingToken_rejected_openBracket_error() {
@@ -233,34 +194,25 @@
     // `<` and `>` as delimiting type arguments, but the parser doesn't have
     // enough lookahead to see that this is the only possible error-free parse;
     // it commits to interpreting `<` and `>` as operators when it sees the `[`.
-    expect_two_args(parseExpression('f(a<b,c>[d]>e)',
-        featureSet: constructorTearoffs,
-        errors: [
-          expectedError(
-              ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, 11, 1),
-        ]) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>[d]>e)', errors: [
+      expectedError(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, 11, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_openBracket_unambiguous() {
-    expect_two_args(
-        parseExpression('f(a<b,c>[d, e])', featureSet: constructorTearoffs)
-            as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>[d, e])') as MethodInvocation);
   }
 
   void test_followingToken_rejected_percent() {
-    expect_two_args(parseExpression('f(a<b,c>%d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>%d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_period_period() {
-    var methodInvocation = parseExpression('f(a<b,c>..toString())',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression('f(a<b,c>..toString())', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
+    ]) as MethodInvocation;
     var arguments = methodInvocation.argumentList.arguments;
     expect(arguments, hasLength(2));
     expect(arguments[0], TypeMatcher<BinaryExpression>());
@@ -268,19 +220,15 @@
   }
 
   void test_followingToken_rejected_plus() {
-    expect_two_args(parseExpression('f(a<b,c>+d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>+d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_question() {
-    var methodInvocation = parseExpression('f(a<b,c> ? null : null)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression('f(a<b,c> ? null : null)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 1),
+    ]) as MethodInvocation;
     var arguments = methodInvocation.argumentList.arguments;
     expect(arguments, hasLength(2));
     expect(arguments[0], TypeMatcher<BinaryExpression>());
@@ -288,28 +236,22 @@
   }
 
   void test_followingToken_rejected_question_period_methodInvocation() {
-    expect_two_args(parseExpression('f(a<b,c>?.toString())',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>?.toString())', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_question_period_methodInvocation_generic() {
-    expect_two_args(parseExpression('f(a<b,c>?.foo<c>())',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>?.foo<c>())', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_question_period_period() {
-    var methodInvocation = parseExpression('f(a<b,c>?..toString())',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 8),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression('f(a<b,c>?..toString())', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 8),
+    ]) as MethodInvocation;
     var arguments = methodInvocation.argumentList.arguments;
     expect(arguments, hasLength(3));
     expect(arguments[0], TypeMatcher<BinaryExpression>());
@@ -318,43 +260,33 @@
   }
 
   void test_followingToken_rejected_question_period_propertyAccess() {
-    expect_two_args(parseExpression('f(a<b,c>?.hashCode)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>?.hashCode)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_question_question() {
-    expect_two_args(parseExpression('f(a<b,c> ?? d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c> ?? d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_slash() {
-    expect_two_args(parseExpression('f(a<b,c>/d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>/d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+    ]) as MethodInvocation);
   }
 
   void test_followingToken_rejected_tilde_slash() {
-    expect_two_args(parseExpression('f(a<b,c>~/d)',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
-        ],
-        featureSet: constructorTearoffs) as MethodInvocation);
+    expect_two_args(parseExpression('f(a<b,c>~/d)', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
+    ]) as MethodInvocation);
   }
 
   void test_functionReference_after_indexExpression() {
     // Note: this is not legal Dart, but it's important that we do error
     // recovery and don't crash the parser.
-    var functionReference =
-        parseExpression('x[0]<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+    var functionReference = parseExpression('x[0]<a, b>') as FunctionReference;
     expect(functionReference.function, TypeMatcher<IndexExpression>());
     var typeArgs = functionReference.typeArguments!.arguments;
     expect(typeArgs, hasLength(2));
@@ -365,9 +297,7 @@
   void test_functionReference_after_indexExpression_bang() {
     // Note: this is not legal Dart, but it's important that we do error
     // recovery and don't crash the parser.
-    var functionReference =
-        parseExpression('x[0]!<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+    var functionReference = parseExpression('x[0]!<a, b>') as FunctionReference;
     expect(functionReference.function, TypeMatcher<PostfixExpression>());
     var typeArgs = functionReference.typeArguments!.arguments;
     expect(typeArgs, hasLength(2));
@@ -379,8 +309,7 @@
     // Note: this is not legal Dart, but it's important that we do error
     // recovery and don't crash the parser.
     var functionReference =
-        parseExpression('x[0]()<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+        parseExpression('x[0]()<a, b>') as FunctionReference;
     expect(functionReference.function,
         TypeMatcher<FunctionExpressionInvocation>());
     var typeArgs = functionReference.typeArguments!.arguments;
@@ -392,9 +321,7 @@
   void test_functionReference_after_indexExpression_nullAware() {
     // Note: this is not legal Dart, but it's important that we do error
     // recovery and don't crash the parser.
-    var functionReference =
-        parseExpression('x?[0]<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+    var functionReference = parseExpression('x?[0]<a, b>') as FunctionReference;
     expect(functionReference.function, TypeMatcher<IndexExpression>());
     var typeArgs = functionReference.typeArguments!.arguments;
     expect(typeArgs, hasLength(2));
@@ -403,9 +330,7 @@
   }
 
   void test_methodTearoff() {
-    var functionReference =
-        parseExpression('f().m<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+    var functionReference = parseExpression('f().m<a, b>') as FunctionReference;
     var function = functionReference.function as PropertyAccess;
     var target = function.target as MethodInvocation;
     expect(target.methodName.name, 'f');
@@ -418,8 +343,7 @@
 
   void test_methodTearoff_cascaded() {
     var cascadeExpression =
-        parseExpression('f()..m<a, b>', featureSet: constructorTearoffs)
-            as CascadeExpression;
+        parseExpression('f()..m<a, b>') as CascadeExpression;
     var functionReference =
         cascadeExpression.cascadeSections[0] as FunctionReference;
     var function = functionReference.function as PropertyAccess;
@@ -433,8 +357,7 @@
 
   void test_prefixedIdentifier() {
     var functionReference =
-        parseExpression('prefix.f<a, b>', featureSet: constructorTearoffs)
-            as FunctionReference;
+        parseExpression('prefix.f<a, b>') as FunctionReference;
     var function = functionReference.function as PrefixedIdentifier;
     expect(function.prefix.name, 'prefix');
     expect(function.identifier.name, 'f');
@@ -445,8 +368,8 @@
   }
 
   void test_three_identifiers() {
-    var functionReference = parseExpression('prefix.ClassName.m<a, b>',
-        featureSet: constructorTearoffs) as FunctionReference;
+    var functionReference =
+        parseExpression('prefix.ClassName.m<a, b>') as FunctionReference;
     var function = functionReference.function as PropertyAccess;
     var target = function.target as PrefixedIdentifier;
     expect(target.prefix.name, 'prefix');
diff --git a/pkg/analyzer/test/generated/generic_metadata_parser_test.dart b/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
index 9e967e9..cfaf099 100644
--- a/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
+++ b/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
@@ -2,13 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
-import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 import 'test_support.dart';
 
@@ -30,10 +29,7 @@
     return parseCompilationUnit(
       content,
       errors: combinedErrors,
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: Version.parse('2.12.0'),
-        flags: [],
-      ),
+      featureSet: FeatureSets.language_2_12,
     );
   }
 }
diff --git a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
index a7e7d3d..7beae7f 100644
--- a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
+++ b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
@@ -7,6 +7,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 
 main() {
@@ -21,32 +22,27 @@
   void test_constructor_field_initializer() {
     // Even though `C() : this.new();` is allowed, `C() : this.new = ...;`
     // should not be.
-    parseCompilationUnit(
-        '''
+    parseCompilationUnit('''
 class C {
   C() : this.new = null;
 }
-''',
-        featureSet: constructorTearoffs,
-        errors: [
-          expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 4),
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 23, 3),
-          expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 23, 3),
-          expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 23, 3),
-          expectedError(ParserErrorCode.MISSING_KEYWORD_OPERATOR, 27, 1),
-          expectedError(ParserErrorCode.INVALID_OPERATOR, 27, 1),
-          expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 27, 1),
-          expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 4),
-          expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 29, 4),
-          expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 33, 1),
-        ]);
+''', errors: [
+      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 4),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 23, 3),
+      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 23, 3),
+      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 23, 3),
+      expectedError(ParserErrorCode.MISSING_KEYWORD_OPERATOR, 27, 1),
+      expectedError(ParserErrorCode.INVALID_OPERATOR, 27, 1),
+      expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 27, 1),
+      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 4),
+      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 29, 4),
+      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 33, 1),
+    ]);
   }
 
   void test_constructor_invocation_const() {
     var instanceCreationExpression =
-        parseExpression('const C.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('const C.new()') as InstanceCreationExpression;
     // Parsing treats `new` as an identifier, so `D.new` is classified as a
     // type.  Resolution will change the type to `D` and the name to `new` if
     // appropriate.
@@ -61,8 +57,7 @@
 
   void test_constructor_invocation_const_generic() {
     var instanceCreationExpression =
-        parseExpression('const C<int>.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('const C<int>.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as SimpleIdentifier;
     expect(typeName.name, 'C');
@@ -73,8 +68,7 @@
 
   void test_constructor_invocation_const_prefixed() {
     var instanceCreationExpression =
-        parseExpression('const prefix.C.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('const prefix.C.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as PrefixedIdentifier;
     expect(typeName.prefix.name, 'prefix');
@@ -86,8 +80,8 @@
 
   void test_constructor_invocation_const_prefixed_generic() {
     var instanceCreationExpression = parseExpression(
-        'const prefix.C<int>.new()',
-        featureSet: constructorTearoffs) as InstanceCreationExpression;
+      'const prefix.C<int>.new()',
+    ) as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as PrefixedIdentifier;
     expect(typeName.prefix.name, 'prefix');
@@ -99,8 +93,7 @@
 
   void test_constructor_invocation_explicit() {
     var instanceCreationExpression =
-        parseExpression('new C.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('new C.new()') as InstanceCreationExpression;
     // Parsing treats `new` as an identifier, so `D.new` is classified as a
     // type.  Resolution will change the type to `D` and the name to `new` if
     // appropriate.
@@ -115,8 +108,7 @@
 
   void test_constructor_invocation_explicit_generic() {
     var instanceCreationExpression =
-        parseExpression('new C<int>.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('new C<int>.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as SimpleIdentifier;
     expect(typeName.name, 'C');
@@ -127,8 +119,7 @@
 
   void test_constructor_invocation_explicit_prefixed() {
     var instanceCreationExpression =
-        parseExpression('new prefix.C.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('new prefix.C.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as PrefixedIdentifier;
     expect(typeName.prefix.name, 'prefix');
@@ -139,8 +130,9 @@
   }
 
   void test_constructor_invocation_explicit_prefixed_generic() {
-    var instanceCreationExpression = parseExpression('new prefix.C<int>.new()',
-        featureSet: constructorTearoffs) as InstanceCreationExpression;
+    var instanceCreationExpression = parseExpression(
+      'new prefix.C<int>.new()',
+    ) as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as PrefixedIdentifier;
     expect(typeName.prefix.name, 'prefix');
@@ -151,9 +143,7 @@
   }
 
   void test_constructor_invocation_implicit() {
-    var methodInvocation =
-        parseExpression('C.new()', featureSet: constructorTearoffs)
-            as MethodInvocation;
+    var methodInvocation = parseExpression('C.new()') as MethodInvocation;
     var target = methodInvocation.target as SimpleIdentifier;
     expect(target.name, 'C');
     expect(methodInvocation.methodName.name, 'new');
@@ -163,8 +153,7 @@
 
   void test_constructor_invocation_implicit_generic() {
     var instanceCreationExpression =
-        parseExpression('C<int>.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('C<int>.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as SimpleIdentifier;
     expect(typeName.name, 'C');
@@ -175,8 +164,7 @@
 
   void test_constructor_invocation_implicit_prefixed() {
     var methodInvocation =
-        parseExpression('prefix.C.new()', featureSet: constructorTearoffs)
-            as MethodInvocation;
+        parseExpression('prefix.C.new()') as MethodInvocation;
     var target = methodInvocation.target as PrefixedIdentifier;
     expect(target.prefix.name, 'prefix');
     expect(target.identifier.name, 'C');
@@ -187,8 +175,7 @@
 
   void test_constructor_invocation_implicit_prefixed_generic() {
     var instanceCreationExpression =
-        parseExpression('prefix.C<int>.new()', featureSet: constructorTearoffs)
-            as InstanceCreationExpression;
+        parseExpression('prefix.C<int>.new()') as InstanceCreationExpression;
     var constructorName = instanceCreationExpression.constructorName;
     var typeName = constructorName.type.name as PrefixedIdentifier;
     expect(typeName.prefix.name, 'prefix');
@@ -203,7 +190,7 @@
 class C {
   C.new();
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -216,7 +203,7 @@
   factory C.new() => C._();
   C._();
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members[0] as ConstructorDeclaration;
@@ -224,17 +211,13 @@
   }
 
   void test_constructor_tearoff() {
-    var prefixedIdentifier =
-        parseExpression('C.new', featureSet: constructorTearoffs)
-            as PrefixedIdentifier;
+    var prefixedIdentifier = parseExpression('C.new') as PrefixedIdentifier;
     expect(prefixedIdentifier.prefix.name, 'C');
     expect(prefixedIdentifier.identifier.name, 'new');
   }
 
   void test_constructor_tearoff_generic() {
-    var propertyAccess =
-        parseExpression('C<int>.new', featureSet: constructorTearoffs)
-            as PropertyAccess;
+    var propertyAccess = parseExpression('C<int>.new') as PropertyAccess;
     var target = propertyAccess.target as FunctionReference;
     var className = target.function as SimpleIdentifier;
     expect(className.name, 'C');
@@ -243,8 +226,8 @@
   }
 
   void test_constructor_tearoff_generic_method_invocation() {
-    var methodInvocation = parseExpression('C<int>.new.toString()',
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation =
+        parseExpression('C<int>.new.toString()') as MethodInvocation;
     var target = methodInvocation.target as PropertyAccess;
     var functionReference = target.target as FunctionReference;
     var className = functionReference.function as SimpleIdentifier;
@@ -266,8 +249,7 @@
 
   void test_constructor_tearoff_method_invocation() {
     var methodInvocation =
-        parseExpression('C.new.toString()', featureSet: constructorTearoffs)
-            as MethodInvocation;
+        parseExpression('C.new.toString()') as MethodInvocation;
     var target = methodInvocation.target as PrefixedIdentifier;
     expect(target.prefix.name, 'C');
     expect(target.identifier.name, 'new');
@@ -277,9 +259,7 @@
   }
 
   void test_constructor_tearoff_prefixed() {
-    var propertyAccess =
-        parseExpression('prefix.C.new', featureSet: constructorTearoffs)
-            as PropertyAccess;
+    var propertyAccess = parseExpression('prefix.C.new') as PropertyAccess;
     var target = propertyAccess.target as PrefixedIdentifier;
     expect(target.prefix.name, 'prefix');
     expect(target.identifier.name, 'C');
@@ -287,9 +267,7 @@
   }
 
   void test_constructor_tearoff_prefixed_generic() {
-    var propertyAccess =
-        parseExpression('prefix.C<int>.new', featureSet: constructorTearoffs)
-            as PropertyAccess;
+    var propertyAccess = parseExpression('prefix.C<int>.new') as PropertyAccess;
     var target = propertyAccess.target as FunctionReference;
     var className = target.function as PrefixedIdentifier;
     expect(className.prefix.name, 'prefix');
@@ -299,8 +277,9 @@
   }
 
   void test_constructor_tearoff_prefixed_generic_method_invocation() {
-    var methodInvocation = parseExpression('prefix.C<int>.new.toString()',
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression(
+      'prefix.C<int>.new.toString()',
+    ) as MethodInvocation;
     var target = methodInvocation.target as PropertyAccess;
     var functionReference = target.target as FunctionReference;
     var className = functionReference.function as PrefixedIdentifier;
@@ -314,8 +293,9 @@
   }
 
   void test_constructor_tearoff_prefixed_method_invocation() {
-    var methodInvocation = parseExpression('prefix.C.new.toString()',
-        featureSet: constructorTearoffs) as MethodInvocation;
+    var methodInvocation = parseExpression(
+      'prefix.C.new.toString()',
+    ) as MethodInvocation;
     var target = methodInvocation.target as PropertyAccess;
     var prefixedIdentifier = target.target as PrefixedIdentifier;
     expect(prefixedIdentifier.prefix.name, 'prefix');
@@ -333,7 +313,7 @@
   C.new();
 }
 ''',
-        featureSet: preConstructorTearoffs,
+        featureSet: FeatureSets.language_2_13,
         errors: [
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 3),
         ]);
@@ -348,7 +328,7 @@
 class C {
   factory C() = D.new;
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -369,7 +349,7 @@
 class C {
   factory C() = D<int>.new;
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -386,7 +366,7 @@
 class C {
   factory C() = prefix.D.new;
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -404,7 +384,7 @@
 class C {
   factory C() = prefix.D<int>.new;
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -422,7 +402,7 @@
 class C extends B {
   C() : super.new();
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
@@ -438,7 +418,7 @@
   C.named() : this.new();
   C();
 }
-''', featureSet: constructorTearoffs);
+''');
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members[0] as ConstructorDeclaration;
diff --git a/pkg/analyzer/test/generated/nnbd_parser_test.dart b/pkg/analyzer/test/generated/nnbd_parser_test.dart
index a43a27c..62c9f59 100644
--- a/pkg/analyzer/test/generated/nnbd_parser_test.dart
+++ b/pkg/analyzer/test/generated/nnbd_parser_test.dart
@@ -12,6 +12,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../util/ast_type_matchers.dart';
+import '../util/feature_sets.dart';
 import 'parser_test_base.dart';
 import 'test_support.dart';
 
@@ -201,7 +202,7 @@
   void test_enableNonNullable_false() {
     parseCompilationUnit('main() { x is String? ? (x + y) : z; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 20, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   void test_for() {
@@ -227,7 +228,7 @@
   void test_functionTypedFormalParameter_nullable_disabled() {
     parseCompilationUnit('void f(void p()?) {}',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   test_fuzz_38113() async {
@@ -301,7 +302,7 @@
   void test_indexExpression_nullable_disabled() {
     parseCompilationUnit('main(a) { a?[0]; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 11, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   void test_is_nullable() {
@@ -357,7 +358,7 @@
 main() {
   f(new C());
 }
-''', featureSet: preNonNullable);
+''', featureSet: FeatureSets.language_2_9);
   }
 
   void test_late_as_identifier_optOut() {
@@ -547,7 +548,7 @@
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 5, 1),
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 21, 1),
         ],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
     var function = unit.declarations[0] as FunctionDeclaration;
     var body = function.functionExpression.body as BlockFunctionBody;
     var statement = body.block.statements[0] as VariableDeclarationStatement;
@@ -609,7 +610,7 @@
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 5, 1),
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 21, 1),
         ],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   void test_nullCheckMethodResult() {
@@ -746,7 +747,7 @@
   void test_nullCheckOnLiteral_disabled() {
     parseCompilationUnit('f() { var x = 0!; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   void test_nullCheckOnLiteralDouble() {
@@ -825,7 +826,7 @@
   void test_nullCheckOnValue_disabled() {
     parseCompilationUnit('f(Point p) { var x = p.y! + 7; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 24, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 
   void test_nullCheckParenthesizedExpression() {
@@ -871,6 +872,6 @@
   void test_typeName_nullable_disabled() {
     parseCompilationUnit('int? x;',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 3, 1)],
-        featureSet: preNonNullable);
+        featureSet: FeatureSets.language_2_9);
   }
 }
diff --git a/pkg/analyzer/test/generated/parser_test_base.dart b/pkg/analyzer/test/generated/parser_test_base.dart
index 6db8545..a0251ce 100644
--- a/pkg/analyzer/test/generated/parser_test_base.dart
+++ b/pkg/analyzer/test/generated/parser_test_base.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart' show CompilationUnitImpl;
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
@@ -28,6 +27,7 @@
 import 'package:pub_semver/src/version.dart';
 import 'package:test/test.dart';
 
+import '../util/feature_sets.dart';
 import 'parser_fasta_listener.dart';
 import 'test_support.dart';
 
@@ -221,25 +221,6 @@
     implements AbstractParserTestCase {
   static final List<ErrorCode> NO_ERROR_COMPARISON = <ErrorCode>[];
 
-  final constructorTearoffs = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: ExperimentStatus.currentVersion,
-    flags: [EnableString.constructor_tearoffs],
-  );
-
-  final controlFlow = FeatureSet.latestLanguageVersion();
-
-  final spread = FeatureSet.latestLanguageVersion();
-
-  final nonNullable = FeatureSet.latestLanguageVersion();
-
-  final preConstructorTearoffs = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: Version.parse('2.13.0'), flags: []);
-
-  final preNonNullable = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: Version.parse('2.9.0'),
-    flags: [],
-  );
-
   late ParserProxy parserProxy;
 
   late Token _fastaTokens;
@@ -1171,13 +1152,7 @@
     analyzer.Parser parser = analyzer.Parser(
       source,
       listener,
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.currentVersion,
-        flags: [
-          Feature.enhanced_enums.enableString,
-          Feature.super_parameters.enableString,
-        ],
-      ),
+      featureSet: FeatureSets.latestWithExperiments,
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
     CompilationUnit unit = parser.parseCompilationUnit(result.tokens);
diff --git a/pkg/analyzer/test/generated/recovery_parser_test.dart b/pkg/analyzer/test/generated/recovery_parser_test.dart
index 1ae179e..196e3ca 100644
--- a/pkg/analyzer/test/generated/recovery_parser_test.dart
+++ b/pkg/analyzer/test/generated/recovery_parser_test.dart
@@ -880,9 +880,7 @@
   }
 
   void test_incompleteForEach2() {
-    var statement =
-        parseStatement('for (String item i) {}', featureSet: controlFlow)
-            as ForStatement;
+    var statement = parseStatement('for (String item i) {}') as ForStatement;
     listener.assertErrors([
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 4),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)
diff --git a/pkg/analyzer/test/generated/simple_parser_test.dart b/pkg/analyzer/test/generated/simple_parser_test.dart
index a2c57e7..6237d6f 100644
--- a/pkg/analyzer/test/generated/simple_parser_test.dart
+++ b/pkg/analyzer/test/generated/simple_parser_test.dart
@@ -1990,8 +1990,8 @@
   }
 
   void test_parseVariableDeclaration_final_late() {
-    var statement = parseStatement('final late a;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement =
+        parseStatement('final late a;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertErrors(
         errors: [expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 6, 4)]);
@@ -2001,8 +2001,7 @@
   }
 
   void test_parseVariableDeclaration_late() {
-    var statement = parseStatement('late a;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement = parseStatement('late a;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertErrors(errors: [
       expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
@@ -2013,8 +2012,8 @@
   }
 
   void test_parseVariableDeclaration_late_final() {
-    var statement = parseStatement('late final a;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement =
+        parseStatement('late final a;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertNoErrors();
     expect(declarationList.keyword!.lexeme, 'final');
@@ -2023,8 +2022,8 @@
   }
 
   void test_parseVariableDeclaration_late_init() {
-    var statement = parseStatement('late a = 0;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement =
+        parseStatement('late a = 0;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertErrors(errors: [
       expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
@@ -2035,8 +2034,7 @@
   }
 
   void test_parseVariableDeclaration_late_type() {
-    var statement = parseStatement('late A a;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement = parseStatement('late A a;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertNoErrors();
     expect(declarationList.lateKeyword, isNotNull);
@@ -2046,8 +2044,8 @@
   }
 
   void test_parseVariableDeclaration_late_var() {
-    var statement = parseStatement('late var a;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement =
+        parseStatement('late var a;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertNoErrors();
     expect(declarationList.lateKeyword, isNotNull);
@@ -2057,8 +2055,8 @@
   }
 
   void test_parseVariableDeclaration_late_var_init() {
-    var statement = parseStatement('late var a = 0;', featureSet: nonNullable)
-        as VariableDeclarationStatement;
+    var statement =
+        parseStatement('late var a = 0;') as VariableDeclarationStatement;
     var declarationList = statement.variables;
     assertNoErrors();
     expect(declarationList.lateKeyword, isNotNull);
diff --git a/pkg/analyzer/test/generated/statement_parser_test.dart b/pkg/analyzer/test/generated/statement_parser_test.dart
index ff93ba2..702d950 100644
--- a/pkg/analyzer/test/generated/statement_parser_test.dart
+++ b/pkg/analyzer/test/generated/statement_parser_test.dart
@@ -256,7 +256,6 @@
     var forStatement = parseStatement(
       'await for (element in list) {}',
       inAsync: true,
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNotNull);
@@ -273,7 +272,6 @@
   void test_parseForStatement_each_finalExternal() {
     var forStatement = parseStatement(
       'for (final external in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -290,7 +288,6 @@
   void test_parseForStatement_each_finalRequired() {
     var forStatement = parseStatement(
       'for (final required in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -325,7 +322,6 @@
   void test_parseForStatement_each_genericFunctionType2() {
     var forStatement = parseStatement(
       'for (void Function<T>(T) element in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -359,7 +355,6 @@
   void test_parseForStatement_each_identifier2() {
     var forStatement = parseStatement(
       'for (element in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -394,7 +389,6 @@
   void test_parseForStatement_each_noType_metadata2() {
     var forStatement = parseStatement(
       'for (@A var element in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -429,7 +423,6 @@
   void test_parseForStatement_each_type2() {
     var forStatement = parseStatement(
       'for (A element in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -463,7 +456,6 @@
   void test_parseForStatement_each_var2() {
     var forStatement = parseStatement(
       'for (var element in list) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.awaitKeyword, isNull);
@@ -497,7 +489,6 @@
   void test_parseForStatement_loop_c2() {
     var forStatement = parseStatement(
       'for (; i < count;) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -533,7 +524,6 @@
   void test_parseForStatement_loop_cu2() {
     var forStatement = parseStatement(
       'for (; i < count; i++) {}',
-      featureSet: controlFlow,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -569,7 +559,6 @@
   void test_parseForStatement_loop_ecu2() {
     var forStatement = parseStatement(
       'for (i--; i < count; i++) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -607,7 +596,6 @@
   void test_parseForStatement_loop_i2() {
     var forStatement = parseStatement(
       'for (var i = 0;;) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -649,7 +637,6 @@
   void test_parseForStatement_loop_i_withMetadata2() {
     var forStatement = parseStatement(
       'for (@A var i = 0;;) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -690,7 +677,6 @@
   void test_parseForStatement_loop_ic2() {
     var forStatement = parseStatement(
       'for (var i = 0; i < count;) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -730,7 +716,6 @@
   void test_parseForStatement_loop_icu2() {
     var forStatement = parseStatement(
       'for (var i = 0; i < count; i++) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -771,7 +756,6 @@
   void test_parseForStatement_loop_iicuu2() {
     var forStatement = parseStatement(
       'for (int i = 0, j = count; i < j; i++, j--) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -811,7 +795,6 @@
   void test_parseForStatement_loop_iu2() {
     var forStatement = parseStatement(
       'for (var i = 0;; i++) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -848,7 +831,6 @@
   void test_parseForStatement_loop_u2() {
     var forStatement = parseStatement(
       'for (;; i++) {}',
-      featureSet: spread,
     ) as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -949,7 +931,7 @@
   }
 
   void test_parseLocalVariable_external() {
-    parseStatement('external int i;', featureSet: nonNullable);
+    parseStatement('external int i;');
     assertErrors(errors: [
       expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 8),
     ]);
diff --git a/pkg/analyzer/test/generated/top_level_parser_test.dart b/pkg/analyzer/test/generated/top_level_parser_test.dart
index 6962aff..8bb9be2 100644
--- a/pkg/analyzer/test/generated/top_level_parser_test.dart
+++ b/pkg/analyzer/test/generated/top_level_parser_test.dart
@@ -2139,34 +2139,29 @@
   }
 
   void test_parseTopLevelVariable_external() {
-    var unit = parseCompilationUnit('external int i;', featureSet: nonNullable);
+    var unit = parseCompilationUnit('external int i;');
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     expect(declaration.externalKeyword, isNotNull);
   }
 
   void test_parseTopLevelVariable_external_late() {
-    var unit = parseCompilationUnit('external late int? i;',
-        featureSet: nonNullable,
-        errors: [
-          expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
-        ]);
+    var unit = parseCompilationUnit('external late int? i;', errors: [
+      expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+    ]);
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     expect(declaration.externalKeyword, isNotNull);
   }
 
   void test_parseTopLevelVariable_external_late_final() {
-    var unit = parseCompilationUnit('external late final int? i;',
-        featureSet: nonNullable,
-        errors: [
-          expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
-        ]);
+    var unit = parseCompilationUnit('external late final int? i;', errors: [
+      expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+    ]);
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     expect(declaration.externalKeyword, isNotNull);
   }
 
   void test_parseTopLevelVariable_final_late() {
     var unit = parseCompilationUnit('final late a;',
-        featureSet: nonNullable,
         errors: [expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 6, 4)]);
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     var declarationList = declaration.variables;
@@ -2176,11 +2171,9 @@
   }
 
   void test_parseTopLevelVariable_late() {
-    var unit = parseCompilationUnit('late a;',
-        featureSet: nonNullable,
-        errors: [
-          expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
-        ]);
+    var unit = parseCompilationUnit('late a;', errors: [
+      expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
+    ]);
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     var declarationList = declaration.variables;
     expect(declarationList.keyword, isNull);
@@ -2189,7 +2182,7 @@
   }
 
   void test_parseTopLevelVariable_late_final() {
-    var unit = parseCompilationUnit('late final a;', featureSet: nonNullable);
+    var unit = parseCompilationUnit('late final a;');
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     var declarationList = declaration.variables;
     expect(declarationList.keyword!.lexeme, 'final');
@@ -2198,11 +2191,9 @@
   }
 
   void test_parseTopLevelVariable_late_init() {
-    var unit = parseCompilationUnit('late a = 0;',
-        featureSet: nonNullable,
-        errors: [
-          expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
-        ]);
+    var unit = parseCompilationUnit('late a = 0;', errors: [
+      expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1)
+    ]);
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     var declarationList = declaration.variables;
     expect(declarationList.keyword, isNull);
@@ -2211,7 +2202,7 @@
   }
 
   void test_parseTopLevelVariable_late_type() {
-    var unit = parseCompilationUnit('late A a;', featureSet: nonNullable);
+    var unit = parseCompilationUnit('late A a;');
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     var declarationList = declaration.variables;
     expect(declarationList.lateKeyword, isNotNull);
@@ -2221,7 +2212,7 @@
   }
 
   void test_parseTopLevelVariable_non_external() {
-    var unit = parseCompilationUnit('int i;', featureSet: nonNullable);
+    var unit = parseCompilationUnit('int i;');
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     expect(declaration.externalKeyword, isNull);
   }
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index aa0c90b..4db863b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -14,6 +12,8 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../util/feature_sets.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(BooleanArrayTest);
@@ -2041,13 +2041,7 @@
   FindNode _parseStringToFindNode(String content) {
     var parseResult = parseString(
       content: content,
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.currentVersion,
-        flags: [
-          Feature.enhanced_enums.enableString,
-          Feature.super_parameters.enableString,
-        ],
-      ),
+      featureSet: FeatureSets.latestWithExperiments,
     );
     return FindNode(parseResult.content, parseResult.unit);
   }
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index 3af192f..17ba251 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/to_source_visitor.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
@@ -16,6 +14,8 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../util/feature_sets.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ToSourceVisitorTest);
@@ -3517,13 +3517,7 @@
   FindNode _parseStringToFindNode(String content) {
     var parseResult = parseString(
       content: content,
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.currentVersion,
-        flags: [
-          Feature.enhanced_enums.enableString,
-          Feature.super_parameters.enableString,
-        ],
-      ),
+      featureSet: FeatureSets.latestWithExperiments,
     );
     return FindNode(parseResult.content, parseResult.unit);
   }
diff --git a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
index c78f9a4..7e64d5d 100644
--- a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
+++ b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
@@ -10,11 +9,11 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../generated/test_analysis_context.dart';
+import '../../../util/feature_sets.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -150,12 +149,7 @@
                 AstTestFactory.formalParameterList(),
                 AstTestFactory.expressionFunctionBody(e)))
       ],
-      featureSet: nonNullable
-          ? FeatureSet.latestLanguageVersion()
-          : FeatureSet.fromEnableFlags2(
-              sdkLanguageVersion: Version.parse('2.9.0'),
-              flags: [],
-            ),
+      featureSet: nonNullable ? FeatureSets.latest : FeatureSets.language_2_9,
     );
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
index fa161b9..8aae0fe 100644
--- a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
+++ b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
@@ -2,16 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 
 import '../../generated/test_support.dart';
+import '../../util/feature_sets.dart';
 import '../summary/resolved_ast_printer.dart';
 
 class ParserDiagnosticsTest {
@@ -54,13 +53,7 @@
   ParseStringResult parseStringWithErrors(String content) {
     return parseString(
       content: content,
-      featureSet: FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.currentVersion,
-        flags: [
-          Feature.enhanced_enums.enableString,
-          Feature.super_parameters.enableString,
-        ],
-      ),
+      featureSet: FeatureSets.latestWithExperiments,
       throwIfDiagnostics: false,
     );
   }
diff --git a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
index b0fcd73..61e6024 100644
--- a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -41,7 +41,7 @@
 f() => [a, if (x) b c];
 ''', [ParserErrorCode.EXPECTED_ELSE_OR_COMMA], '''
 f() => [a, if (x) b, c];
-''', featureSet: controlFlow);
+''');
   }
 
   void test_missingComma_afterIfElse() {
@@ -49,7 +49,7 @@
 f() => [a, if (x) b else y c];
 ''', [ParserErrorCode.EXPECTED_TOKEN], '''
 f() => [a, if (x) b else y, c];
-''', featureSet: controlFlow);
+''');
   }
 }
 
@@ -69,7 +69,7 @@
 f() => {a: b, if (x) c: d e: f};
 ''', [ParserErrorCode.EXPECTED_ELSE_OR_COMMA], '''
 f() => {a: b, if (x) c: d, e: f};
-''', featureSet: controlFlow);
+''');
   }
 
   void test_missingComma_afterIfElse() {
@@ -77,7 +77,7 @@
 f() => {a: b, if (x) c: d else y: z e: f};
 ''', [ParserErrorCode.EXPECTED_TOKEN], '''
 f() => {a: b, if (x) c: d else y: z, e: f};
-''', featureSet: controlFlow);
+''');
   }
 
   void test_missingKey() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 3c1a267..60ab80c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/util/uri.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../util/feature_sets.dart';
 import 'element_text.dart';
 import 'resynthesize_common.dart';
 import 'test_strategies.dart';
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 87c34e9..b1c1f02 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8,17 +8,16 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../util/feature_sets.dart';
 import 'element_text.dart';
 
 /// Abstract base class for resynthesizing and comparing elements.
@@ -85,27 +84,6 @@
       {bool allowErrors = false});
 }
 
-class FeatureSets {
-  static final FeatureSet language_2_9 = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: Version.parse('2.9.0'),
-    flags: [],
-  );
-
-  static final FeatureSet language_2_12 = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: Version.parse('2.12.0'),
-    flags: [],
-  );
-
-  static final FeatureSet latestWithExperiments = FeatureSet.fromEnableFlags2(
-    sdkLanguageVersion: Version.parse('2.16.0'),
-    flags: [
-      EnableString.constructor_tearoffs,
-      EnableString.enhanced_enums,
-      EnableString.super_parameters,
-    ],
-  );
-}
-
 /// Mixin containing test cases exercising summary resynthesis.  Intended to be
 /// applied to a class implementing [AbstractResynthesizeTest].
 mixin ResynthesizeTestCases on AbstractResynthesizeTest {
diff --git a/pkg/analyzer/test/util/feature_sets.dart b/pkg/analyzer/test/util/feature_sets.dart
new file mode 100644
index 0000000..34ff0eb
--- /dev/null
+++ b/pkg/analyzer/test/util/feature_sets.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+class FeatureSets {
+  static final FeatureSet language_2_3 = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.3.0'),
+    flags: [],
+  );
+
+  static final FeatureSet language_2_9 = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.9.0'),
+    flags: [],
+  );
+
+  static final FeatureSet language_2_12 = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.12.0'),
+    flags: [],
+  );
+
+  static final FeatureSet language_2_13 = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.13.0'),
+    flags: [],
+  );
+
+  static final FeatureSet latest = FeatureSet.latestLanguageVersion();
+
+  static final FeatureSet latestWithExperiments = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: ExperimentStatus.currentVersion,
+    flags: [
+      EnableString.constructor_tearoffs,
+      EnableString.enhanced_enums,
+      EnableString.super_parameters,
+    ],
+  );
+
+  FeatureSets._();
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index c807337..fd50ae4 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -51,9 +51,7 @@
   /// The types in the `on` clause of an extension or mixin declaration.
   List<TypeBuilder>? get onTypes;
 
-  ConstructorScope get constructors;
-
-  ConstructorScopeBuilder get constructorScopeBuilder;
+  ConstructorScope get constructorScope;
 
   @override
   Uri get fileUri;
@@ -144,10 +142,7 @@
   List<TypeBuilder>? onTypes;
 
   @override
-  final ConstructorScope constructors;
-
-  @override
-  final ConstructorScopeBuilder constructorScopeBuilder;
+  final ConstructorScope constructorScope;
 
   @override
   bool isNullClass = false;
@@ -166,11 +161,10 @@
       this.interfaceBuilders,
       this.onTypes,
       Scope scope,
-      this.constructors,
+      this.constructorScope,
       LibraryBuilder parent,
       int charOffset)
-      : constructorScopeBuilder = new ConstructorScopeBuilder(constructors),
-        super(metadata, modifiers, name, parent, charOffset, scope);
+      : super(metadata, modifiers, name, parent, charOffset, scope);
 
   @override
   String get debugName => "ClassBuilder";
@@ -227,7 +221,7 @@
       return null;
     }
     MemberBuilder? declaration =
-        constructors.lookup(name == 'new' ? '' : name, charOffset, uri);
+        constructorScope.lookup(name == 'new' ? '' : name, charOffset, uri);
     if (declaration == null && isPatch) {
       return origin.findConstructorOrFactory(
           name, charOffset, uri, accessingLibrary);
diff --git a/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart b/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart
index 4490af2..4a09bd96 100644
--- a/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/declaration_builder.dart
@@ -15,8 +15,6 @@
 abstract class DeclarationBuilder implements TypeDeclarationBuilder {
   Scope get scope;
 
-  ScopeBuilder get scopeBuilder;
-
   LibraryBuilder get library;
 
   /// Lookup a member accessed statically through this declaration.
@@ -48,15 +46,11 @@
   final Scope scope;
 
   @override
-  final ScopeBuilder scopeBuilder;
-
-  @override
   final Uri fileUri;
 
   DeclarationBuilderImpl(List<MetadataBuilder>? metadata, int modifiers,
       String name, LibraryBuilder parent, int charOffset, this.scope)
-      : scopeBuilder = new ScopeBuilder(scope),
-        fileUri = parent.fileUri,
+      : fileUri = parent.fileUri,
         super(metadata, modifiers, name, parent, charOffset);
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index c86c3c0..423e617 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -42,10 +42,6 @@
 
   Scope get exportScope;
 
-  ScopeBuilder get scopeBuilder;
-
-  ScopeBuilder get exportScopeBuilder;
-
   List<Export> get exporters;
 
   abstract LibraryBuilder? partOfLibrary;
@@ -164,12 +160,6 @@
   final Scope exportScope;
 
   @override
-  final ScopeBuilder scopeBuilder;
-
-  @override
-  final ScopeBuilder exportScopeBuilder;
-
-  @override
   final List<Export> exporters = <Export>[];
 
   @override
@@ -182,9 +172,7 @@
   bool mayImplementRestrictedTypes = false;
 
   LibraryBuilderImpl(this.fileUri, this.scope, this.exportScope)
-      : scopeBuilder = new ScopeBuilder(scope),
-        exportScopeBuilder = new ScopeBuilder(exportScope),
-        super(null, -1);
+      : super(null, -1);
 
   @override
   bool get isSynthetic => false;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 03a982b..625151e 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -89,19 +89,19 @@
   void addField(Field field) {
     DillFieldBuilder builder = new DillFieldBuilder(field, this);
     String name = field.name.text;
-    scopeBuilder.addMember(name, builder);
+    scope.addLocalMember(name, builder, setter: false);
   }
 
   void addConstructor(Constructor constructor, Procedure? constructorTearOff) {
     DillConstructorBuilder builder =
         new DillConstructorBuilder(constructor, constructorTearOff, this);
     String name = constructor.name.text;
-    constructorScopeBuilder.addMember(name, builder);
+    constructorScope.addLocalMember(name, builder);
   }
 
   void addFactory(Procedure factory, Procedure? factoryTearOff) {
     String name = factory.name.text;
-    constructorScopeBuilder.addMember(
+    constructorScope.addLocalMember(
         name, new DillFactoryBuilder(factory, factoryTearOff, this));
   }
 
@@ -111,16 +111,20 @@
       case ProcedureKind.Factory:
         throw new UnsupportedError("Use addFactory for adding factories");
       case ProcedureKind.Setter:
-        scopeBuilder.addSetter(name, new DillSetterBuilder(procedure, this));
+        scope.addLocalMember(name, new DillSetterBuilder(procedure, this),
+            setter: true);
         break;
       case ProcedureKind.Getter:
-        scopeBuilder.addMember(name, new DillGetterBuilder(procedure, this));
+        scope.addLocalMember(name, new DillGetterBuilder(procedure, this),
+            setter: false);
         break;
       case ProcedureKind.Operator:
-        scopeBuilder.addMember(name, new DillOperatorBuilder(procedure, this));
+        scope.addLocalMember(name, new DillOperatorBuilder(procedure, this),
+            setter: false);
         break;
       case ProcedureKind.Method:
-        scopeBuilder.addMember(name, new DillMethodBuilder(procedure, this));
+        scope.addLocalMember(name, new DillMethodBuilder(procedure, this),
+            setter: false);
         break;
     }
   }
@@ -180,7 +184,7 @@
   @override
   void forEachConstructor(void Function(String, MemberBuilder) f,
       {bool includeInjectedConstructors: false}) {
-    constructors.forEach(f);
+    constructorScope.forEach(f);
   }
 
   void clearCachedValues() {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
index 01f0010..5659abd 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
@@ -47,10 +47,11 @@
         case ExtensionMemberKind.Method:
           if (descriptor.isStatic) {
             Procedure procedure = descriptor.member.asProcedure;
-            scopeBuilder.addMember(
+            scope.addLocalMember(
                 name.text,
                 new DillExtensionStaticMethodBuilder(
-                    procedure, descriptor, this));
+                    procedure, descriptor, this),
+                setter: false);
           } else {
             _methods[name] = descriptor;
           }
@@ -60,23 +61,27 @@
           break;
         case ExtensionMemberKind.Getter:
           Procedure procedure = descriptor.member.asProcedure;
-          scopeBuilder.addMember(name.text,
-              new DillExtensionGetterBuilder(procedure, descriptor, this));
+          scope.addLocalMember(name.text,
+              new DillExtensionGetterBuilder(procedure, descriptor, this),
+              setter: false);
           break;
         case ExtensionMemberKind.Field:
           Field field = descriptor.member.asField;
-          scopeBuilder.addMember(name.text,
-              new DillExtensionFieldBuilder(field, descriptor, this));
+          scope.addLocalMember(
+              name.text, new DillExtensionFieldBuilder(field, descriptor, this),
+              setter: false);
           break;
         case ExtensionMemberKind.Setter:
           Procedure procedure = descriptor.member.asProcedure;
-          scopeBuilder.addSetter(name.text,
-              new DillExtensionSetterBuilder(procedure, descriptor, this));
+          scope.addLocalMember(name.text,
+              new DillExtensionSetterBuilder(procedure, descriptor, this),
+              setter: true);
           break;
         case ExtensionMemberKind.Operator:
           Procedure procedure = descriptor.member.asProcedure;
-          scopeBuilder.addMember(name.text,
-              new DillExtensionOperatorBuilder(procedure, descriptor, this));
+          scope.addLocalMember(name.text,
+              new DillExtensionOperatorBuilder(procedure, descriptor, this),
+              setter: false);
           break;
       }
     }
@@ -84,10 +89,11 @@
       Procedure procedure = descriptor.member.asProcedure;
       assert(_tearOffs.containsKey(name),
           "No tear found for ${descriptor} in ${_tearOffs}");
-      scopeBuilder.addMember(
+      scope.addLocalMember(
           name.text,
           new DillExtensionInstanceMethodBuilder(
-              procedure, descriptor, this, _tearOffs[name]!));
+              procedure, descriptor, this, _tearOffs[name]!),
+          setter: false);
     });
   }
 
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index d09fac5..6643502 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -269,18 +269,19 @@
 
     bool isSetter = declaration.isSetter;
     if (isSetter) {
-      scopeBuilder.addSetter(name, declaration as MemberBuilder);
+      scope.addLocalMember(name, declaration as MemberBuilder, setter: true);
     } else {
-      scopeBuilder.addMember(name, declaration);
+      scope.addLocalMember(name, declaration, setter: false);
     }
     if (declaration.isExtension) {
-      scopeBuilder.addExtension(declaration as ExtensionBuilder);
+      scope.addExtension(declaration as ExtensionBuilder);
     }
     if (!name.startsWith("_") && !name.contains('#')) {
       if (isSetter) {
-        exportScopeBuilder.addSetter(name, declaration as MemberBuilder);
+        exportScope.addLocalMember(name, declaration as MemberBuilder,
+            setter: true);
       } else {
-        exportScopeBuilder.addMember(name, declaration);
+        exportScope.addLocalMember(name, declaration, setter: false);
       }
     }
     return declaration;
@@ -339,7 +340,8 @@
         case "void":
           // TODO(ahe): It's likely that we shouldn't be exporting these types
           // from dart:core, and this case can be removed.
-          declaration = loader.coreLibrary.exportScopeBuilder[name]!;
+          declaration = loader.coreLibrary.exportScope
+              .lookupLocalMember(name, setter: false)!;
           break;
 
         default:
@@ -353,7 +355,7 @@
           declaration = new InvalidTypeDeclarationBuilder(
               name, message.withoutLocation());
       }
-      exportScopeBuilder.addMember(name, declaration);
+      exportScope.addLocalMember(name, declaration, setter: false);
     });
 
     Map<Reference, Builder>? sourceBuildersMap =
@@ -374,9 +376,10 @@
         }
 
         if (declaration.isSetter) {
-          exportScopeBuilder.addSetter(name, declaration as MemberBuilder);
+          exportScope.addLocalMember(name, declaration as MemberBuilder,
+              setter: true);
         } else {
-          exportScopeBuilder.addMember(name, declaration);
+          exportScope.addLocalMember(name, declaration, setter: false);
         }
       } else {
         Uri libraryUri;
@@ -411,11 +414,12 @@
         if (isSetter) {
           declaration =
               library.exportScope.lookupLocalMember(name, setter: true)!;
-          exportScopeBuilder.addSetter(name, declaration as MemberBuilder);
+          exportScope.addLocalMember(name, declaration as MemberBuilder,
+              setter: true);
         } else {
           declaration =
               library.exportScope.lookupLocalMember(name, setter: false)!;
-          exportScopeBuilder.addMember(name, declaration);
+          exportScope.addLocalMember(name, declaration, setter: false);
         }
         // ignore: unnecessary_null_comparison
         if (declaration == null) {
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 5a2e170..e876c78 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1672,8 +1672,8 @@
 
       Class? cls;
       if (className != null) {
-        ClassBuilder? classBuilder =
-            libraryBuilder.scopeBuilder[className] as ClassBuilder?;
+        ClassBuilder? classBuilder = libraryBuilder.scope
+            .lookupLocalMember(className, setter: false) as ClassBuilder?;
         cls = classBuilder?.cls;
         if (cls == null) return null;
       }
@@ -1684,11 +1684,13 @@
         if (indexOfDot >= 0) {
           String beforeDot = methodName.substring(0, indexOfDot);
           String afterDot = methodName.substring(indexOfDot + 1);
-          Builder? builder = libraryBuilder.scopeBuilder[beforeDot];
+          Builder? builder =
+              libraryBuilder.scope.lookupLocalMember(beforeDot, setter: false);
           extensionName = beforeDot;
           if (builder is ExtensionBuilder) {
             extension = builder.extension;
-            Builder? subBuilder = builder.scopeBuilder[afterDot];
+            Builder? subBuilder =
+                builder.lookupLocalMember(afterDot, setter: false);
             if (subBuilder is MemberBuilder) {
               if (subBuilder.isExtensionInstanceMember) {
                 isStatic = false;
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 184639e..142fef3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -84,7 +84,6 @@
     show internalProblem, unexpected, unhandled, unsupported;
 import '../scope.dart';
 import '../source/diet_parser.dart';
-import '../source/scope_listener.dart' show JumpTargetKind, ScopeListener;
 import '../source/source_class_builder.dart';
 import '../source/source_constructor_builder.dart';
 import '../source/source_enum_builder.dart';
@@ -93,7 +92,8 @@
 import '../source/source_function_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 import '../source/source_procedure_builder.dart';
-import '../source/stack_listener_impl.dart' show offsetForToken;
+import '../source/stack_listener_impl.dart'
+    show StackListenerImpl, offsetForToken;
 import '../source/value_kinds.dart';
 import '../type_inference/type_inferrer.dart'
     show TypeInferrer, InferredFunctionBody, InitializerInferenceResult;
@@ -125,7 +125,13 @@
 // has been enabled by default.
 const Object invalidCollectionElement = const Object();
 
-class BodyBuilder extends ScopeListener<JumpTarget>
+enum JumpTargetKind {
+  Break,
+  Continue,
+  Goto, // Continue label in switch.
+}
+
+class BodyBuilder extends StackListenerImpl
     implements ExpressionGeneratorHelper, EnsureLoaded, DelayedActionPerformer {
   @override
   final Forest forest;
@@ -336,6 +342,12 @@
 
   final List<TypeParameter>? extensionTypeParameters;
 
+  Scope scope;
+
+  JumpTarget? breakTarget;
+
+  JumpTarget? continueTarget;
+
   BodyBuilder(
       {required this.libraryBuilder,
       required this.member,
@@ -365,7 +377,7 @@
             declarationBuilder is SourceClassBuilder &&
                 coreTypes.objectClass != declarationBuilder.cls,
         benchmarker = libraryBuilder.loader.target.benchmarker,
-        super(enclosingScope) {
+        this.scope = enclosingScope {
     formalParameterScope?.forEach((String name, Builder builder) {
       if (builder is VariableBuilder) {
         typeInferrer.assignedVariables.declare(builder.variable!);
@@ -421,6 +433,147 @@
                 .createLocalTypeInferrer(
                     fileUri, declarationBuilder?.thisType, library, null));
 
+  JumpTarget createBreakTarget(int charOffset) {
+    return createJumpTarget(JumpTargetKind.Break, charOffset);
+  }
+
+  JumpTarget createContinueTarget(int charOffset) {
+    return createJumpTarget(JumpTargetKind.Continue, charOffset);
+  }
+
+  JumpTarget createGotoTarget(int charOffset) {
+    return createJumpTarget(JumpTargetKind.Goto, charOffset);
+  }
+
+  void enterLocalScope(String debugName, [Scope? newScope]) {
+    push(scope);
+    scope = newScope ?? scope.createNestedScope(debugName);
+    assert(checkState(null, [
+      ValueKinds.Scope,
+    ]));
+  }
+
+  @override
+  void exitLocalScope() {
+    assert(checkState(null, [
+      ValueKinds.Scope,
+    ]));
+    scope = pop() as Scope;
+    // ignore: unnecessary_null_comparison
+    assert(scope != null);
+  }
+
+  void enterBreakTarget(int charOffset, [JumpTarget? target]) {
+    push(breakTarget ?? NullValue.BreakTarget);
+    breakTarget = target ?? createBreakTarget(charOffset);
+  }
+
+  void enterContinueTarget(int charOffset, [JumpTarget? target]) {
+    push(continueTarget ?? NullValue.ContinueTarget);
+    continueTarget = target ?? createContinueTarget(charOffset);
+  }
+
+  JumpTarget? exitBreakTarget() {
+    JumpTarget? current = breakTarget;
+    breakTarget = pop() as JumpTarget?;
+    return current;
+  }
+
+  JumpTarget? exitContinueTarget() {
+    JumpTarget? current = continueTarget;
+    continueTarget = pop() as JumpTarget?;
+    return current;
+  }
+
+  @override
+  void beginBlockFunctionBody(Token begin) {
+    debugEvent("beginBlockFunctionBody");
+    enterLocalScope("block function body");
+  }
+
+  @override
+  void beginForStatement(Token token) {
+    debugEvent("beginForStatement");
+    enterLoop(token.charOffset);
+    enterLocalScope("for statement");
+  }
+
+  @override
+  void beginForControlFlow(Token? awaitToken, Token forToken) {
+    debugEvent("beginForControlFlow");
+    enterLocalScope("for in a collection");
+  }
+
+  @override
+  void beginDoWhileStatementBody(Token token) {
+    debugEvent("beginDoWhileStatementBody");
+    enterLocalScope("do-while statement body");
+  }
+
+  @override
+  void endDoWhileStatementBody(Token token) {
+    debugEvent("endDoWhileStatementBody");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
+  }
+
+  @override
+  void beginWhileStatementBody(Token token) {
+    debugEvent("beginWhileStatementBody");
+    enterLocalScope("while statement body");
+  }
+
+  @override
+  void endWhileStatementBody(Token token) {
+    debugEvent("endWhileStatementBody");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
+  }
+
+  @override
+  void beginForStatementBody(Token token) {
+    debugEvent("beginForStatementBody");
+    enterLocalScope("for statement body");
+  }
+
+  @override
+  void endForStatementBody(Token token) {
+    debugEvent("endForStatementBody");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
+  }
+
+  @override
+  void beginForInBody(Token token) {
+    debugEvent("beginForInBody");
+    enterLocalScope("for-in body");
+  }
+
+  @override
+  void endForInBody(Token token) {
+    debugEvent("endForInBody");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
+  }
+
+  @override
+  void beginElseStatement(Token token) {
+    debugEvent("beginElseStatement");
+    enterLocalScope("else");
+  }
+
+  @override
+  void endElseStatement(Token token) {
+    debugEvent("endElseStatement");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
+  }
+
   bool get inConstructor {
     return functionNestingLevel == 0 && member is ConstructorBuilder;
   }
@@ -640,7 +793,6 @@
     }
   }
 
-  @override
   JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
     return new JumpTarget(
         kind, functionNestingLevel, member as MemberBuilder, charOffset);
@@ -2995,17 +3147,21 @@
 
   @override
   void beginThenStatement(Token token) {
+    debugEvent("beginThenStatement");
     Expression condition = popForValue();
     // This is matched by the call to [deferNode] in
     // [endThenStatement].
     typeInferrer.assignedVariables.beginNode();
     push(condition);
-    super.beginThenStatement(token);
+    enterLocalScope("then");
   }
 
   @override
   void endThenStatement(Token token) {
-    super.endThenStatement(token);
+    debugEvent("endThenStatement");
+    Object? body = pop();
+    exitLocalScope();
+    push(body);
     // This is matched by the call to [beginNode] in
     // [beginThenStatement] and by the call to [storeInfo] in
     // [endIfStatement].
@@ -3281,7 +3437,8 @@
       tryStatementInfoStack = tryStatementInfoStack
           .prepend(typeInferrer.assignedVariables.deferNode());
     }
-    super.beginBlock(token, blockKind);
+    debugEvent("beginBlock");
+    enterLocalScope("block");
   }
 
   @override
@@ -3331,7 +3488,6 @@
     }
   }
 
-  @override
   void enterLoop(int charOffset) {
     if (peek() is LabelTarget) {
       LabelTarget target = peek() as LabelTarget;
@@ -3985,13 +4141,12 @@
     enterLocalScope('FunctionTypeScope',
         scope.createNestedScope("function-type scope", isModifiable: true));
     if (typeVariables != null) {
-      ScopeBuilder scopeBuilder = new ScopeBuilder(scope);
       for (TypeVariableBuilder builder in typeVariables) {
         String name = builder.name;
-        TypeVariableBuilder? existing =
-            scopeBuilder[name] as TypeVariableBuilder?;
+        TypeVariableBuilder? existing = scope.lookupLocalMember(name,
+            setter: false) as TypeVariableBuilder?;
         if (existing == null) {
-          scopeBuilder.addMember(name, builder);
+          scope.addLocalMember(name, builder, setter: false);
         } else {
           reportDuplicatedDeclaration(existing, name, builder.charOffset);
         }
@@ -5869,9 +6024,10 @@
 
   @override
   void beginDoWhileStatement(Token token) {
+    debugEvent("beginDoWhileStatement");
     // This is matched by the [endNode] call in [endDoWhileStatement].
     typeInferrer.assignedVariables.beginNode();
-    super.beginDoWhileStatement(token);
+    enterLoop(token.charOffset);
   }
 
   @override
@@ -6198,9 +6354,10 @@
 
   @override
   void beginWhileStatement(Token token) {
+    debugEvent("beginWhileStatement");
     // This is matched by the [endNode] call in [endWhileStatement].
     typeInferrer.assignedVariables.beginNode();
-    super.beginWhileStatement(token);
+    enterLoop(token.charOffset);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index e5aa742..0c41ecf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1322,7 +1322,7 @@
           patchConstructorNames.add(name);
         }
       });
-      builder.constructors.forEach((String name, Builder builder) {
+      builder.constructorScope.forEach((String name, Builder builder) {
         if (builder is ConstructorBuilder) {
           patchConstructorNames.remove(name);
         }
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index ab0037c..c431fd6 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -615,6 +615,14 @@
     }
   }
 
+  MemberBuilder? lookupLocalMember(String name) {
+    return local[name];
+  }
+
+  void addLocalMember(String name, MemberBuilder builder) {
+    local[name] = builder;
+  }
+
   @override
   String toString() => "ConstructorScope($className, ${local.keys})";
 }
@@ -651,38 +659,6 @@
   }
 }
 
-class ScopeBuilder {
-  final Scope scope;
-
-  ScopeBuilder(this.scope);
-
-  void addMember(String name, Builder builder) {
-    scope._local[name] = builder;
-  }
-
-  void addSetter(String name, MemberBuilder builder) {
-    scope._setters[name] = builder;
-  }
-
-  void addExtension(ExtensionBuilder builder) {
-    scope.addExtension(builder);
-  }
-
-  Builder? operator [](String name) => scope._local[name];
-}
-
-class ConstructorScopeBuilder {
-  final ConstructorScope scope;
-
-  ConstructorScopeBuilder(this.scope);
-
-  void addMember(String name, MemberBuilder builder) {
-    scope.local[name] = builder;
-  }
-
-  MemberBuilder? operator [](String name) => scope.local[name];
-}
-
 abstract class ProblemBuilder extends BuilderImpl {
   final String name;
 
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index b98d0c0..86e5832 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -1131,7 +1131,7 @@
     } else if (getOrSet != null && optional("set", getOrSet)) {
       declaration = libraryBuilder.scope.lookupLocalMember(name, setter: true);
     } else {
-      declaration = libraryBuilder.scopeBuilder[name];
+      declaration = libraryBuilder.scope.lookupLocalMember(name, setter: false);
     }
     declaration = handleDuplicatedName(declaration, token);
     checkBuilder(token, declaration, name);
@@ -1152,7 +1152,7 @@
     if (libraryBuilder.enableConstructorTearOffsInLibrary) {
       suffix = suffix == "new" ? "" : suffix;
     }
-    declaration = currentClass!.constructors.local[suffix];
+    declaration = currentClass!.constructorScope.local[suffix];
     declaration = handleDuplicatedName(declaration, token);
     checkBuilder(token, declaration, nameOrQualified);
     return declaration;
diff --git a/pkg/front_end/lib/src/fasta/source/scope_listener.dart b/pkg/front_end/lib/src/fasta/source/scope_listener.dart
deleted file mode 100644
index 221222f..0000000
--- a/pkg/front_end/lib/src/fasta/source/scope_listener.dart
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.scope_listener;
-
-import 'package:_fe_analyzer_shared/src/parser/block_kind.dart' show BlockKind;
-
-import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart'
-    show NullValue;
-
-import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
-import '../scope.dart' show Scope;
-import 'stack_listener_impl.dart';
-import 'value_kinds.dart';
-
-enum JumpTargetKind {
-  Break,
-  Continue,
-  Goto, // Continue label in switch.
-}
-
-abstract class ScopeListener<J> extends StackListenerImpl {
-  Scope scope;
-
-  J? breakTarget;
-
-  J? continueTarget;
-
-  ScopeListener(Scope? scope) : scope = scope ?? new Scope.immutable();
-
-  J createJumpTarget(JumpTargetKind kind, int charOffset);
-
-  J createBreakTarget(int charOffset) {
-    return createJumpTarget(JumpTargetKind.Break, charOffset);
-  }
-
-  J createContinueTarget(int charOffset) {
-    return createJumpTarget(JumpTargetKind.Continue, charOffset);
-  }
-
-  J createGotoTarget(int charOffset) {
-    return createJumpTarget(JumpTargetKind.Goto, charOffset);
-  }
-
-  void enterLocalScope(String debugName, [Scope? newScope]) {
-    push(scope);
-    scope = newScope ?? scope.createNestedScope(debugName);
-    assert(checkState(null, [
-      ValueKinds.Scope,
-    ]));
-  }
-
-  @override
-  void exitLocalScope() {
-    assert(checkState(null, [
-      ValueKinds.Scope,
-    ]));
-    scope = pop() as Scope;
-    // ignore: unnecessary_null_comparison
-    assert(scope != null);
-  }
-
-  void enterBreakTarget(int charOffset, [J? target]) {
-    push(breakTarget ?? NullValue.BreakTarget);
-    breakTarget = target ?? createBreakTarget(charOffset);
-  }
-
-  void enterContinueTarget(int charOffset, [J? target]) {
-    push(continueTarget ?? NullValue.ContinueTarget);
-    continueTarget = target ?? createContinueTarget(charOffset);
-  }
-
-  J? exitBreakTarget() {
-    J? current = breakTarget;
-    breakTarget = pop() as J?;
-    return current;
-  }
-
-  J? exitContinueTarget() {
-    J? current = continueTarget;
-    continueTarget = pop() as J?;
-    return current;
-  }
-
-  void enterLoop(int charOffset) {
-    enterBreakTarget(charOffset);
-    enterContinueTarget(charOffset);
-  }
-
-  @override
-  void beginBlockFunctionBody(Token begin) {
-    debugEvent("beginBlockFunctionBody");
-    enterLocalScope("block function body");
-  }
-
-  @override
-  void beginForStatement(Token token) {
-    debugEvent("beginForStatement");
-    enterLoop(token.charOffset);
-    enterLocalScope("for statement");
-  }
-
-  @override
-  void beginForControlFlow(Token? awaitToken, Token forToken) {
-    debugEvent("beginForControlFlow");
-    enterLocalScope("for in a collection");
-  }
-
-  @override
-  void beginBlock(Token token, BlockKind blockKind) {
-    debugEvent("beginBlock");
-    enterLocalScope("block");
-  }
-
-  @override
-  void beginSwitchBlock(Token token) {
-    debugEvent("beginSwitchBlock");
-    enterLocalScope("switch block");
-    enterBreakTarget(token.charOffset);
-  }
-
-  @override
-  void beginDoWhileStatement(Token token) {
-    debugEvent("beginDoWhileStatement");
-    enterLoop(token.charOffset);
-  }
-
-  @override
-  void beginWhileStatement(Token token) {
-    debugEvent("beginWhileStatement");
-    enterLoop(token.charOffset);
-  }
-
-  @override
-  void beginDoWhileStatementBody(Token token) {
-    debugEvent("beginDoWhileStatementBody");
-    enterLocalScope("do-while statement body");
-  }
-
-  @override
-  void endDoWhileStatementBody(Token token) {
-    debugEvent("endDoWhileStatementBody");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-
-  @override
-  void beginWhileStatementBody(Token token) {
-    debugEvent("beginWhileStatementBody");
-    enterLocalScope("while statement body");
-  }
-
-  @override
-  void endWhileStatementBody(Token token) {
-    debugEvent("endWhileStatementBody");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-
-  @override
-  void beginForStatementBody(Token token) {
-    debugEvent("beginForStatementBody");
-    enterLocalScope("for statement body");
-  }
-
-  @override
-  void endForStatementBody(Token token) {
-    debugEvent("endForStatementBody");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-
-  @override
-  void beginForInBody(Token token) {
-    debugEvent("beginForInBody");
-    enterLocalScope("for-in body");
-  }
-
-  @override
-  void endForInBody(Token token) {
-    debugEvent("endForInBody");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-
-  @override
-  void beginThenStatement(Token token) {
-    debugEvent("beginThenStatement");
-    enterLocalScope("then");
-  }
-
-  @override
-  void endThenStatement(Token token) {
-    debugEvent("endThenStatement");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-
-  @override
-  void beginElseStatement(Token token) {
-    debugEvent("beginElseStatement");
-    enterLocalScope("else");
-  }
-
-  @override
-  void endElseStatement(Token token) {
-    debugEvent("endElseStatement");
-    Object? body = pop();
-    exitLocalScope();
-    push(body);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 3f25a57..0fe0d36 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -202,7 +202,7 @@
     }
 
     scope.forEach(buildBuilders);
-    constructors.forEach(buildBuilders);
+    constructorScope.forEach(buildBuilders);
     if (supertypeBuilder != null) {
       supertypeBuilder = _checkSupertype(supertypeBuilder!);
     }
@@ -276,8 +276,8 @@
       }
     }
 
-    constructors.forEach((String name, Builder constructor) {
-      Builder? member = scopeBuilder[name];
+    constructorScope.forEach((String name, Builder constructor) {
+      Builder? member = scope.lookupLocalMember(name, setter: false);
       if (member == null) return;
       if (!member.isStatic) return;
       // TODO(ahe): Revisit these messages. It seems like the last two should
@@ -299,7 +299,7 @@
     });
 
     scope.forEachLocalSetter((String name, Builder setter) {
-      Builder? constructor = constructorScopeBuilder[name];
+      Builder? constructor = constructorScope.lookupLocalMember(name);
       if (constructor == null || !setter.isStatic) return;
       addProblem(templateConflictsWithConstructor.withArguments(name),
           setter.charOffset, noLength);
@@ -350,7 +350,7 @@
       }
     }
 
-    constructors.forEach(build);
+    constructorScope.forEach(build);
     scope.forEach(build);
   }
 
@@ -378,11 +378,12 @@
     if (isPatch) {
       actualOrigin!.forEachConstructor(f);
     } else {
-      constructors.forEach(f);
+      constructorScope.forEach(f);
       List<SourceClassBuilder>? patchClasses = _patches;
       if (patchClasses != null) {
         for (SourceClassBuilder patchClass in patchClasses) {
-          patchClass.constructors.forEach((String name, MemberBuilder builder) {
+          patchClass.constructorScope
+              .forEach((String name, MemberBuilder builder) {
             if (!builder.isPatch) {
               f(name, builder);
             }
@@ -445,10 +446,10 @@
     List<SourceClassBuilder>? patchClasses = _patches;
     if (patchClasses != null) {
       for (SourceClassBuilder patchClass in patchClasses) {
-        patchClass.constructors.forEach(callbackFilteringFieldBuilders);
+        patchClass.constructorScope.forEach(callbackFilteringFieldBuilders);
       }
     }
-    constructors.forEach(callbackFilteringFieldBuilders);
+    constructorScope.forEach(callbackFilteringFieldBuilders);
   }
 
   /// Looks up the constructor by [name] on the class built by this class
@@ -668,16 +669,16 @@
         }
       });
 
-      patch.constructors.local
+      patch.constructorScope.local
           .forEach((String name, MemberBuilder patchConstructor) {
-        MemberBuilder? originConstructor = constructors.local[name];
+        MemberBuilder? originConstructor = constructorScope.local[name];
         if (patch.isAugmentation) {
           if (originConstructor != null) {
             // TODO(johnniwinther): Should we support constructor augmentation?
             // Currently the syntax doesn't allow it.
             originConstructor.applyPatch(patchConstructor);
           } else {
-            constructorScopeBuilder.addMember(name, patchConstructor);
+            constructorScope.addLocalMember(name, patchConstructor);
           }
         } else {
           if (originConstructor != null) {
@@ -1131,7 +1132,7 @@
   }
 
   void checkRedirectingFactories(TypeEnvironment typeEnvironment) {
-    Map<String, MemberBuilder> constructors = this.constructors.local;
+    Map<String, MemberBuilder> constructors = this.constructorScope.local;
     for (Builder? constructor in constructors.values) {
       do {
         if (constructor is RedirectingFactoryBuilder) {
@@ -1416,8 +1417,8 @@
   void addSyntheticConstructor(
       SyntheticSourceConstructorBuilder constructorBuilder) {
     String name = constructorBuilder.name;
-    constructorBuilder.next = constructorScopeBuilder[name];
-    constructorScopeBuilder.addMember(name, constructorBuilder);
+    constructorBuilder.next = constructorScope.lookupLocalMember(name);
+    constructorScope.addLocalMember(name, constructorBuilder);
     // Synthetic constructors are created after the component has been built
     // so we need to add the constructor to the class.
     cls.addConstructor(constructorBuilder.invokeTarget);
@@ -1442,7 +1443,7 @@
     scope.forEach((String name, Builder declaration) {
       count += declaration.finishPatch();
     });
-    constructors.forEach((String name, Builder declaration) {
+    constructorScope.forEach((String name, Builder declaration) {
       count += declaration.finishPatch();
     });
     return count;
@@ -1788,7 +1789,7 @@
     }
     int count = constructorReferences!.length;
     if (count != 0) {
-      Map<String, MemberBuilder> constructors = this.constructors.local;
+      Map<String, MemberBuilder> constructors = this.constructorScope.local;
       // Copy keys to avoid concurrent modification error.
       for (MapEntry<String, MemberBuilder> entry in constructors.entries) {
         Builder? declaration = entry.value;
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 1b39c45..f41c3b9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -288,7 +288,7 @@
         initializers.last is SuperInitializer) {
       superTarget = (initializers.last as SuperInitializer).target;
     } else {
-      MemberBuilder? memberBuilder = superclassBuilder.constructors
+      MemberBuilder? memberBuilder = superclassBuilder.constructorScope
           .lookup("", charOffset, library.fileUri);
       if (memberBuilder is ConstructorBuilder) {
         superTarget = memberBuilder.constructor;
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 6455359..d2e74f6 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -626,7 +626,7 @@
           String constructorName =
               enumConstantInfo.constructorReferenceBuilder?.suffix ?? "";
           MemberBuilder? constructorBuilder =
-              constructorScopeBuilder[constructorName];
+              constructorScope.lookupLocalMember(constructorName);
 
           ArgumentsImpl arguments;
           List<Expression> enumSyntheticArguments = <Expression>[
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index ce1548c..8c5da3c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -3709,7 +3709,7 @@
           count += computeDefaultTypesForVariables(declaration.typeVariables,
               inErrorRecovery: issues.isNotEmpty);
 
-          declaration.constructors.forEach((String name, Builder member) {
+          declaration.constructorScope.forEach((String name, Builder member) {
             List<FormalParameterBuilder>? formals;
             if (member is SourceFactoryBuilder) {
               assert(member.isFactory,
@@ -3908,9 +3908,9 @@
         // import it into the patch library. This ensures that the origin
         // library is in scope of the patch library.
         if (isSetter) {
-          scopeBuilder.addSetter(name, member as MemberBuilder);
+          scope.addLocalMember(name, member as MemberBuilder, setter: true);
         } else {
-          scopeBuilder.addMember(name, member);
+          scope.addLocalMember(name, member, setter: false);
         }
       }
     }
@@ -3954,10 +3954,10 @@
   void injectMemberFromPatch(String name, Builder member) {
     if (member.isSetter) {
       assert(scope.lookupLocalMember(name, setter: true) == null);
-      scopeBuilder.addSetter(name, member as MemberBuilder);
+      scope.addLocalMember(name, member as MemberBuilder, setter: true);
     } else {
       assert(scope.lookupLocalMember(name, setter: false) == null);
-      scopeBuilder.addMember(name, member);
+      scope.addLocalMember(name, member, setter: false);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 257a4b8..88c7198 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1554,7 +1554,7 @@
             Map<String, List<String>>? constructorMap;
             for (ClassBuilder macroClass in macroClasses) {
               List<String> constructors =
-                  macroClass.constructors.local.keys.toList();
+                  macroClass.constructorScope.local.keys.toList();
               if (constructors.isNotEmpty) {
                 // TODO(johnniwinther): If there is no constructor here, it
                 // means the macro had no _explicit_ constructors. Since macro
@@ -1878,7 +1878,7 @@
 
   void _checkConstructorsForMixin(
       SourceClassBuilder cls, ClassBuilder builder) {
-    for (Builder constructor in builder.constructors.local.values) {
+    for (Builder constructor in builder.constructorScope.local.values) {
       if (constructor.isConstructor && !constructor.isSynthetic) {
         cls.addProblem(
             templateIllegalMixinDueToConstructors
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 4c4f476..a764f12 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -177,7 +177,7 @@
   MemberBuilder? memberBuilder;
   if (classBuilder != null) {
     if (member is Constructor || member is Procedure && member.isFactory) {
-      memberBuilder = classBuilder.constructors.local[memberName];
+      memberBuilder = classBuilder.constructorScope.local[memberName];
     } else {
       memberBuilder = classBuilder.scope.lookupLocalMember(memberName,
           setter: member is Procedure && member.isSetter) as MemberBuilder?;
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index c171029..2091796 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -34,11 +34,21 @@
         location.columnNumber, _computeEnclosingName(node));
   }
 
-  factory CodeReference.fromElement(
-      Element element, LineInfo Function(String) getLineInfo) {
-    var path = element.source!.fullName;
+  factory CodeReference.fromElement(Element element) {
+    var unitElement = element.thisOrAncestorOfType<CompilationUnitElement>();
+    if (unitElement == null) {
+      var enclosingElement = element.enclosingElement;
+      if (enclosingElement is LibraryElement) {
+        unitElement = enclosingElement.definingCompilationUnit;
+      } else {
+        throw StateError('Unexpected element: $element');
+      }
+    }
+
+    var path = unitElement.source.fullName;
     var offset = element.nameOffset;
-    var location = getLineInfo(path).getLocation(offset);
+
+    var location = unitElement.lineInfo!.getLocation(offset);
     return CodeReference(path, offset, location.lineNumber,
         location.columnNumber, _computeElementFullName(element));
   }
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 93691b6..2a30f55 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -546,17 +546,14 @@
               resourceProvider.getFile(s).exists)
           .toSet();
 
-  NonNullableFix createNonNullableFix(
-      DartFixListener listener,
-      ResourceProvider resourceProvider,
-      LineInfo Function(String path) getLineInfo,
-      Object? bindAddress,
+  NonNullableFix createNonNullableFix(DartFixListener listener,
+      ResourceProvider resourceProvider, Object? bindAddress,
       {List<String> included = const <String>[],
       int? preferredPort,
       String? summaryPath,
       required String sdkPath}) {
-    return NonNullableFix(listener, resourceProvider, getLineInfo, bindAddress,
-        logger, (String? path) => shouldBeMigrated(path!),
+    return NonNullableFix(listener, resourceProvider, bindAddress, logger,
+        (String? path) => shouldBeMigrated(path!),
         included: included,
         preferredPort: preferredPort,
         summaryPath: summaryPath,
@@ -661,8 +658,8 @@
     _fixCodeProcessor = _FixCodeProcessor(analysisContext, this);
     _dartFixListener = DartFixListener(
         DriverProviderImpl(resourceProvider, analysisContext), this);
-    nonNullableFix = createNonNullableFix(_dartFixListener!, resourceProvider,
-        _fixCodeProcessor!.getLineInfo, computeBindAddress(),
+    nonNullableFix = createNonNullableFix(
+        _dartFixListener!, resourceProvider, computeBindAddress(),
         included: [options.directory],
         preferredPort: options.previewPort,
         summaryPath: options.summary,
@@ -1000,9 +997,6 @@
 
   bool get isPreviewServerRunning => _task?.isPreviewServerRunning ?? false;
 
-  LineInfo getLineInfo(String path) =>
-      (context.currentSession.getFile(path) as FileResult).lineInfo;
-
   void prepareToRerun() {
     var driver = context.driver;
     pathsToProcess = _migrationCli.computePathsToProcess(context);
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index a780bfa..c549d2d 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -321,7 +321,6 @@
   /// should be warned about or removed (in the way specified by
   /// [removeViaComments]).
   factory NullabilityMigration(NullabilityMigrationListener? listener,
-      LineInfo Function(String) getLineInfo,
       {bool? permissive,
       NullabilityMigrationInstrumentation? instrumentation,
       bool? removeViaComments,
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
index ae86a52..8873cd0 100644
--- a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
@@ -22,10 +21,7 @@
 
   final TypeProvider _typeProvider;
 
-  final LineInfo Function(String) _getLineInfo;
-
-  AlreadyMigratedCodeDecorator(
-      this._graph, this._typeProvider, this._getLineInfo);
+  AlreadyMigratedCodeDecorator(this._graph, this._typeProvider);
 
   /// Transforms [type], which should have come from code that has already been
   /// migrated to NNBD, into the corresponding [DecoratedType].
@@ -118,7 +114,7 @@
     }
     return [
       for (var t in allSupertypes)
-        decorate(t, class_, NullabilityNodeTarget.element(class_, _getLineInfo))
+        decorate(t, class_, NullabilityNodeTarget.element(class_))
     ];
   }
 }
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index fea31af..83e0fd0 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -57,8 +57,6 @@
 
   final ResourceProvider resourceProvider;
 
-  final LineInfo Function(String) _getLineInfo;
-
   /// The HTTP server that serves the preview tool.
   HttpPreviewServer? _server;
 
@@ -85,8 +83,8 @@
   /// Completes when the server has been shutdown.
   late Completer<void> serverIsShutdown;
 
-  NonNullableFix(this.listener, this.resourceProvider, this._getLineInfo,
-      this.bindAddress, this._logger, this.shouldBeMigratedFunction,
+  NonNullableFix(this.listener, this.resourceProvider, this.bindAddress,
+      this._logger, this.shouldBeMigratedFunction,
       {List<String> included = const [],
       this.preferredPort,
       this.summaryPath,
@@ -176,7 +174,7 @@
             ? null
             : MigrationSummary(summaryPath, resourceProvider, includedRoot));
     adapter = NullabilityMigrationAdapter(listener);
-    migration = NullabilityMigration(adapter, _getLineInfo,
+    migration = NullabilityMigration(adapter,
         permissive: true, instrumentation: instrumentationListener);
   }
 
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 965e616..fde5e28 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -42,8 +42,6 @@
   @override
   final Source? source;
 
-  final LineInfo Function(String) _getLineInfo;
-
   /// If the parameters of a function or method are being visited, the
   /// [DecoratedType]s of the function's named parameters that have been seen so
   /// far.  Otherwise `null`.
@@ -72,7 +70,7 @@
   bool _visitingExternalDeclaration = false;
 
   NodeBuilder(this._variables, this.source, this.listener, this._graph,
-      this._typeProvider, this._getLineInfo,
+      this._typeProvider,
       {this.instrumentation});
 
   NullabilityNodeTarget get safeTarget {
@@ -95,7 +93,7 @@
     var exceptionElement = node.exceptionParameter?.staticElement;
     var target = exceptionElement == null
         ? NullabilityNodeTarget.text('exception type')
-        : NullabilityNodeTarget.element(exceptionElement, _getLineInfo);
+        : NullabilityNodeTarget.element(exceptionElement);
     DecoratedType? exceptionType = _pushNullabilityNodeTarget(
         target, () => node.exceptionType?.accept(this));
     if (node.exceptionParameter != null) {
@@ -167,8 +165,7 @@
       assert(constructorElement.isSynthetic);
       var decoratedReturnType =
           _createDecoratedTypeForClass(classElement, node);
-      var target =
-          NullabilityNodeTarget.element(constructorElement, _getLineInfo);
+      var target = NullabilityNodeTarget.element(constructorElement);
       var functionType = DecoratedType.forImplicitFunction(
           _typeProvider, constructorElement.type, _graph.never, _graph, target,
           returnType: decoratedReturnType);
@@ -217,7 +214,7 @@
   DecoratedType? visitDeclaredIdentifier(DeclaredIdentifier node) {
     node.metadata.accept(this);
     var declaredElement = node.declaredElement!;
-    var target = NullabilityNodeTarget.element(declaredElement, _getLineInfo);
+    var target = NullabilityNodeTarget.element(declaredElement);
     DecoratedType? type =
         _pushNullabilityNodeTarget(target, () => node.type?.accept(this));
     if (type == null) {
@@ -267,13 +264,12 @@
 
     for (var item in node.constants) {
       var declaredElement = item.declaredElement!;
-      var target = NullabilityNodeTarget.element(declaredElement, _getLineInfo);
+      var target = NullabilityNodeTarget.element(declaredElement);
       _variables!.recordDecoratedElementType(declaredElement,
           DecoratedType(classElement.thisType, makeNonNullNode(target, item)));
     }
     final valuesGetter = classElement.getGetter('values')!;
-    var valuesTarget =
-        NullabilityNodeTarget.element(valuesGetter, _getLineInfo);
+    var valuesTarget = NullabilityNodeTarget.element(valuesGetter);
     _variables!.recordDecoratedElementType(
         valuesGetter,
         DecoratedType(valuesGetter.type, makeNonNullNode(valuesTarget),
@@ -363,7 +359,7 @@
     var functionType = functionElement.type;
     var returnType = node.returnType;
     DecoratedType? decoratedReturnType;
-    var target = NullabilityNodeTarget.element(declaredElement, _getLineInfo);
+    var target = NullabilityNodeTarget.element(declaredElement);
     if (returnType != null) {
       _pushNullabilityNodeTarget(target.returnType(), () {
         decoratedReturnType = returnType.accept(this);
@@ -410,8 +406,7 @@
     node.metadata.accept(this);
     DecoratedType? decoratedFunctionType;
     node.typeParameters?.accept(this);
-    var target =
-        NullabilityNodeTarget.element(node.declaredElement!, _getLineInfo);
+    var target = NullabilityNodeTarget.element(node.declaredElement!);
     _pushNullabilityNodeTarget(target, () {
       decoratedFunctionType = node.functionType!.accept(this);
     });
@@ -647,8 +642,7 @@
     node.metadata.accept(this);
     var typeAnnotation = node.type;
     var declaredType = _pushNullabilityNodeTarget(
-        NullabilityNodeTarget.element(
-            node.variables.first.declaredElement!, _getLineInfo),
+        NullabilityNodeTarget.element(node.variables.first.declaredElement!),
         () => typeAnnotation?.accept(this));
     var hint = getPrefixHint(node.firstTokenAfterCommentAndMetadata);
     if (hint != null && hint.kind == HintCommentKind.late_) {
@@ -663,8 +657,7 @@
       var declaredElement = variable.declaredElement;
       var type = declaredType;
       if (type == null) {
-        var target =
-            NullabilityNodeTarget.element(declaredElement!, _getLineInfo);
+        var target = NullabilityNodeTarget.element(declaredElement!);
         type = DecoratedType.forImplicitType(
             _typeProvider, declaredElement.type, _graph, target);
         instrumentation?.implicitType(source, node, type);
@@ -747,7 +740,7 @@
       }
       var functionType = declaredElement.type;
       DecoratedType? decoratedReturnType;
-      var target = NullabilityNodeTarget.element(declaredElement, _getLineInfo);
+      var target = NullabilityNodeTarget.element(declaredElement);
       if (returnType != null) {
         _pushNullabilityNodeTarget(target.returnType(), () {
           decoratedReturnType = returnType.accept(this);
@@ -931,8 +924,7 @@
     }
     var decoratedSupertypes = <ClassElement, DecoratedType?>{};
     _pushNullabilityNodeTarget(
-        NullabilityNodeTarget.element(declaredElement, _getLineInfo).supertype,
-        () {
+        NullabilityNodeTarget.element(declaredElement).supertype, () {
       for (var supertype in supertypes) {
         DecoratedType? decoratedSupertype;
         if (supertype == null) {
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index a9d155e..c0f6603 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -49,8 +49,6 @@
 
   final _decoratedTypeParameterBounds = DecoratedTypeParameterBounds();
 
-  final LineInfo Function(String) _getLineInfo;
-
   /// Map from [Source] object to a boolean indicating whether the source is
   /// opted in to null safety.
   final Map<Source, bool> _libraryOptInStatus = {};
@@ -77,28 +75,27 @@
   /// should be warned about or removed (in the way specified by
   /// [removeViaComments]).
   NullabilityMigrationImpl(NullabilityMigrationListener? listener,
-      LineInfo Function(String) getLineInfo,
       {bool? permissive = false,
       NullabilityMigrationInstrumentation? instrumentation,
       bool? removeViaComments = false,
       bool? warnOnWeakCode = true})
       : this._(
-            listener,
-            NullabilityGraph(instrumentation: instrumentation),
-            permissive,
-            instrumentation,
-            removeViaComments,
-            warnOnWeakCode,
-            getLineInfo);
+          listener,
+          NullabilityGraph(instrumentation: instrumentation),
+          permissive,
+          instrumentation,
+          removeViaComments,
+          warnOnWeakCode,
+        );
 
   NullabilityMigrationImpl._(
-      this.listener,
-      this._graph,
-      this._permissive,
-      this._instrumentation,
-      this.removeViaComments,
-      this.warnOnWeakCode,
-      this._getLineInfo) {
+    this.listener,
+    this._graph,
+    this._permissive,
+    this._instrumentation,
+    this.removeViaComments,
+    this.warnOnWeakCode,
+  ) {
     _instrumentation?.immutableNodes(_graph.never, _graph.always);
   }
 
@@ -199,20 +196,15 @@
     _recordTransitiveImportExportOptInStatus(
         result.libraryElement.exportedLibraries);
     if (_variables == null) {
-      _variables = Variables(_graph, result.typeProvider, _getLineInfo,
+      _variables = Variables(_graph, result.typeProvider,
           instrumentation: _instrumentation);
       _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph);
     }
     var unit = result.unit;
     try {
       DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
-      unit.accept(NodeBuilder(
-          _variables,
-          unit.declaredElement!.source,
-          _permissive! ? listener : null,
-          _graph,
-          result.typeProvider,
-          _getLineInfo,
+      unit.accept(NodeBuilder(_variables, unit.declaredElement!.source,
+          _permissive! ? listener : null, _graph, result.typeProvider,
           instrumentation: _instrumentation));
     } finally {
       DecoratedTypeParameterBounds.current = null;
diff --git a/pkg/nnbd_migration/lib/src/nullability_node_target.dart b/pkg/nnbd_migration/lib/src/nullability_node_target.dart
index da43dbd..38833b9 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node_target.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node_target.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 
 String _computeElementName(Element? element) {
@@ -29,8 +28,7 @@
 /// code is referenced by a given nullability node.
 abstract class NullabilityNodeTarget {
   /// Creates a [NullabilityNodeTarget] referring to a particular element.
-  factory NullabilityNodeTarget.element(
-          Element element, LineInfo Function(String) getLineInfo) =
+  factory NullabilityNodeTarget.element(Element element) =
       _NullabilityNodeTarget_Element;
 
   /// Creates a [NullabilityNodeTarget] with a simple text description.
@@ -111,10 +109,9 @@
 
   final CodeReference codeReference;
 
-  _NullabilityNodeTarget_Element(
-      Element element, LineInfo Function(String) getLineInfo)
+  _NullabilityNodeTarget_Element(Element element)
       : name = _computeElementName(element),
-        codeReference = CodeReference.fromElement(element, getLineInfo),
+        codeReference = CodeReference.fromElement(element),
         super._();
 
   @override
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 7222753..8246f140 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -69,12 +69,9 @@
 
   final NullabilityMigrationInstrumentation? instrumentation;
 
-  final LineInfo Function(String) _getLineInfo;
-
-  Variables(this._graph, this._typeProvider, this._getLineInfo,
-      {this.instrumentation})
+  Variables(this._graph, this._typeProvider, {this.instrumentation})
       : _alreadyMigratedCodeDecorator =
-            AlreadyMigratedCodeDecorator(_graph, _typeProvider, _getLineInfo);
+            AlreadyMigratedCodeDecorator(_graph, _typeProvider);
 
   /// Given a [class_], gets the decorated type information for the superclasses
   /// it directly implements/extends/etc.
@@ -400,7 +397,7 @@
       element = element.aliasedElement!;
     }
 
-    var target = NullabilityNodeTarget.element(element, _getLineInfo);
+    var target = NullabilityNodeTarget.element(element);
     if (element is FunctionTypedElement) {
       decoratedType = _alreadyMigratedCodeDecorator.decorate(
           element.preMigrationType, element, target);
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
index 51c7632..2965a8a 100644
--- a/pkg/nnbd_migration/test/abstract_context.dart
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -5,7 +5,6 @@
 import 'dart:convert';
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
@@ -165,9 +164,6 @@
     return _getContext(path).driver;
   }
 
-  LineInfo getLineInfo(String path) =>
-      (session.getFile(path) as FileResult).lineInfo;
-
   void setUp() {
     setupResourceProvider();
     overlayResourceProvider = OverlayResourceProvider(resourceProvider);
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
index 7eeea96..dcc89c4 100644
--- a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
@@ -353,7 +352,7 @@
     expect(decoratedSupertypes, hasLength(2));
     // TODO(scheglov) Use location matcher.
     withElement.checkObject(decoratedSupertypes[0],
-        withElement.checkExplicitlyNonNullable, 'Future (async.dart:1:79)');
+        withElement.checkExplicitlyNonNullable, 'Future (async.dart:7:16)');
     // Since Future<T> is a subtype of FutureOr<T>, we consider FutureOr<T> to
     // be an immediate supertype, even though the class declaration for Future
     // doesn't mention FutureOr.
@@ -363,7 +362,7 @@
         withElement.checkExplicitlyNonNullable,
         (t, displayName) => withElement.checkTypeParameter(
             t!, withElement.checkExplicitlyNonNullable, typeParam, displayName),
-        'Future (async.dart:1:79)');
+        'Future (async.dart:7:16)');
   }
 
   Future<void> test_getImmediateSupertypes_generic() async {
@@ -492,8 +491,7 @@
   NullabilityNode get always => graph.always;
 
   AlreadyMigratedCodeDecorator get decorator {
-    return AlreadyMigratedCodeDecorator(
-        graph, typeProvider, (_) => LineInfo([0]));
+    return AlreadyMigratedCodeDecorator(graph, typeProvider);
   }
 
   NullabilityNode get never => graph.never;
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index e2799e8..c88be9a 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -60,7 +60,7 @@
       newFile(path, content: input[path]!);
     }
     var listener = TestMigrationListener();
-    var migration = NullabilityMigration(listener, getLineInfo,
+    var migration = NullabilityMigration(listener,
         permissive: _usePermissiveMode,
         removeViaComments: removeViaComments,
         warnOnWeakCode: warnOnWeakCode);
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
index 3f28996..0ca6fe8 100644
--- a/pkg/nnbd_migration/test/decorated_type_test.dart
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -41,7 +40,7 @@
   factory DecoratedTypeTest() {
     var typeProvider = TestTypeProvider();
     var graph = NullabilityGraph();
-    var variables = Variables(graph, typeProvider, _getLineInfo);
+    var variables = Variables(graph, typeProvider);
     return DecoratedTypeTest._(graph, typeProvider, variables);
   }
 
@@ -616,8 +615,6 @@
     var decoratedType = function(dynamic_, positional: [xType], node: always);
     expect(decoratedType.toString(), 'dynamic Function([$xType])?');
   }
-
-  static LineInfo _getLineInfo(String path) => LineInfo([0]);
 }
 
 class _ElementTypeProvider extends ElementTypeProvider {
diff --git a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
index 451a1d7..047149f 100644
--- a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -228,7 +228,7 @@
     var listener = DartFixListener(server, ListenerClient());
     var instrumentationListener = InstrumentationListener();
     var adapter = NullabilityMigrationAdapter(listener);
-    var migration = NullabilityMigration(adapter, getLineInfo,
+    var migration = NullabilityMigration(adapter,
         permissive: false,
         instrumentation: instrumentationListener,
         removeViaComments: removeViaComments,
diff --git a/pkg/nnbd_migration/test/instrumentation_test.dart b/pkg/nnbd_migration/test/instrumentation_test.dart
index 821b21c..f9a4131 100644
--- a/pkg/nnbd_migration/test/instrumentation_test.dart
+++ b/pkg/nnbd_migration/test/instrumentation_test.dart
@@ -144,7 +144,7 @@
     var sourcePath = convertPath('$testsPath/lib/test.dart');
     newFile(sourcePath, content: content);
     var listener = TestMigrationListener();
-    var migration = NullabilityMigration(listener, getLineInfo,
+    var migration = NullabilityMigration(listener,
         instrumentation: _InstrumentationClient(this),
         removeViaComments: removeViaComments,
         warnOnWeakCode: warnOnWeakCode);
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index c0523f6..0d289f8 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart' as mock_sdk;
 import 'package:args/args.dart';
@@ -63,17 +62,13 @@
 /// Specialization of [NonNullableFix] that generates artificial exceptions, so
 /// that we can test they are properly propagated to top level.
 class _ExceptionGeneratingNonNullableFix extends NonNullableFix {
-  _ExceptionGeneratingNonNullableFix(
-      DartFixListener listener,
-      ResourceProvider resourceProvider,
-      LineInfo Function(String) getLineInfo,
-      Object? bindAddress,
-      Logger logger,
+  _ExceptionGeneratingNonNullableFix(DartFixListener listener,
+      ResourceProvider resourceProvider, Object? bindAddress, Logger logger,
       {List<String> included = const <String>[],
       int? preferredPort,
       String? summaryPath,
       required String sdkPath})
-      : super(listener, resourceProvider, getLineInfo, bindAddress, logger,
+      : super(listener, resourceProvider, bindAddress, logger,
             (String? path) => true,
             included: included,
             preferredPort: preferredPort,
@@ -141,25 +136,21 @@
       _sortPaths(super.computePathsToProcess(context));
 
   @override
-  NonNullableFix createNonNullableFix(
-      DartFixListener listener,
-      ResourceProvider resourceProvider,
-      LineInfo Function(String path) getLineInfo,
-      Object? bindAddress,
+  NonNullableFix createNonNullableFix(DartFixListener listener,
+      ResourceProvider resourceProvider, Object? bindAddress,
       {List<String> included = const <String>[],
       int? preferredPort,
       String? summaryPath,
       required String sdkPath}) {
     if (cli._test.injectArtificialException) {
       return _ExceptionGeneratingNonNullableFix(
-          listener, resourceProvider, getLineInfo, bindAddress, logger,
+          listener, resourceProvider, bindAddress, logger,
           included: included,
           preferredPort: preferredPort,
           summaryPath: summaryPath,
           sdkPath: sdkPath);
     } else {
-      return super.createNonNullableFix(
-          listener, resourceProvider, getLineInfo, bindAddress,
+      return super.createNonNullableFix(listener, resourceProvider, bindAddress,
           included: included,
           preferredPort: preferredPort,
           summaryPath: summaryPath,
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 85448d0..3f57caae 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -304,9 +304,8 @@
 
   final _expressionChecks = <Expression, ExpressionChecksOrigin>{};
 
-  InstrumentedVariables(NullabilityGraph graph, TypeProvider typeProvider,
-      LineInfo Function(String) getLineInfo)
-      : super(graph, typeProvider, getLineInfo);
+  InstrumentedVariables(NullabilityGraph graph, TypeProvider typeProvider)
+      : super(graph, typeProvider);
 
   /// Gets the [ExpressionChecks] associated with the given [expression].
   ExpressionChecksOrigin? checkExpression(Expression expression) =>
@@ -370,9 +369,9 @@
 
   Future<CompilationUnit> analyze(String code) async {
     await resolveTestUnit(code);
-    variables = InstrumentedVariables(graph, typeProvider, getLineInfo);
-    testUnit!.accept(NodeBuilder(
-        variables, testSource, null, graph, typeProvider, getLineInfo));
+    variables = InstrumentedVariables(graph, typeProvider);
+    testUnit!
+        .accept(NodeBuilder(variables, testSource, null, graph, typeProvider));
     return testUnit!;
   }
 
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
index 982cbf7..d4f9d61 100644
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ b/pkg/nnbd_migration/tool/trial_migration.dart
@@ -66,10 +66,7 @@
           context.contextRoot.analyzedFiles().where((s) => s.endsWith('.dart'));
       files.addAll(localFiles);
       var session = context.currentSession;
-      LineInfo getLineInfo(String path) =>
-          (session.getFile(path) as FileResult).lineInfo;
-      var migration =
-          NullabilityMigration(listener, getLineInfo, permissive: true);
+      var migration = NullabilityMigration(listener, permissive: true);
       for (var file in localFiles) {
         var resolvedUnit =
             await session.getResolvedUnit(file) as ResolvedUnitResult;
diff --git a/tools/VERSION b/tools/VERSION
index f45b0e0..d69f4db 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 160
+PRERELEASE 161
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 8845d5c..b35e47a 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3560,6 +3560,14 @@
           ]
         },
         {
+          "name": "validate .dart_tool/package_config.json",
+          "script": "tools/sdks/dart-sdk/bin/dart",
+          "arguments": [
+            "tools/generate_package_config.dart",
+            "--check"
+          ]
+        },
+        {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 417b548..b4ba277 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -1,80 +1,136 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
+#!/usr/bin/env dart
 
 /// Generates the repo's ".dart_tool/package_config.json" file.
 import 'dart:convert';
 import 'dart:io';
 
-// Important! Do not add package: imports to this file.
-// Do not add relative deps for libraries that themselves use package deps.
-// This tool runs before the .dart_tool/package_config.json file is created, so
-// can not itself use package references.
+import 'package:args/args.dart';
+import 'package:path/path.dart' as p;
+import 'package:pub_semver/pub_semver.dart';
+import 'package:yaml/yaml.dart';
 
-final repoRoot = dirname(dirname(fromUri(Platform.script)));
+bool _parseOptions(List<String> args) {
+  const usage = "Usage: dart generate_package_config.dart [flags...]";
+
+  var parser = ArgParser();
+
+  parser.addFlag("help", abbr: "h");
+
+  parser.addFlag("check",
+      abbr: "c",
+      help: "Return with a non-zero exit code if not up-to-date",
+      negatable: false);
+
+  var results = parser.parse(args);
+
+  if (results["help"] as bool) {
+    print("Regenerate the .dart_tool/package_config.json file.");
+    print("");
+    print(usage);
+    print("");
+    print(parser.usage);
+    exit(0);
+  }
+
+  return results["check"] as bool;
+}
+
+final repoRoot = p.dirname(p.dirname(p.fromUri(Platform.script)));
+final configFilePath = p.join(repoRoot, '.dart_tool/package_config.json');
 
 void main(List<String> args) {
+  bool checkOnly = _parseOptions(args);
+
   var packageDirs = [
-    ...listSubdirectories(platform('pkg')),
-    ...listSubdirectories(platform('third_party/pkg_tested')),
-    ...listSubdirectories(platform('third_party/pkg')),
-    ...listSubdirectories(platform('third_party/pkg/file/packages')),
-    ...listSubdirectories(platform('third_party/pkg/test/pkgs')),
-    platform('pkg/vm_service/test/test_package'),
-    platform('runtime/observatory_2'),
-    platform(
+    ...listSubdirectories('pkg'),
+    ...listSubdirectories('third_party/pkg'),
+    ...listSubdirectories('third_party/pkg_tested'),
+    ...listSubdirectories('third_party/pkg/file/packages'),
+    ...listSubdirectories('third_party/pkg/test/pkgs'),
+    packageDirectory('runtime/observatory'),
+    packageDirectory(
+        'runtime/observatory/tests/service/observatory_test_package'),
+    packageDirectory('runtime/observatory_2'),
+    packageDirectory(
         'runtime/observatory_2/tests/service_2/observatory_test_package_2'),
-    platform('runtime/observatory'),
-    platform('runtime/observatory/tests/service/observatory_test_package'),
-    platform('sdk/lib/_internal/sdk_library_metadata'),
-    platform('third_party/devtools/devtools_shared'),
-    platform('third_party/pkg/protobuf/protobuf'),
-    platform('third_party/pkg/webdev/frontend_server_client'),
-    platform('tools/package_deps'),
+    packageDirectory('pkg/vm_service/test/test_package'),
+    packageDirectory('sdk/lib/_internal/sdk_library_metadata'),
+    packageDirectory('third_party/devtools/devtools_shared'),
+    packageDirectory('third_party/pkg/protobuf/protobuf'),
+    packageDirectory('third_party/pkg/webdev/frontend_server_client'),
+    packageDirectory('tools/package_deps'),
   ];
 
   var cfePackageDirs = [
-    platform('pkg/front_end/testcases'),
+    packageDirectory('pkg/front_end/testcases/'),
   ];
 
   var feAnalyzerSharedPackageDirs = [
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables'),
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment'),
-    platform(
-        'pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment'),
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/nullability'),
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/reachability'),
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion'),
-    platform('pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted'),
-    platform('pkg/_fe_analyzer_shared/test/inheritance'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables/'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/definite_assignment/'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/'),
+    packageDirectory('pkg/_fe_analyzer_shared/test/flow_analysis/nullability/'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/reachability/'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/'),
+    packageDirectory(
+        'pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted//'),
+    packageDirectory('pkg/_fe_analyzer_shared/test/inheritance/'),
   ];
 
-  var packages = <Package>[
+  var packages = [
     ...makePackageConfigs(packageDirs),
     ...makeCfePackageConfigs(cfePackageDirs),
     ...makeFeAnalyzerSharedPackageConfigs(feAnalyzerSharedPackageDirs)
   ];
-  packages.sort((a, b) => a.name.compareTo(b.name));
+  packages.sort((a, b) => a['name']!.compareTo(b['name']!));
 
-  var configFile = File(join(repoRoot, '.dart_tool', 'package_config.json'));
-  var packageConfig = PackageConfig(
-    packages,
-    extraData: {
-      'copyright': [
-        'Copyright (c) 2020, the Dart project authors. Please see the AUTHORS ',
-        'file for details. All rights reserved. Use of this source code is ',
-        'governed by a BSD-style license that can be found in the LICENSE file.',
-      ],
-      'comment': [
-        'Package configuration for all packages in pkg/, third_party/pkg/, and',
-        'third_party/pkg_tested/',
-      ],
-    },
-  );
-  writeIfDifferent(configFile, packageConfig.generateJson('..'));
+  var configFile = File(p.join(repoRoot, '.dart_tool', 'package_config.json'));
+  var json = jsonDecode(configFile.readAsStringSync()) as Map<dynamic, dynamic>;
+  var oldPackages = json['packages'] as List<dynamic>;
 
-  // Also generate the repo's .packages file.
-  var packagesFile = File(join(repoRoot, '.packages'));
+  if (checkOnly) {
+    // Validate the packages entry only, to avoid spurious failures from changes
+    // in the dates embedded in the other entries.
+    if (jsonEncode(packages) == jsonEncode(oldPackages)) {
+      print("Package config up to date.");
+      exit(0);
+    } else {
+      print("Package config out of date.");
+      print("Run `gclient sync -D && dart tools/generate_package_config.dart` "
+          "to update.");
+      exit(1);
+    }
+  }
+
+  var year = DateTime.now().year;
+  var config = <String, dynamic>{
+    'copyright': [
+      'Copyright (c) $year, the Dart project authors. Please see the AUTHORS ',
+      'file for details. All rights reserved. Use of this source code is ',
+      'governed by a BSD-style license that can be found in the LICENSE file.'
+    ],
+    'comment': [
+      'Package configuration for all packages in /pkg, and checked out by DEPS',
+      'into /third_party/pkg and /third_party/pkg_tested.',
+      'If you add a package to DEPS or /pkg or change a package\'s SDK',
+      'constraint, update this by running tools/generate_package_config.dart.'
+    ],
+    'configVersion': 2,
+    'generator': 'tools/generate_package_config.dart',
+    'packages': packages,
+  };
+
+  // TODO(rnystrom): Consider using package_config_v2 to generate this instead.
+  var jsonString = JsonEncoder.withIndent('  ').convert(config);
+  configFile.writeAsStringSync('$jsonString\n');
+
+  // Also generate the reop's .packages file.
+  var packagesFile = File(p.join(repoRoot, '.packages'));
   var buffer = StringBuffer('''
 # Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
@@ -85,190 +141,114 @@
 
 ''');
   for (var package in packages) {
-    final name = package.name;
-    final rootUri = package.rootUri;
-    final packageUri = package.packageUri;
-
+    final name = package['name'];
+    var path = package['rootUri']!;
+    if (path.startsWith('../')) {
+      path = path.substring('../'.length);
+    }
+    var packageUri = package['packageUri'];
+    if (packageUri != null && packageUri.endsWith('/')) {
+      packageUri = packageUri.substring(0, packageUri.length - 1);
+    }
     if (packageUri != null && packageUri != '.nonexisting') {
-      buffer.writeln('$name:${posix(rootUri)}/${posix(packageUri)}');
+      buffer.writeln('$name:$path/$packageUri');
     }
   }
-  writeIfDifferent(packagesFile, buffer.toString());
-}
-
-/// Writes the given [contents] string to [file] if the contents are different
-/// than what's currently in the file.
-///
-/// This updates the file to the given contents, while preserving the file
-/// timestamp if there are no changes.
-void writeIfDifferent(File file, String contents) {
-  if (!file.existsSync() || file.readAsStringSync() != contents) {
-    file.writeAsStringSync(contents);
-  }
+  packagesFile.writeAsStringSync(buffer.toString());
 }
 
 /// Generates package configurations for each package in [packageDirs].
-Iterable<Package> makePackageConfigs(List<String> packageDirs) sync* {
+Iterable<Map<String, String>> makePackageConfigs(
+    List<String> packageDirs) sync* {
   for (var packageDir in packageDirs) {
     var version = pubspecLanguageVersion(packageDir);
-    var hasLibDirectory =
-        Directory(join(repoRoot, packageDir, 'lib')).existsSync();
+    var hasLibDirectory = Directory(p.join(packageDir, 'lib')).existsSync();
 
-    yield Package(
-      name: basename(packageDir),
-      rootUri: packageDir,
-      packageUri: hasLibDirectory ? 'lib/' : null,
-      languageVersion: version,
-    );
-  }
-}
-
-/// Generates package configurations for the special pseudo-packages used by the
-/// CFE unit tests (`pkg/front_end/test/unit_test_suites.dart`).
-Iterable<Package> makeCfePackageConfigs(List<String> packageDirs) sync* {
-  // TODO: Remove the use of '.nonexisting/'.
-  for (var packageDir in packageDirs) {
-    yield Package(
-      name: 'front_end_${basename(packageDir)}',
-      rootUri: packageDir,
-      packageUri: '.nonexisting/',
-    );
-  }
-}
-
-/// Generates package configurations for the special pseudo-packages used by the
-/// _fe_analyzer_shared id tests.
-Iterable<Package> makeFeAnalyzerSharedPackageConfigs(
-    List<String> packageDirs) sync* {
-  // TODO: Remove the use of '.nonexisting/'.
-  for (var packageDir in packageDirs) {
-    yield Package(
-      name: '_fe_analyzer_shared_${basename(packageDir)}',
-      rootUri: packageDir,
-      packageUri: '.nonexisting/',
-    );
-  }
-}
-
-/// Finds the paths of the immediate subdirectories of [dir] that
-/// contain pubspecs.
-Iterable<String> listSubdirectories(String dir) sync* {
-  for (var entry in Directory(join(repoRoot, dir)).listSync()) {
-    if (entry is! Directory) continue;
-    if (!File(join(entry.path, 'pubspec.yaml')).existsSync()) continue;
-    yield join(dir, basename(entry.path));
-  }
-}
-
-final versionRE = RegExp(r"(?:\^|>=)(\d+\.\d+)");
-
-/// Infers the language version from the SDK constraint in the pubspec for
-/// [packageDir].
-///
-/// The version is returned in the form `major.minor`.
-String? pubspecLanguageVersion(String packageDir) {
-  var pubspecFile = File(join(repoRoot, packageDir, 'pubspec.yaml'));
-
-  if (!pubspecFile.existsSync()) {
-    print("Error: Missing pubspec for $packageDir.");
-    exit(1);
-  }
-
-  var contents = pubspecFile.readAsLinesSync();
-  if (!contents.any((line) => line.contains('sdk: '))) {
-    print("Error: Pubspec for $packageDir has no SDK constraint.");
-    exit(1);
-  }
-
-  // Handle either "sdk: >=2.14.0 <3.0.0" or "sdk: ^2.3.0".
-  var sdkConstraint = contents.firstWhere((line) => line.contains('sdk: '));
-  sdkConstraint = sdkConstraint.trim().substring('sdk:'.length).trim();
-  if (sdkConstraint.startsWith('"') || sdkConstraint.startsWith("'")) {
-    sdkConstraint = sdkConstraint.substring(1, sdkConstraint.length - 2);
-  }
-
-  var match = versionRE.firstMatch(sdkConstraint);
-  if (match == null) {
-    print("Error: unknown version range for $packageDir: '$sdkConstraint'.");
-    exit(1);
-  }
-  return match[1]!;
-}
-
-class Package {
-  final String name;
-  final String rootUri;
-  final String? packageUri;
-  final String? languageVersion;
-
-  Package({
-    required this.name,
-    required this.rootUri,
-    this.packageUri,
-    this.languageVersion,
-  });
-
-  Map<String, Object?> toMap(String relativeTo) {
-    return {
-      'name': name,
-      'rootUri': posix(join(relativeTo, rootUri)),
-      if (packageUri != null) 'packageUri': posix(packageUri!),
-      if (languageVersion != null) 'languageVersion': languageVersion,
+    yield {
+      'name': p.basename(packageDir),
+      'rootUri': p
+          .toUri(p.relative(packageDir, from: p.dirname(configFilePath)))
+          .toString(),
+      if (hasLibDirectory) 'packageUri': 'lib/',
+      'languageVersion': '${version.major}.${version.minor}'
     };
   }
 }
 
-class PackageConfig {
-  final List<Package> packages;
-  final Map<String, Object?>? extraData;
-
-  PackageConfig(this.packages, {this.extraData});
-
-  String generateJson(String relativeTo) {
-    var config = <String, Object?>{};
-    if (extraData != null) {
-      for (var key in extraData!.keys) {
-        config[key] = extraData![key];
-      }
-    }
-    config['configVersion'] = 2;
-    config['generator'] = 'tools/generate_package_config.dart';
-    config['packages'] =
-        packages.map((package) => package.toMap(relativeTo)).toList();
-    var jsonString = JsonEncoder.withIndent('  ').convert(config);
-    return '$jsonString\n';
+/// Generates package configurations for the special pseudo-packages used by
+/// the CFE unit tests (`pkg/front_end/test/unit_test_suites.dart`).
+Iterable<Map<String, String>> makeCfePackageConfigs(
+    List<String> packageDirs) sync* {
+  for (var packageDir in packageDirs) {
+    yield {
+      'name': 'front_end_${p.basename(packageDir)}',
+      'rootUri': p
+          .toUri(p.relative(packageDir, from: p.dirname(configFilePath)))
+          .toString(),
+      'packageUri': '.nonexisting/',
+    };
   }
 }
 
-// Below are some (very simplified) versions of the package:path functions.
-
-final String _separator = Platform.pathSeparator;
-
-String dirname(String s) {
-  return s.substring(0, s.lastIndexOf(_separator));
-}
-
-String join(String s1, String s2, [String? s3]) {
-  if (s3 != null) {
-    return join(join(s1, s2), s3);
-  } else {
-    return s1.endsWith(_separator) ? '$s1$s2' : '$s1$_separator$s2';
+/// Generates package configurations for the special pseudo-packages used by
+/// the _fe_analyzer_shared id tests.
+Iterable<Map<String, String>> makeFeAnalyzerSharedPackageConfigs(
+    List<String> packageDirs) sync* {
+  for (var packageDir in packageDirs) {
+    yield {
+      'name': '_fe_analyzer_shared_${p.basename(packageDir)}',
+      'rootUri': p
+          .toUri(p.relative(packageDir, from: p.dirname(configFilePath)))
+          .toString(),
+      'packageUri': '.nonexisting/',
+    };
   }
 }
 
-String basename(String s) {
-  while (s.endsWith(_separator)) {
-    s = s.substring(0, s.length - 1);
+/// Generates a path to [relativePath] within the repo.
+String packageDirectory(String relativePath) => p.join(repoRoot, relativePath);
+
+/// Finds the paths of the immediate subdirectories of [packagesDir] that
+/// contain pubspecs.
+Iterable<String> listSubdirectories(String packagesDir) sync* {
+  for (var entry in Directory(p.join(repoRoot, packagesDir)).listSync()) {
+    if (entry is! Directory) continue;
+    if (!File(p.join(entry.path, 'pubspec.yaml')).existsSync()) continue;
+    yield entry.path;
   }
-  return s.substring(s.lastIndexOf(_separator) + 1);
 }
 
-String fromUri(Uri uri) => uri.toFilePath();
+/// Infers the language version from the SDK constraint in the pubspec for
+/// [packageDir].
+Version pubspecLanguageVersion(String packageDir) {
+  final dartVersion2 = Version.parse('2.0.0');
 
-/// Given a platform path, return a posix one.
-String posix(String s) =>
-    Platform.isWindows ? s.replaceAll(_separator, '/') : s;
+  var pubspecFile = File(p.join(packageDir, 'pubspec.yaml'));
+  var relative = p.relative(packageDir, from: repoRoot);
 
-/// Given a posix path, return a platform one.
-String platform(String s) =>
-    Platform.isWindows ? s.replaceAll('/', _separator) : s;
+  if (!pubspecFile.existsSync()) {
+    print("Error: Missing pubspec for $relative.");
+    exit(1);
+  }
+
+  var pubspec =
+      loadYaml(pubspecFile.readAsStringSync()) as Map<dynamic, dynamic>;
+  if (!pubspec.containsKey('environment')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
+
+  var environment = pubspec['environment'] as Map<dynamic, dynamic>;
+  if (!environment.containsKey('sdk')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
+
+  var sdkConstraint = VersionConstraint.parse(environment['sdk'] as String);
+  if (sdkConstraint is VersionRange) {
+    return sdkConstraint.min ?? dartVersion2;
+  }
+
+  print("Error: SDK constraint $relative is not a version range.");
+  exit(1);
+}
diff --git a/tools/generate_package_config.py b/tools/generate_package_config.py
deleted file mode 100644
index b763b3d..0000000
--- a/tools/generate_package_config.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Invoke the `tools/generate_package_config.dart` script.
-
-import os
-import os.path
-import platform
-import subprocess
-import sys
-
-USE_PYTHON3 = True
-
-
-def is_windows():
-    os_id = platform.system()
-    return os_id == 'Windows'
-
-
-def checked_in_sdk_path():
-    tools_dir = os.path.dirname(os.path.realpath(__file__))
-    return os.path.join(tools_dir, 'sdks', 'dart-sdk')
-
-
-def checked_in_sdk_executable():
-    name = 'dart'
-    if is_windows():
-        name = 'dart.exe'
-    return os.path.join(checked_in_sdk_path(), 'bin', name)
-
-
-def generate_package_config():
-    tools_dir = os.path.dirname(os.path.realpath(__file__))
-    process = subprocess.run([
-        checked_in_sdk_executable(),
-        os.path.join(tools_dir, 'generate_package_config.dart')
-    ])
-    return process.returncode
-
-
-def Main():
-    sys.exit(generate_package_config())
-
-
-if __name__ == '__main__':
-    Main()