Version 2.18.0-122.0.dev

Merge commit '6ebd2633cd7bb68efb53d190780be377aeecdcc6' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c44a181..5a3cc15 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@
 - Add `connectionState` attribute and `connectionstatechange` listener to
   `RtcPeerConnection`.
 
+#### `dart:js_util`
+
+- Added `dartify` and a number of minor helper functions.
+
 ### Tools
 
 #### Linter
diff --git a/DEPS b/DEPS
index 7b983ec..1a1424f1 100644
--- a/DEPS
+++ b/DEPS
@@ -80,7 +80,7 @@
   "async_rev": "f3ed5f690e2ec9dbe1bfc5184705575b4f6480e5",
   "bazel_worker_rev": "ceeba0982d4ff40d32371c9d35f3d2dc1868de20",
   "benchmark_harness_rev": "0530da692a5d689f4b5450a7c8d1a8abe3e2d555",
-  "boolean_selector_rev": "437e7f06c7e416bed91e16ae1df453555897e945",
+  "boolean_selector_rev": "1d3565e2651d16566bb556955b96ea75018cbd0c",
   "boringssl_gen_rev": "ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f",
   "boringssl_rev": "87f316d7748268eb56f2dc147bd593254ae93198",
   "browser-compat-data_tag": "ac8cae697014da1ff7124fba33b0b4245cc6cd1b", # v1.0.22
@@ -165,7 +165,7 @@
   "WebCore_rev": "bcb10901266c884e7b3740abc597ab95373ab55c",
   "webdev_rev": "8c814f9d89915418d8abe354ff9befec8f2906b2",
   "webdriver_rev": "ff5ccb1522edf4bed578ead4d65e0cbc1f2c4f02",
-  "webkit_inspection_protocol_rev": "dd6fb5d8b536e19cedb384d0bbf1f5631923f1e8",
+  "webkit_inspection_protocol_rev": "e4965778e2837adc62354eec3a19123402997897",
   "yaml_edit_rev": "0b74d85fac10b4fbf7d1a347debcf16c8f7b0e9c",
   "yaml_rev": "0971c06490b9670add644ed62182acd6a5536946",
   "zlib_rev": "27c2f474b71d0d20764f86f60ef8b00da1a16cda",
diff --git a/pkg/_js_interop_checks/pubspec.yaml b/pkg/_js_interop_checks/pubspec.yaml
index 53c668a..776dab8 100644
--- a/pkg/_js_interop_checks/pubspec.yaml
+++ b/pkg/_js_interop_checks/pubspec.yaml
@@ -7,9 +7,4 @@
 
 dependencies:
   _fe_analyzer_shared: any
-  kernel:
-    path: ../kernel
-
-dependency_overrides:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
+  kernel: any
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart
index 46710be..c1ffb23 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart
@@ -5,7 +5,9 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/completion/yaml/producer.dart';
 import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/task/options.dart';
 
@@ -17,10 +19,10 @@
   // TODO(brianwilkerson) We need to support multiple valid formats.
   //  For example, the lint rules can either be a list or a map, but we only
   //  suggest list items.
-  static const MapProducer analysisOptionsProducer = MapProducer({
+  static MapProducer analysisOptionsProducer = MapProducer({
     AnalyzerOptions.analyzer: MapProducer({
-      AnalyzerOptions.enableExperiment: EmptyProducer(),
-      AnalyzerOptions.errors: EmptyProducer(),
+      AnalyzerOptions.enableExperiment: ListProducer(_ExperimentProducer()),
+      AnalyzerOptions.errors: _ErrorProducer(),
       AnalyzerOptions.exclude: EmptyProducer(),
       AnalyzerOptions.language: MapProducer({
         AnalyzerOptions.strictCasts: EmptyProducer(),
@@ -45,7 +47,7 @@
     AnalyzerOptions.include: EmptyProducer(),
     // TODO(brianwilkerson) Create constants for 'linter' and 'rules'.
     'linter': MapProducer({
-      'rules': ListProducer(LintRuleProducer()),
+      'rules': ListProducer(_LintRuleProducer()),
     }),
   });
 
@@ -58,10 +60,49 @@
   Producer get topLevelProducer => analysisOptionsProducer;
 }
 
-class LintRuleProducer extends Producer {
+class _ErrorProducer extends KeyValueProducer {
+  static const enumProducer = EnumProducer([
+    'ignore',
+    'info',
+    'warning',
+    'error',
+  ]);
+
+  @override
+  Producer? producerForKey(String key) => enumProducer;
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var error in errorCodeValues) {
+      yield identifier('${error.name.toLowerCase()}: ');
+    }
+    for (var rule in Registry.ruleRegistry.rules) {
+      yield identifier('${rule.name}: ');
+    }
+  }
+}
+
+class _ExperimentProducer extends Producer {
+  /// Initialize a location whose valid values are the names of the known
+  /// experimental features.
+  const _ExperimentProducer();
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var feature in ExperimentStatus.knownFeatures.values) {
+      if (!feature.isEnabledByDefault) {
+        yield identifier(feature.enableString);
+      }
+    }
+  }
+}
+
+class _LintRuleProducer extends Producer {
   /// Initialize a location whose valid values are the names of the registered
   /// lint rules.
-  const LintRuleProducer();
+  const _LintRuleProducer();
 
   @override
   Iterable<CompletionSuggestion> suggestions(
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 00e4d99..4b7314d 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,43 +6,29 @@
   sdk: '>=2.17.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  analyzer:
-    path: ../analyzer
-  analyzer_plugin:
-    path: ../analyzer_plugin
+  _fe_analyzer_shared: any
+  analyzer: any
+  analyzer_plugin: any
   args: any
   collection: any
   convert: any
   crypto: any
   dart_style: any
-  http: any
   html: any
+  http: any
   linter: any
-  meta:
-    path: ../meta
-  stream_channel: any
-  telemetry:
-    path: ../telemetry
-  test: any
+  meta: any
   path: any
+  stream_channel: any
+  telemetry: any
+  test: any
   watcher: any
   yaml: any
 
 dev_dependencies:
-  analyzer_utilities:
-    path: ../analyzer_utilities
+  analyzer_utilities: any
   cli_util: any
-  lints: ^2.0.0
+  lints: any
   logging: any
   matcher: any
   test_reflective_loader: any
-
-dependency_overrides:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  analyzer:
-    path: ../analyzer
-  meta:
-    path: ../meta
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart
index 7d020ef..b7520c2 100644
--- a/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart
@@ -29,7 +29,62 @@
 analyzer:
   ^
 ''');
-    assertSuggestion('${AnalyzerOptions.enableExperiment}: ');
+    assertSuggestion('${AnalyzerOptions.enableExperiment}:');
+  }
+
+  void test_analyzer_enableExperiment() {
+    registerLintRules();
+    getCompletions('''
+analyzer:
+  enable-experiment:
+    ^
+''');
+    assertSuggestion('macros');
+    assertNoSuggestion('super-parameters');
+  }
+
+  void test_analyzer_enableExperiment_nonDuplicate() {
+    registerLintRules();
+    getCompletions('''
+analyzer:
+  enable-experiment:
+    - macros
+    ^
+''');
+    assertNoSuggestion('macros');
+  }
+
+  void test_analyzer_errors() {
+    getCompletions('''
+analyzer:
+  errors:
+    ^
+''');
+    assertSuggestion('dead_code: ');
+    assertSuggestion('invalid_assignment: ');
+    assertSuggestion('annotate_overrides: ');
+  }
+
+  void test_analyzer_errors_nonDuplicate() {
+    getCompletions('''
+analyzer:
+  errors:
+    dead_code: info
+    ^
+''');
+    assertNoSuggestion('dead_code');
+  }
+
+  void test_analyzer_errors_severity() {
+    getCompletions('''
+analyzer:
+  errors:
+    dead_code: ^
+''');
+    assertSuggestion('ignore');
+    assertSuggestion('info');
+    assertSuggestion('warning');
+    assertSuggestion('error');
   }
 
   void test_codeStyle() {
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 4396c0f..e120c27 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -4,6 +4,7 @@
 * Deprecated `ResourceProviderMixin.newAnalysisOptionsYamlFile2`, use `newAnalysisOptionsYamlFile` instead.
 * Deprecated `DartType.resolveToBound`, use `TypeSystem.resolveToBound` instead.
 * Deprecated `LibraryElement.getImportsWithPrefix`, use `PrefixElement.imports` instead.
+* Fix for `AnalysisSession.getFile()` to return stale content even after `applyPendingFileChanges`.
 
 ## 4.0.0
 * Removed deprecated `UriKind` and `Source.uriKind`.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 5e0d327..c3aaba2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -84,7 +84,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 218;
+  static const int DATA_VERSION = 219;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
@@ -1041,10 +1041,6 @@
 
   @override
   Future<void> performWork() async {
-    if (_fileTracker.verifyChangedFilesIfNeeded()) {
-      return;
-    }
-
     if (!_hasDartCoreDiscovered) {
       _hasDartCoreDiscovered = true;
       _discoverDartCore();
@@ -1370,6 +1366,9 @@
     }
     _pendingFileChanges.clear();
 
+    // Read files, so that synchronous methods also see new content.
+    while (_fileTracker.verifyChangedFilesIfNeeded()) {}
+
     if (_pendingFileChangesCompleters.isNotEmpty) {
       var completers = _pendingFileChangesCompleters.toList();
       _pendingFileChangesCompleters.clear();
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index c28b106..0ddc93b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -22,6 +22,7 @@
   EnableString.extension_types: ExperimentalFeatures.extension_types,
   EnableString.generic_metadata: ExperimentalFeatures.generic_metadata,
   EnableString.inference_update_1: ExperimentalFeatures.inference_update_1,
+  EnableString.inference_update_2: ExperimentalFeatures.inference_update_2,
   EnableString.macros: ExperimentalFeatures.macros,
   EnableString.named_arguments_anywhere:
       ExperimentalFeatures.named_arguments_anywhere,
@@ -67,6 +68,9 @@
   /// String to enable the experiment "inference-update-1"
   static const String inference_update_1 = 'inference-update-1';
 
+  /// String to enable the experiment "inference-update-2"
+  static const String inference_update_2 = 'inference-update-2';
+
   /// String to enable the experiment "macros"
   static const String macros = 'macros';
 
@@ -196,8 +200,18 @@
     releaseVersion: null,
   );
 
-  static final macros = ExperimentalFeature(
+  static final inference_update_2 = ExperimentalFeature(
     index: 9,
+    enableString: EnableString.inference_update_2,
+    isEnabledByDefault: IsEnabledByDefault.inference_update_2,
+    isExpired: IsExpired.inference_update_2,
+    documentation: 'Type promotion for fields',
+    experimentalReleaseVersion: null,
+    releaseVersion: null,
+  );
+
+  static final macros = ExperimentalFeature(
+    index: 10,
     enableString: EnableString.macros,
     isEnabledByDefault: IsEnabledByDefault.macros,
     isExpired: IsExpired.macros,
@@ -207,7 +221,7 @@
   );
 
   static final named_arguments_anywhere = ExperimentalFeature(
-    index: 10,
+    index: 11,
     enableString: EnableString.named_arguments_anywhere,
     isEnabledByDefault: IsEnabledByDefault.named_arguments_anywhere,
     isExpired: IsExpired.named_arguments_anywhere,
@@ -217,7 +231,7 @@
   );
 
   static final non_nullable = ExperimentalFeature(
-    index: 11,
+    index: 12,
     enableString: EnableString.non_nullable,
     isEnabledByDefault: IsEnabledByDefault.non_nullable,
     isExpired: IsExpired.non_nullable,
@@ -227,7 +241,7 @@
   );
 
   static final nonfunction_type_aliases = ExperimentalFeature(
-    index: 12,
+    index: 13,
     enableString: EnableString.nonfunction_type_aliases,
     isEnabledByDefault: IsEnabledByDefault.nonfunction_type_aliases,
     isExpired: IsExpired.nonfunction_type_aliases,
@@ -237,7 +251,7 @@
   );
 
   static final set_literals = ExperimentalFeature(
-    index: 13,
+    index: 14,
     enableString: EnableString.set_literals,
     isEnabledByDefault: IsEnabledByDefault.set_literals,
     isExpired: IsExpired.set_literals,
@@ -247,7 +261,7 @@
   );
 
   static final spread_collections = ExperimentalFeature(
-    index: 14,
+    index: 15,
     enableString: EnableString.spread_collections,
     isEnabledByDefault: IsEnabledByDefault.spread_collections,
     isExpired: IsExpired.spread_collections,
@@ -257,7 +271,7 @@
   );
 
   static final super_parameters = ExperimentalFeature(
-    index: 15,
+    index: 16,
     enableString: EnableString.super_parameters,
     isEnabledByDefault: IsEnabledByDefault.super_parameters,
     isExpired: IsExpired.super_parameters,
@@ -267,7 +281,7 @@
   );
 
   static final test_experiment = ExperimentalFeature(
-    index: 16,
+    index: 17,
     enableString: EnableString.test_experiment,
     isEnabledByDefault: IsEnabledByDefault.test_experiment,
     isExpired: IsExpired.test_experiment,
@@ -278,7 +292,7 @@
   );
 
   static final triple_shift = ExperimentalFeature(
-    index: 17,
+    index: 18,
     enableString: EnableString.triple_shift,
     isEnabledByDefault: IsEnabledByDefault.triple_shift,
     isExpired: IsExpired.triple_shift,
@@ -288,7 +302,7 @@
   );
 
   static final value_class = ExperimentalFeature(
-    index: 18,
+    index: 19,
     enableString: EnableString.value_class,
     isEnabledByDefault: IsEnabledByDefault.value_class,
     isExpired: IsExpired.value_class,
@@ -298,7 +312,7 @@
   );
 
   static final variance = ExperimentalFeature(
-    index: 19,
+    index: 20,
     enableString: EnableString.variance,
     isEnabledByDefault: IsEnabledByDefault.variance,
     isExpired: IsExpired.variance,
@@ -338,6 +352,9 @@
   /// Default state of the experiment "inference-update-1"
   static const bool inference_update_1 = false;
 
+  /// Default state of the experiment "inference-update-2"
+  static const bool inference_update_2 = false;
+
   /// Default state of the experiment "macros"
   static const bool macros = false;
 
@@ -403,6 +420,9 @@
   /// Expiration status of the experiment "inference-update-1"
   static const bool inference_update_1 = false;
 
+  /// Expiration status of the experiment "inference-update-2"
+  static const bool inference_update_2 = false;
+
   /// Expiration status of the experiment "macros"
   static const bool macros = false;
 
@@ -470,6 +490,10 @@
   bool get inference_update_1 =>
       isEnabled(ExperimentalFeatures.inference_update_1);
 
+  /// Current state for the flag "inference-update-2"
+  bool get inference_update_2 =>
+      isEnabled(ExperimentalFeatures.inference_update_2);
+
   /// Current state for the flag "macros"
   bool get macros => isEnabled(ExperimentalFeatures.macros);
 
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index fa0b08f..65e6668 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -33,7 +33,7 @@
   late final AnalysisDriverScheduler scheduler;
   late final AnalysisDriver driver;
   final List<AnalysisStatus> allStatuses = <AnalysisStatus>[];
-  final List<AnalysisResultWithErrors> allResults = [];
+  final DriverTestAnalysisResults allResults = DriverTestAnalysisResults();
   final List<ExceptionResult> allExceptions = <ExceptionResult>[];
 
   late final String testProject;
@@ -142,9 +142,7 @@
     scheduler.start();
     scheduler.status.listen(allStatuses.add);
     driver.results.listen((result) {
-      if (result is AnalysisResultWithErrors) {
-        allResults.add(result);
-      }
+      allResults.add(result);
     });
     driver.exceptions.listen(allExceptions.add);
   }
@@ -152,6 +150,42 @@
   void tearDown() {}
 }
 
+class DriverTestAnalysisResults {
+  final List<Object> _results = [];
+
+  Object get first => _results.first;
+
+  bool get isEmpty => _results.isEmpty;
+
+  int get length => _results.length;
+
+  List<String> get pathList => _withErrors.map((e) => e.path).toList();
+
+  Set<String> get pathSet => _withErrors.map((e) => e.path).toSet();
+
+  Object get single => _results.single;
+
+  Iterable<AnalysisResultWithErrors> get _withErrors {
+    return _results.whereType<AnalysisResultWithErrors>();
+  }
+
+  void add(Object result) {
+    _results.add(result);
+  }
+
+  void clear() {
+    _results.clear();
+  }
+
+  List<Object> toList() => _results.toList();
+
+  Iterable<T> whereType<T>() => _results.whereType<T>();
+
+  AnalysisResultWithErrors withPath(String path) {
+    return _withErrors.singleWhere((result) => result.path == path);
+  }
+}
+
 class _GeneratedUriResolverMock extends UriResolver {
   Source? Function(Uri)? resolveAbsoluteFunction;
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 2493532..60fd9f7 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -436,7 +436,7 @@
     driver.addFile(b);
 
     void assertNumberOfErrorsInB(int n) {
-      var bResult = allResults.singleWhere((r) => r.path == b);
+      var bResult = allResults.withPath(b);
       expect(bResult.errors, hasLength(n));
       allResults.clear();
     }
@@ -482,8 +482,7 @@
     await waitForIdleWithoutExceptions();
 
     // Only 'b' has been analyzed, because 'a' was removed before we started.
-    expect(allResults, hasLength(1));
-    expect(allResults[0].path, b);
+    expect(allResults.pathList, [b]);
   }
 
   test_analyze_resolveDirectives() async {
@@ -993,8 +992,7 @@
     // Initial analysis.
     {
       await waitForIdleWithoutExceptions();
-      expect(allResults, hasLength(1));
-      var result = allResults[0] as ResolvedUnitResult;
+      final result = allResults.whereType<ResolvedUnitResult>().single;
       expect(result.path, testFile);
       _assertTopLevelVarType(result.unit, 'V', 'int');
     }
@@ -1014,8 +1012,7 @@
     // We get a new result.
     {
       await waitForIdleWithoutExceptions();
-      expect(allResults, hasLength(1));
-      var result = allResults[0] as ResolvedUnitResult;
+      final result = allResults.whereType<ResolvedUnitResult>().single;
       expect(result.path, testFile);
       _assertTopLevelVarType(result.unit, 'V', 'double');
     }
@@ -1729,7 +1726,7 @@
 
     // The same result is also received through the stream.
     await waitForIdleWithoutExceptions();
-    expect(allResults, [result]);
+    expect(allResults.toList(), [result]);
   }
 
   test_getResult_constants_defaultParameterValue_localFunction() async {
@@ -3004,7 +3001,7 @@
     driver.addFile(a);
 
     await waitForIdleWithoutExceptions();
-    expect(allResults.map((e) => e.path).toSet(), {a});
+    expect(allResults.pathSet, {a});
     allResults.clear();
 
     driver.removeFile(a);
@@ -3012,7 +3009,7 @@
 
     // a.dart should be produced again
     await waitForIdleWithoutExceptions();
-    expect(allResults.map((e) => e.path).toSet(), {a});
+    expect(allResults.pathSet, {a});
   }
 
   test_removeFile_changeFile_implicitlyAnalyzed() async {
@@ -3068,8 +3065,7 @@
 
     // We have a result.
     await waitForIdleWithoutExceptions();
-    expect(allResults, hasLength(1));
-    expect(allResults[0].path, testFile);
+    expect(allResults.pathSet, {testFile});
     allResults.clear();
 
     // Remove the file and send the change notification.
@@ -3094,14 +3090,14 @@
     await waitForIdleWithoutExceptions();
 
     // b.dart s clean.
-    expect(allResults.singleWhere((r) => r.path == b).errors, isEmpty);
+    expect(allResults.withPath(b).errors, isEmpty);
     allResults.clear();
 
     // Remove a.dart, now b.dart should be reanalyzed and has an error.
     deleteFile(a);
     driver.removeFile(a);
     await waitForIdleWithoutExceptions();
-    expect(allResults.singleWhere((r) => r.path == b).errors, hasLength(2));
+    expect(allResults.withPath(b).errors, hasLength(2));
     allResults.clear();
   }
 
@@ -3155,7 +3151,7 @@
     driver.changeFile(b);
     await waitForIdleWithoutExceptions();
 
-    List<String> analyzedPaths = allResults.map((r) => r.path).toList();
+    List<String> analyzedPaths = allResults.pathList;
 
     // The changed file must be the first.
     expect(analyzedPaths[0], b);
@@ -3197,7 +3193,7 @@
     driver.changeFile(a);
     await waitForIdleWithoutExceptions();
 
-    List<String> analyzedPaths = allResults.map((r) => r.path).toList();
+    List<String> analyzedPaths = allResults.pathList;
 
     // The changed files must be the first.
     expect(analyzedPaths[0], a);
@@ -3242,7 +3238,7 @@
     await waitForIdleWithoutExceptions();
 
     expect(allResults, hasLength(3));
-    var result = allResults[0] as ResolvedUnitResult;
+    var result = allResults.first as ResolvedUnitResult;
     expect(result.path, b);
     expect(result.unit, isNotNull);
     expect(result.errors, hasLength(0));
@@ -3270,7 +3266,7 @@
     driver.addFile(a);
 
     await waitForIdleWithoutExceptions();
-    expect(allResults.singleWhere((r) => r.path == a).errors, hasLength(0));
+    expect(allResults.withPath(a).errors, hasLength(0));
     allResults.clear();
 
     newFile(a, r'''
@@ -3279,7 +3275,7 @@
     driver.removeFile(b);
     driver.changeFile(a);
     await waitForIdleWithoutExceptions();
-    expect(allResults.singleWhere((r) => r.path == a).errors, hasLength(1));
+    expect(allResults.withPath(a).errors, hasLength(1));
   }
 
   test_results_skipNotAffected() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index fd95452..ee74d7f 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -124,6 +124,64 @@
 
 @reflectiveTest
 class AnalysisSessionImplTest extends PubPackageResolutionTest {
+  test_applyPendingFileChanges_getFile() async {
+    final a = newFile('$testPackageLibPath/a.dart', '');
+    final analysisContext = contextFor(a.path);
+
+    int lineCount_in_a() {
+      final result = analysisContext.currentSession.getFileValid(a.path);
+      return result.lineInfo.lineCount;
+    }
+
+    expect(lineCount_in_a(), 1);
+
+    newFile(a.path, '\n');
+    analysisContext.changeFile(a.path);
+    await analysisContext.applyPendingFileChanges();
+
+    // The file must be re-read after `applyPendingFileChanges()`.
+    expect(lineCount_in_a(), 2);
+  }
+
+  test_applyPendingFileChanges_getParsedLibrary() async {
+    final a = newFile('$testPackageLibPath/a.dart', '');
+    final analysisContext = contextFor(a.path);
+
+    int lineCount_in_a() {
+      final analysisSession = analysisContext.currentSession;
+      final result = analysisSession.getParsedLibraryValid(a.path);
+      return result.units.first.lineInfo.lineCount;
+    }
+
+    expect(lineCount_in_a(), 1);
+
+    newFile(a.path, '\n');
+    analysisContext.changeFile(a.path);
+    await analysisContext.applyPendingFileChanges();
+
+    // The file must be re-read after `applyPendingFileChanges()`.
+    expect(lineCount_in_a(), 2);
+  }
+
+  test_applyPendingFileChanges_getParsedUnit() async {
+    final a = newFile('$testPackageLibPath/a.dart', '');
+    final analysisContext = contextFor(a.path);
+
+    int lineCount_in_a() {
+      final result = analysisContext.currentSession.getParsedUnitValid(a.path);
+      return result.lineInfo.lineCount;
+    }
+
+    expect(lineCount_in_a(), 1);
+
+    newFile(a.path, '\n');
+    analysisContext.changeFile(a.path);
+    await analysisContext.applyPendingFileChanges();
+
+    // The file must be re-read after `applyPendingFileChanges()`.
+    expect(lineCount_in_a(), 2);
+  }
+
   test_getErrors() async {
     var test = newFile(testFilePath, 'class C {');
 
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 0580b81..6007114 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -10,19 +10,13 @@
 dependencies:
   analyzer: any
   args: any
-  linter: ^1.0.0
+  linter: any
   meta: any
   path: any
-  pub_semver: ^2.0.0
+  pub_semver: any
   yaml: any
 
 dev_dependencies:
   lints: any
-  test_reflective_loader: ^0.2.0
-  test: ^1.0.0
-
-dependency_overrides:
-  analyzer:
-    path: ../analyzer
-  meta:
-    path: ../meta
+  test_reflective_loader: any
+  test: any
diff --git a/pkg/analyzer_utilities/pubspec.yaml b/pkg/analyzer_utilities/pubspec.yaml
index 2eac4b1..e974be1 100644
--- a/pkg/analyzer_utilities/pubspec.yaml
+++ b/pkg/analyzer_utilities/pubspec.yaml
@@ -6,11 +6,9 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
-  analyzer:
-    path: ../analyzer
+  analyzer: any
   html: any
-  meta:
-    path: ../meta
+  meta: any
   path: any
   test: any
 
diff --git a/pkg/async_helper/pubspec.yaml b/pkg/async_helper/pubspec.yaml
index f79d98f..55bc80d 100644
--- a/pkg/async_helper/pubspec.yaml
+++ b/pkg/async_helper/pubspec.yaml
@@ -13,5 +13,4 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
-  expect:
-    path: ../expect
+  expect: any
diff --git a/pkg/build_integration/pubspec.yaml b/pkg/build_integration/pubspec.yaml
index 899a5ed..2286f3e 100644
--- a/pkg/build_integration/pubspec.yaml
+++ b/pkg/build_integration/pubspec.yaml
@@ -9,8 +9,7 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
-  front_end:
-    path: ../front_end
+  front_end: any
 
 dev_dependencies:
   test: any
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index d2e8bbb..22f0ac4 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -10,110 +10,25 @@
 # package. The `.packages` file in the repository root will be used by default.
 dependencies:
   _fe_analyzer_shared: any
-  # Published packages - repo version ensured via dependency_overrides
+  _js_interop_checks: any
   collection: any
   crypto: any
-  dart2js_info:
-    path: ../dart2js_info
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
-
-  # Unpublished packages that can be used via path dependency
-  _js_interop_checks:
-    path: ../_js_interop_checks
-  js_ast:
-    path: ../js_ast
-  js_runtime:
-    path: ../js_runtime
+  dart2js_info: any
+  front_end: any
+  js_ast: any
+  js_runtime: any
+  kernel: any
 
 dev_dependencies:
-  # Published packages - repo version ensured via dependency_overrides
   args: any
   dart_style: any
   http: any
-  js:
-    path: ../js
+  js: any
   path: any
   source_maps: any
-  # Unpublished packages that can be used via path dependency
-  async_helper:
-    path: ../async_helper
-  dart2js_tools:
-    path: ../dart2js_tools
-  expect:
-    path: ../expect
-  modular_test:
-    path: ../modular_test
-  sourcemap_testing:
-    path: ../sourcemap_testing
-  testing:
-    path: ../testing
-
-dependency_overrides:
-  # Packages with source in the SDK
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  analyzer:
-    path: ../analyzer
-  front_end:
-    path: ../front_end
-  js:
-    path: ../js
-  kernel:
-    path: ../kernel
-  meta:
-    path: ../meta
-  dart2js_info:
-    path: ../dart2js_info
-  smith:
-    path: ../smith
-
-  # Packages brought in via DEPS
-  args:
-    path: ../../third_party/pkg/args
-  async:
-    path: ../../third_party/pkg/async
-  charcode:
-    path: ../../third_party/pkg/charcode
-  collection:
-    path: ../../third_party/pkg/collection
-  convert:
-    path: ../../third_party/pkg/convert
-  crypto:
-    path: ../../third_party/pkg/crypto
-  fixnum:
-    path: ../../third_party/pkg/fixnum
-  http_parser:
-    path: ../../third_party/pkg/http_parser
-  matcher:
-    path: ../../third_party/pkg/matcher
-  mime:
-    path: ../../third_party/pkg/mime
-  package_config:
-    path: ../../third_party/pkg_tested/package_config
-  path:
-    path: ../../third_party/pkg/path
-  protobuf:
-    path: ../../third_party/pkg/protobuf/protobuf
-  shelf:
-    path: ../../third_party/pkg/shelf/pkgs/shelf
-  shelf_static:
-    path: ../../third_party/pkg/shelf/pkgs/shelf_static
-  source_span:
-    path: ../../third_party/pkg/source_span
-  stack_trace:
-    path: ../../third_party/pkg/stack_trace
-  stream_channel:
-    path: ../../third_party/pkg/stream_channel
-  string_scanner:
-    path: ../../third_party/pkg/string_scanner
-  test:
-    path: ../../third_party/pkg/test/pkgs/test
-  test_api:
-    path: ../../third_party/pkg/test/pkgs/test_api
-  typed_data:
-    path: ../../third_party/pkg/typed_data
-  yaml:
-    path: ../../third_party/pkg/yaml
+  async_helper: any
+  dart2js_tools: any
+  expect: any
+  modular_test: any
+  sourcemap_testing: any
+  testing: any
diff --git a/pkg/dart2js_info/pubspec.yaml b/pkg/dart2js_info/pubspec.yaml
index fd83226..2d8ff24 100644
--- a/pkg/dart2js_info/pubspec.yaml
+++ b/pkg/dart2js_info/pubspec.yaml
@@ -9,17 +9,17 @@
   sdk: '>=2.11.99 <3.0.0'
 
 dependencies:
-  args: ^2.3.0
-  collection: ^1.10.1
-  fixnum: '>=0.10.5 <2.0.0'
-  path: ^1.3.6
-  protobuf: '>=1.0.1 <3.0.0'
-  shelf: ^1.2.0
-  yaml: ^3.1.0
+  args: any
+  collection: any
+  fixnum: any
+  path: any
+  protobuf: any
+  shelf: any
+  yaml: any
 
 dev_dependencies:
   lints: any
-  test: ^1.2.0
+  test: any
 
 executables:
   dart2js_info: tools
diff --git a/pkg/dart2js_runtime_metrics/pubspec.yaml b/pkg/dart2js_runtime_metrics/pubspec.yaml
index 31c227f5..8db9891 100644
--- a/pkg/dart2js_runtime_metrics/pubspec.yaml
+++ b/pkg/dart2js_runtime_metrics/pubspec.yaml
@@ -12,6 +12,4 @@
   sdk: ">=2.14.0 <2.15.0"
 
 dev_dependencies:
-  # Unpublished packages that can be used via path dependency
-  expect:
-    path: ../expect
+  expect: any
diff --git a/pkg/dart2js_tools/pubspec.yaml b/pkg/dart2js_tools/pubspec.yaml
index 392ed56..ec4d63b 100644
--- a/pkg/dart2js_tools/pubspec.yaml
+++ b/pkg/dart2js_tools/pubspec.yaml
@@ -4,10 +4,12 @@
 description: >
   Collection of tools used with dart2js including analyzing compilation
   information, deobfuscation of stack-traces and minified names.
-dependencies:
-  path: any
-  source_maps: ^0.10.10
-  source_span: any
-  stack_trace: ^1.9.3
+
 environment:
   sdk: '>=2.12.0 <3.0.0'
+
+dependencies:
+  path: any
+  source_maps: any
+  source_span: any
+  stack_trace: any
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart
index a837c13..b9fc9e9 100644
--- a/pkg/dart2wasm/lib/class_info.dart
+++ b/pkg/dart2wasm/lib/class_info.dart
@@ -27,6 +27,7 @@
   static const closureFunction = 3;
   static const typeIsNullable = 2;
   static const interfaceTypeTypeArguments = 4;
+  static const functionTypeNamedParameters = 6;
   static const typedListBaseLength = 2;
   static const typedListArray = 3;
   static const typedListViewTypedData = 3;
@@ -55,6 +56,8 @@
     check(translator.typeClass, "isNullable", FieldIndex.typeIsNullable);
     check(translator.interfaceTypeClass, "typeArguments",
         FieldIndex.interfaceTypeTypeArguments);
+    check(translator.functionTypeClass, "namedParameters",
+        FieldIndex.functionTypeNamedParameters);
   }
 }
 
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
index 3a3c52e..fbf5eeb 100644
--- a/pkg/dart2wasm/lib/constants.dart
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -247,6 +247,33 @@
     b.end();
   }
 
+  /// Makes a type list [ListConstant].
+  ListConstant makeTypeList(List<DartType> types) => ListConstant(
+      InterfaceType(translator.typeClass, Nullability.nonNullable),
+      types.map((t) => TypeLiteralConstant(t)).toList());
+
+  /// Makes a `_NamedParameter` [InstanceConstant].
+  InstanceConstant makeNamedParameterConstant(NamedType n) {
+    Class namedParameter = translator.namedParameterClass;
+    assert(namedParameter.fields[0].name.text == 'name' &&
+        namedParameter.fields[1].name.text == 'type' &&
+        namedParameter.fields[2].name.text == 'isRequired');
+    Reference namedParameterName = namedParameter.fields[0].fieldReference;
+    Reference namedParameterType = namedParameter.fields[1].fieldReference;
+    Reference namedParameterIsRequired =
+        namedParameter.fields[2].fieldReference;
+    return InstanceConstant(namedParameter.reference, [], {
+      namedParameterName: StringConstant(n.name),
+      namedParameterType: TypeLiteralConstant(n.type),
+      namedParameterIsRequired: BoolConstant(n.isRequired)
+    });
+  }
+
+  /// Makes a [ListConstant] of `_NamedParameters` to initialize a [FunctionType].
+  ListConstant makeNamedParametersList(FunctionType type) => ListConstant(
+      translator.types.namedParameterType,
+      type.namedParameters.map(makeNamedParameterConstant).toList());
+
   /// Ensure that the constant has a Wasm global assigned.
   ///
   /// In eager mode, sub-constants must have Wasm globals assigned before the
@@ -682,6 +709,69 @@
     });
   }
 
+  ConstantInfo? _makeInterfaceType(
+      TypeLiteralConstant constant, InterfaceType type, ClassInfo info) {
+    ListConstant typeArgs = constants.makeTypeList(type.typeArguments);
+    ensureConstant(typeArgs);
+    return createConstant(constant, info.nonNullableType, (function, b) {
+      ClassInfo typeInfo = translator.classInfo[type.classNode]!;
+      w.ValueType typeListExpectedType = info
+          .struct.fields[FieldIndex.interfaceTypeTypeArguments].type.unpacked;
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      types.encodeNullability(b, type);
+      b.i64_const(typeInfo.classId);
+      constants.instantiateConstant(
+          function, b, typeArgs, typeListExpectedType);
+      translator.struct_new(b, info);
+    });
+  }
+
+  ConstantInfo? _makeFutureOrType(
+      TypeLiteralConstant constant, FutureOrType type, ClassInfo info) {
+    TypeLiteralConstant typeArgument = TypeLiteralConstant(type.typeArgument);
+    ensureConstant(typeArgument);
+    return createConstant(constant, info.nonNullableType, (function, b) {
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      types.encodeNullability(b, type);
+      constants.instantiateConstant(
+          function, b, typeArgument, types.nonNullableTypeType);
+      translator.struct_new(b, info);
+    });
+  }
+
+  ConstantInfo? _makeFunctionType(
+      TypeLiteralConstant constant, FunctionType type, ClassInfo info) {
+    TypeLiteralConstant returnTypeConstant =
+        TypeLiteralConstant(type.returnType);
+    ListConstant positionalParametersConstant =
+        constants.makeTypeList(type.positionalParameters);
+    IntConstant requiredParameterCountConstant =
+        IntConstant(type.requiredParameterCount);
+    ListConstant namedParametersConstant =
+        constants.makeNamedParametersList(type);
+    ensureConstant(returnTypeConstant);
+    ensureConstant(positionalParametersConstant);
+    ensureConstant(requiredParameterCountConstant);
+    ensureConstant(namedParametersConstant);
+    return createConstant(constant, info.nonNullableType, (function, b) {
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      types.encodeNullability(b, type);
+      constants.instantiateConstant(
+          function, b, returnTypeConstant, types.nonNullableTypeType);
+      constants.instantiateConstant(function, b, positionalParametersConstant,
+          types.typeListExpectedType);
+      constants.instantiateConstant(
+          function, b, requiredParameterCountConstant, w.NumType.i64);
+      constants.instantiateConstant(function, b, namedParametersConstant,
+          types.namedParametersExpectedType);
+      translator.struct_new(b, info);
+    });
+  }
+
   @override
   ConstantInfo? visitTypeLiteralConstant(TypeLiteralConstant constant) {
     DartType type = constant.type;
@@ -690,42 +780,22 @@
     ClassInfo info = translator.classInfo[types.classForType(type)]!;
     translator.functions.allocateClass(info.classId);
     if (type is InterfaceType) {
-      ListConstant typeArgs = ListConstant(
-          InterfaceType(translator.typeClass, Nullability.nonNullable),
-          type.typeArguments.map((t) => TypeLiteralConstant(t)).toList());
-      ensureConstant(typeArgs);
-      return createConstant(constant, info.nonNullableType, (function, b) {
-        ClassInfo typeInfo = translator.classInfo[type.classNode]!;
-        w.ValueType typeListExpectedType = info
-            .struct.fields[FieldIndex.interfaceTypeTypeArguments].type.unpacked;
-
-        b.i32_const(info.classId);
-        b.i32_const(initialIdentityHash);
-        types.encodeNullability(b, type);
-        b.i64_const(typeInfo.classId);
-        constants.instantiateConstant(
-            function, b, typeArgs, typeListExpectedType);
-        translator.struct_new(b, info);
-      });
+      return _makeInterfaceType(constant, type, info);
     } else if (type is FutureOrType) {
-      TypeLiteralConstant typeArgument = TypeLiteralConstant(type.typeArgument);
-      ensureConstant(typeArgument);
-      return createConstant(constant, info.nonNullableType, (function, b) {
-        b.i32_const(info.classId);
-        b.i32_const(initialIdentityHash);
-        types.encodeNullability(b, type);
-        constants.instantiateConstant(
-            function, b, typeArgument, types.nonNullableTypeType);
-        translator.struct_new(b, info);
-      });
+      return _makeFutureOrType(constant, type, info);
     } else if (type is FunctionType) {
-      // TODO(joshualitt): Real implementation for function types.
-      return createConstant(constant, info.nonNullableType, (function, b) {
-        b.i32_const(info.classId);
-        b.i32_const(initialIdentityHash);
-        types.encodeNullability(b, type);
-        translator.struct_new(b, info);
-      });
+      if (types.isGenericFunction(type)) {
+        // TODO(joshualitt): implement generic function types and share most of
+        // the logic with _makeFunctionType.
+        return createConstant(constant, info.nonNullableType, (function, b) {
+          b.i32_const(info.classId);
+          b.i32_const(initialIdentityHash);
+          types.encodeNullability(b, type);
+          translator.struct_new(b, info);
+        });
+      } else {
+        return _makeFunctionType(constant, type, info);
+      }
     } else {
       assert(type is VoidType ||
           type is NeverType ||
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index e019025..47a9670 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -97,6 +97,7 @@
   late final Class interfaceTypeClass;
   late final Class functionTypeClass;
   late final Class genericFunctionTypeClass;
+  late final Class namedParameterClass;
   late final Class stackTraceClass;
   late final Class ffiCompoundClass;
   late final Class ffiPointerClass;
@@ -212,6 +213,7 @@
     interfaceTypeClass = lookupCore("_InterfaceType");
     functionTypeClass = lookupCore("_FunctionType");
     genericFunctionTypeClass = lookupCore("_GenericFunctionType");
+    namedParameterClass = lookupCore("_NamedParameter");
     stackTraceClass = lookupCore("StackTrace");
     typeUniverseClass = lookupCore("_TypeUniverse");
     ffiCompoundClass = lookupFfi("_Compound");
diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart
index 18d38eb..b94a144 100644
--- a/pkg/dart2wasm/lib/types.dart
+++ b/pkg/dart2wasm/lib/types.dart
@@ -14,9 +14,16 @@
 class Types {
   final Translator translator;
   late final typeClassInfo = translator.classInfo[translator.typeClass]!;
+  late final w.ValueType typeListExpectedType = classAndFieldToType(
+      translator.interfaceTypeClass, FieldIndex.interfaceTypeTypeArguments);
+  late final w.ValueType namedParametersExpectedType = classAndFieldToType(
+      translator.functionTypeClass, FieldIndex.functionTypeNamedParameters);
 
   Types(this.translator);
 
+  w.ValueType classAndFieldToType(Class cls, int fieldIndex) =>
+      translator.classInfo[cls]!.struct.fields[fieldIndex].type.unpacked;
+
   Iterable<Class> _getConcreteSubtypes(Class cls) =>
       translator.subtypes.getSubtypesOf(cls).where((c) => !c.isAbstract);
 
@@ -24,6 +31,9 @@
 
   w.ValueType get nonNullableTypeType => typeClassInfo.nonNullableType;
 
+  InterfaceType get namedParameterType =>
+      InterfaceType(translator.namedParameterClass, Nullability.nonNullable);
+
   /// Build a [Map<int, List<int>>] to store subtype information.
   Map<int, List<int>> _buildSubtypeMap() {
     List<ClassInfo> classes = translator.classes;
@@ -62,13 +72,19 @@
     return expectedType;
   }
 
+  bool isGenericFunction(FunctionType type) => type.typeParameters.isNotEmpty;
+
   bool _isTypeConstant(DartType type) {
     return type is DynamicType ||
         type is VoidType ||
         type is NeverType ||
         type is NullType ||
-        type is FunctionType ||
         type is FutureOrType && _isTypeConstant(type.typeArgument) ||
+        (type is FunctionType &&
+            type.typeParameters.isEmpty && // TODO(joshualitt) generic functions
+            _isTypeConstant(type.returnType) &&
+            type.positionalParameters.every(_isTypeConstant) &&
+            type.namedParameters.every((n) => _isTypeConstant(n.type))) ||
         type is InterfaceType && type.typeArguments.every(_isTypeConstant);
   }
 
@@ -92,30 +108,32 @@
     } else if (type is InterfaceType) {
       return translator.interfaceTypeClass;
     } else if (type is FunctionType) {
-      if (type.typeParameters.isEmpty) {
-        return translator.functionTypeClass;
-      } else {
+      if (isGenericFunction(type)) {
         return translator.genericFunctionTypeClass;
+      } else {
+        return translator.functionTypeClass;
       }
     }
     throw "Unexpected DartType: $type";
   }
 
+  void _makeTypeList(
+      CodeGenerator codeGen, List<DartType> types, TreeNode node) {
+    w.ValueType listType = codeGen.makeList(
+        types.map((t) => TypeLiteral(t)).toList(),
+        translator.fixedLengthListClass,
+        InterfaceType(translator.typeClass, Nullability.nonNullable),
+        node);
+    translator.convertType(codeGen.function, listType, typeListExpectedType);
+  }
+
   void _makeInterfaceType(CodeGenerator codeGen, ClassInfo info,
       InterfaceType type, TreeNode node) {
     w.Instructions b = codeGen.b;
     ClassInfo typeInfo = translator.classInfo[type.classNode]!;
-    w.ValueType typeListExpectedType =
-        info.struct.fields[FieldIndex.interfaceTypeTypeArguments].type.unpacked;
     encodeNullability(b, type);
     b.i64_const(typeInfo.classId);
-    w.DefinedFunction function = codeGen.function;
-    w.ValueType listType = codeGen.makeList(
-        type.typeArguments.map((t) => TypeLiteral(t)).toList(),
-        translator.fixedLengthListClass,
-        InterfaceType(translator.typeClass, Nullability.nonNullable),
-        node);
-    translator.convertType(function, listType, typeListExpectedType);
+    _makeTypeList(codeGen, type.typeArguments, node);
   }
 
   void _makeFutureOrType(
@@ -140,6 +158,52 @@
     }
   }
 
+  void _makeFunctionType(
+      CodeGenerator codeGen, ClassInfo info, FunctionType type, TreeNode node) {
+    w.Instructions b = codeGen.b;
+    encodeNullability(b, type);
+    makeType(codeGen, type.returnType, node);
+    if (type.positionalParameters.every(_isTypeConstant)) {
+      translator.constants.instantiateConstant(
+          codeGen.function,
+          b,
+          translator.constants.makeTypeList(type.positionalParameters),
+          typeListExpectedType);
+    } else {
+      _makeTypeList(codeGen, type.positionalParameters, node);
+    }
+    b.i64_const(type.requiredParameterCount);
+    if (type.namedParameters.every((n) => _isTypeConstant(n.type))) {
+      translator.constants.instantiateConstant(
+          codeGen.function,
+          b,
+          translator.constants.makeNamedParametersList(type),
+          namedParametersExpectedType);
+    } else {
+      Class namedParameterClass = translator.namedParameterClass;
+      Constructor namedParameterConstructor =
+          namedParameterClass.constructors.single;
+      List<Expression> expressions = [];
+      for (NamedType n in type.namedParameters) {
+        expressions.add(_isTypeConstant(n.type)
+            ? ConstantExpression(
+                translator.constants.makeNamedParameterConstant(n),
+                namedParameterType)
+            : ConstructorInvocation(
+                namedParameterConstructor,
+                Arguments([
+                  StringLiteral(n.name),
+                  TypeLiteral(n.type),
+                  BoolLiteral(n.isRequired)
+                ])));
+      }
+      w.ValueType namedParametersListType = codeGen.makeList(expressions,
+          translator.fixedLengthListClass, namedParameterType, node);
+      translator.convertType(codeGen.function, namedParametersListType,
+          namedParametersExpectedType);
+    }
+  }
+
   /// Makes a `_Type` object on the stack.
   /// TODO(joshualitt): Refactor this logic to remove the dependency on
   /// CodeGenerator.
@@ -190,9 +254,14 @@
     } else if (type is FutureOrType) {
       _makeFutureOrType(codeGen, type, node);
     } else if (type is FunctionType) {
-      // TODO(joshualitt): Finish RTI.
-      print("Not implemented: RTI ${type}");
-      encodeNullability(b, type);
+      if (isGenericFunction(type)) {
+        // TODO(joshualitt): Implement generic function types and share most of
+        // the logic with _makeFunctionType.
+        print("Not implemented: RTI ${type}");
+        encodeNullability(b, type);
+      } else {
+        _makeFunctionType(codeGen, info, type, node);
+      }
     } else {
       throw '`$type` should have already been handled.';
     }
diff --git a/pkg/dart2wasm/pubspec.yaml b/pkg/dart2wasm/pubspec.yaml
index 8d6f9c2..2c0f711 100644
--- a/pkg/dart2wasm/pubspec.yaml
+++ b/pkg/dart2wasm/pubspec.yaml
@@ -5,26 +5,8 @@
   sdk: '>=2.12.0'
 
 dependencies:
-  _js_interop_checks:
-    path: ../_js_interop_checks
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
-  vm:
-    path: ../vm
-  wasm_builder:
-    path: ../wasm_builder
-
-dependency_overrides:
-  # Packages with source in the SDK
-  _js_interop_checks:
-    path: ../_js_interop_checks
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
-  vm:
-    path: ../vm
-  wasm_builder:
-    path: ../wasm_builder
+  _js_interop_checks: any
+  front_end: any
+  kernel: any
+  vm: any
+  wasm_builder: any
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index 5dc3ae7..3756ce2 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -120,7 +120,7 @@
     if (args.wasParsed('sdk-path')) {
       sdkPath = io.Directory(args['sdk-path'] as String);
       if (!sdkPath.existsSync()) {
-        usageException('Invalid Dart SDK path: $sdkPath');
+        usageException('Invalid Dart SDK path: ${sdkPath.path}');
       }
       final snapshotPath = path.join(
         sdkPath.path,
@@ -131,7 +131,7 @@
       if (!io.File(snapshotPath).existsSync()) {
         usageException(
             'Invalid Dart SDK path has no analysis_server.dart.snapshot file: '
-            '$sdkPath');
+            '${sdkPath.path}');
       }
     } else {
       sdkPath = io.Directory(sdk.sdkPath);
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index 51e57b2..2e71998 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -5,37 +5,28 @@
 
 environment:
   sdk: '>=2.12.0 <3.0.0'
+
 dependencies:
-  analysis_server:
-    path: ../analysis_server
-  analysis_server_client:
-    path: ../analysis_server_client
-  analyzer:
-    path: ../analyzer
+  analysis_server: any
+  analysis_server_client: any
+  analyzer: any
   args: any
   cli_util: any
   collection: any
-  dart2native:
-    path: ../dart2native
+  dart2native: any
   dart_style: any
   dartdoc: any
-  dds:
-    path: ../dds
-  front_end:
-    path: ../front_end
-  meta:
-    path: ../meta
-  nnbd_migration:
-    path: ../nnbd_migration
+  dds: any
+  front_end: any
+  meta: any
+  nnbd_migration: any
   path: any
   pub: any
-  telemetry:
-    path: ../telemetry
+  telemetry: any
   usage: any
 
 dev_dependencies:
-  expect:
-    path: ../expect
+  expect: any
   lints: any
   pub_semver: any
   test: any
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 9ff430c..5ec84aa 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -7,51 +7,30 @@
 
 dependencies:
   _fe_analyzer_shared: any
-  _js_interop_checks:
-    path: ../_js_interop_checks
+  _js_interop_checks: any
   args: any
   async: any
   bazel_worker: any
-  build_integration:
-    path: ../build_integration
-  collection: ^1.15.0
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
+  build_integration: any
+  collection: any
+  front_end: any
+  kernel: any
   meta: any
   path: any
   source_maps: any
   source_span: any
 
 dev_dependencies:
-  browser_launcher: ^1.0.0
-  expect:
-    path: ../expect
+  browser_launcher: any
+  expect: any
   http_multi_server: any
   js: any
   lints: any
-  modular_test:
-    path: ../modular_test
-  sourcemap_testing:
-    path: ../sourcemap_testing
-  stack_trace: any
+  modular_test: any
   shelf: any
+  sourcemap_testing: any
+  stack_trace: any
   test: any
-  testing:
-    path: ../testing
-  vm:
-    path: ../vm
-  webkit_inspection_protocol: ^1.0.0
-
-dependency_overrides:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  js:
-    path: ../js
-  meta:
-    path: ../meta
-  shelf:
-    path: ../../third_party/pkg/shelf/pkgs/shelf
-  http_multi_server:
-    path: ../../third_party/pkg/http_multi_server
+  testing: any
+  vm: any
+  webkit_inspection_protocol: any
diff --git a/pkg/expect/pubspec.yaml b/pkg/expect/pubspec.yaml
index 54c4ad1..e231d0c 100644
--- a/pkg/expect/pubspec.yaml
+++ b/pkg/expect/pubspec.yaml
@@ -14,9 +14,3 @@
 dependencies:
   meta: any
   smith: any
-
-dependency_overrides:
- meta:
-  path: ../meta
- smith:
-  path: ../smith
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 23aef55..3bfd9d3 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -131,6 +131,14 @@
       experimentEnabledVersion: const Version(2, 18),
       experimentReleasedVersion: const Version(2, 18));
 
+  static const ExperimentalFlag inferenceUpdate2 = const ExperimentalFlag(
+      name: 'inference-update-2',
+      isEnabledByDefault: false,
+      isExpired: false,
+      enabledVersion: const Version(2, 18),
+      experimentEnabledVersion: const Version(2, 18),
+      experimentReleasedVersion: const Version(2, 18));
+
   static const ExperimentalFlag macros = const ExperimentalFlag(
       name: 'macros',
       isEnabledByDefault: false,
@@ -306,6 +314,10 @@
   GlobalFeature get inferenceUpdate1 => _inferenceUpdate1 ??=
       _computeGlobalFeature(ExperimentalFlag.inferenceUpdate1);
 
+  GlobalFeature? _inferenceUpdate2;
+  GlobalFeature get inferenceUpdate2 => _inferenceUpdate2 ??=
+      _computeGlobalFeature(ExperimentalFlag.inferenceUpdate2);
+
   GlobalFeature? _macros;
   GlobalFeature get macros =>
       _macros ??= _computeGlobalFeature(ExperimentalFlag.macros);
@@ -415,6 +427,11 @@
       _inferenceUpdate1 ??= globalFeatures._computeLibraryFeature(
           ExperimentalFlag.inferenceUpdate1, canonicalUri, libraryVersion);
 
+  LibraryFeature? _inferenceUpdate2;
+  LibraryFeature get inferenceUpdate2 =>
+      _inferenceUpdate2 ??= globalFeatures._computeLibraryFeature(
+          ExperimentalFlag.inferenceUpdate2, canonicalUri, libraryVersion);
+
   LibraryFeature? _macros;
   LibraryFeature get macros =>
       _macros ??= globalFeatures._computeLibraryFeature(
@@ -497,6 +514,8 @@
       return ExperimentalFlag.genericMetadata;
     case "inference-update-1":
       return ExperimentalFlag.inferenceUpdate1;
+    case "inference-update-2":
+      return ExperimentalFlag.inferenceUpdate2;
     case "macros":
       return ExperimentalFlag.macros;
     case "named-arguments-anywhere":
@@ -544,6 +563,8 @@
       ExperimentalFlag.genericMetadata.isEnabledByDefault,
   ExperimentalFlag.inferenceUpdate1:
       ExperimentalFlag.inferenceUpdate1.isEnabledByDefault,
+  ExperimentalFlag.inferenceUpdate2:
+      ExperimentalFlag.inferenceUpdate2.isEnabledByDefault,
   ExperimentalFlag.macros: ExperimentalFlag.macros.isEnabledByDefault,
   ExperimentalFlag.namedArgumentsAnywhere:
       ExperimentalFlag.namedArgumentsAnywhere.isEnabledByDefault,
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 47e743c..780e0c6 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -10,44 +10,25 @@
 
 dependencies:
   _fe_analyzer_shared: any
-  kernel:
-    path: ../kernel
+  kernel: any
   package_config: any
 
 dev_dependencies:
   analyzer: any
-  args: ^2.0.0
-  async_helper:
-    path: ../async_helper
-  build_integration:
-    path: ../build_integration
-  compiler:
-    path: ../compiler
-  dart2wasm:
-    path: ../dart2wasm
-  dart_style: ^2.0.0
-  dev_compiler:
-    path: ../dev_compiler
-  expect:
-    path: ../expect
-  json_rpc_2: ^3.0.0
-  path: ^1.3.9
-  test: ^1.3.4
-  testing:
-    path: ../testing
-  test_reflective_loader: ^0.2.0
-  vm:
-    path: ../vm
+  args: any
+  async_helper: any
+  build_integration: any
+  compiler: any
+  dart2wasm: any
+  dart_style: any
+  dev_compiler: any
+  expect: any
+  json_rpc_2: any
+  path: any
+  test: any
+  test_reflective_loader: any
+  testing: any
+  vm: any
   vm_service: any
-  web_socket_channel: ^2.0.0
+  web_socket_channel: any
   yaml: any
-
-dependency_overrides:
-  analyzer:
-    path: ../analyzer
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  package_config:
-    path: ../../third_party/pkg_tested/package_config
-  vm_service:
-    path: ../vm_service
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 62f7446..9ce3011 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -7,24 +7,17 @@
   sdk: "^2.15.0"
 
 dependencies:
-  args: ^2.0.0
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  build_integration:
-    path: ../build_integration
-  compiler:
-    path: ../compiler
-  dev_compiler:
-    path: ../dev_compiler
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
-  package_config: ^2.0.0
+  _fe_analyzer_shared: any
+  args: any
+  build_integration: any
+  compiler: any
+  dev_compiler: any
+  front_end: any
+  kernel: any
+  package_config: any
   path: any
   usage: any
-  vm:
-    path: ../vm
+  vm: any
 
 dev_dependencies:
   mockito: any
diff --git a/pkg/js_ast/pubspec.yaml b/pkg/js_ast/pubspec.yaml
index 4afc01e..7d23ea0 100644
--- a/pkg/js_ast/pubspec.yaml
+++ b/pkg/js_ast/pubspec.yaml
@@ -6,7 +6,6 @@
   sdk: '>=2.16.0 <3.0.0'
 
 dev_dependencies:
-  expect:
-    path: ../expect
-  lints: ^2.0.0
-  test: ^1.3.4
+  expect: any
+  lints: any
+  test: any
diff --git a/pkg/js_runtime/pubspec.yaml b/pkg/js_runtime/pubspec.yaml
index e707d77..14f07a4 100644
--- a/pkg/js_runtime/pubspec.yaml
+++ b/pkg/js_runtime/pubspec.yaml
@@ -6,7 +6,5 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dev_dependencies:
-  expect:
-    path: ../expect
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
+  expect: any
+  _fe_analyzer_shared: any
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 140b0ee..31ec688 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -9,9 +9,7 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dev_dependencies:
-  args: ^2.0.0
-  expect:
-    path: ../expect
-  front_end:
-    path: ../front_end
+  args: any
+  expect: any
+  front_end: any
   test: any
diff --git a/pkg/meta/CHANGELOG.md b/pkg/meta/CHANGELOG.md
index ea032dd..1d01881 100644
--- a/pkg/meta/CHANGELOG.md
+++ b/pkg/meta/CHANGELOG.md
@@ -1,4 +1,4 @@
-## master
+## 1.8.0
 
 * Add `@UseResult.unless`.
 * The mechanism behind `noInline` and `tryInline` from `dart2js.dart` has been
diff --git a/pkg/meta/README.md b/pkg/meta/README.md
index 81fae76..cf01a70 100644
--- a/pkg/meta/README.md
+++ b/pkg/meta/README.md
@@ -1,4 +1,5 @@
-# Annotations for Static Analysis
+[![pub package](https://img.shields.io/pub/v/meta.svg)](https://pub.dev/packages/meta)
+[![package publisher](https://img.shields.io/pub/publisher/meta.svg)](https://pub.dev/packages/meta/publisher)
 
 This package defines annotations that can be used by the tools that are shipped
 with the Dart SDK.
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index ea5763c..4c5deeb 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -1,10 +1,9 @@
 name: meta
 # Note, because version `2.0.0` was mistakenly released, the next major version must be `3.x.y`.
-version: 1.7.1-dev
+version: 1.8.0
 description: >-
- Annotations that developers can use to express the intentions that otherwise
- can't be deduced by statically analyzing the source code. These annotations
- are intended to be used by tools to provide a better user experience.
+ Annotations used to express developer intentions that can't otherwise be
+ deduced by statically analyzing source code.
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/meta
 
 environment:
diff --git a/pkg/modular_test/pubspec.yaml b/pkg/modular_test/pubspec.yaml
index d6fcca8..538c555 100644
--- a/pkg/modular_test/pubspec.yaml
+++ b/pkg/modular_test/pubspec.yaml
@@ -5,6 +5,7 @@
  Small framework to test modular pipelines.
  This is used within the Dart SDK to define and validate modular tests, and to
  execute them using the modular pipeline of different SDK tools.
+
 environment:
   sdk: '>=2.16.0 <3.0.0'
 
@@ -14,8 +15,6 @@
   yaml: any
 
 dev_dependencies:
-  async_helper:
-    path: ../async_helper
-  expect:
-    path: ../expect
+  async_helper: any
+  expect: any
   test: any
diff --git a/pkg/nnbd_migration/pubspec.yaml b/pkg/nnbd_migration/pubspec.yaml
index e89625b..67f287b 100644
--- a/pkg/nnbd_migration/pubspec.yaml
+++ b/pkg/nnbd_migration/pubspec.yaml
@@ -10,30 +10,19 @@
   _fe_analyzer_shared: any
   analyzer: any
   analyzer_plugin: any
-  args: ^2.3.0
-  cli_util: ^0.3.5
-  collection: ^1.15.0
-  crypto: ^3.0.1
+  args: any
+  cli_util: any
+  collection: any
+  crypto: any
   meta: any
-  path: ^1.6.2
-  pub_semver: ^2.1.0
-  source_span: ^1.4.1
+  path: any
+  pub_semver: any
+  source_span: any
   yaml: any
 
 dev_dependencies:
-  analyzer_utilities:
-    path: ../analyzer_utilities
-  http: ^0.13.4
+  analyzer_utilities: any
+  http: any
   lints: any
-  test: ^1.6.4
-  test_reflective_loader: ^0.2.0
-
-dependency_overrides:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  analyzer:
-    path: ../analyzer
-  analyzer_plugin:
-    path: ../analyzer_plugin
-  meta:
-    path: ../meta
+  test: any
+  test_reflective_loader: any
diff --git a/pkg/scrape/pubspec.yaml b/pkg/scrape/pubspec.yaml
index d540ce1..ca3cee5 100644
--- a/pkg/scrape/pubspec.yaml
+++ b/pkg/scrape/pubspec.yaml
@@ -7,10 +7,9 @@
   sdk: ^2.13.0
 
 dependencies:
-  args: ^2.1.1
-  analyzer:
-    path: ../analyzer
-  path: ^1.7.0
+  args: any
+  analyzer: any
+  path: any
 
 dev_dependencies:
   lints: any
diff --git a/pkg/smith/pubspec.yaml b/pkg/smith/pubspec.yaml
index de47131..4dfeaea 100644
--- a/pkg/smith/pubspec.yaml
+++ b/pkg/smith/pubspec.yaml
@@ -5,5 +5,4 @@
 environment:
   sdk: "^2.12.0"
 dev_dependencies:
-  expect:
-    path: ../expect
+  expect: any
diff --git a/pkg/sourcemap_testing/pubspec.yaml b/pkg/sourcemap_testing/pubspec.yaml
index 5732caf..95dada8 100644
--- a/pkg/sourcemap_testing/pubspec.yaml
+++ b/pkg/sourcemap_testing/pubspec.yaml
@@ -7,12 +7,9 @@
   sdk: '>=2.1.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared
-  dart2js_tools: 
-    path: ../dart2js_tools
-  expect: 
-    path: ../expect
+  _fe_analyzer_shared: any
+  dart2js_tools:  any
+  expect:  any
   path: any
   source_maps: any
   source_span: any
diff --git a/pkg/status_file/pubspec.yaml b/pkg/status_file/pubspec.yaml
index 5f9e8e2..27e76b2 100644
--- a/pkg/status_file/pubspec.yaml
+++ b/pkg/status_file/pubspec.yaml
@@ -1,12 +1,13 @@
 name: status_file
 # This package is not intended for consumption on pub.dev. DO NOT publish.
 publish_to: none
+
 environment:
   sdk: "^2.12.0"
+
 dependencies:
-  path: "^1.4.0"
-  args: ^2.0.0
+  path: any
+  args: any
 
 dev_dependencies:
-  expect:
-    path: ../expect
+  expect: any
diff --git a/pkg/telemetry/pubspec.yaml b/pkg/telemetry/pubspec.yaml
index 2ceeac0..12acecc 100644
--- a/pkg/telemetry/pubspec.yaml
+++ b/pkg/telemetry/pubspec.yaml
@@ -7,12 +7,11 @@
   sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
-  http: ^0.13.0
-  meta:
-    path: ../meta
-  path: ^1.4.0
-  stack_trace: ^1.7.0
-  usage: ^4.0.0
+  http: any
+  meta: any
+  path: any
+  stack_trace: any
+  usage: any
 
 dev_dependencies:
-  test: ^1.0.0
+  test: any
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index e78bc08..f831b6b 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -9,33 +9,16 @@
   sdk: "^2.3.0"
 dependencies:
   args: any
-  dart2js_tools:
-    path: ../dart2js_tools
-  package_config:
-    path: ../../third_party/pkg_tested/package_config
+  dart2js_tools: any
+  package_config: any
   path: any
   pool: any
-  smith:
-    path: ../smith
-  status_file:
-    path: ../status_file
-  webdriver:
-    path: ../../third_party/pkg/webdriver
+  smith: any
+  status_file: any
+  webdriver: any
+
 dev_dependencies:
-  analyzer:
-    path: ../../pkg/analyzer
-  expect:
-    path: ../expect
+  analyzer: any
+  expect: any
   file: any
   glob: any
-dependency_overrides:
-  # Other packages in the dependency graph have normal hosted dependencies on
-  # this, so just override it to force the local one.
-  analyzer:
-    path: ../../pkg/analyzer
-  args:
-    path: ../../third_party/pkg/args
-  file:
-    path: ../../third_party/pkg/file/packages/file
-  glob:
-    path: ../../third_party/pkg/glob
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index 4086172..ca8bf35 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -7,20 +7,16 @@
   sdk: '>=2.15.0 <3.0.0'
 
 dependencies:
-  args: ^2.0.0
-  build_integration:
-    path: ../build_integration
+  args: any
+  build_integration: any
+  collection: any
   crypto: any
-  front_end:
-    path: ../front_end
-  kernel:
-    path: ../kernel
+  front_end: any
+  kernel: any
   package_config: any
-  collection: ^1.15.0
 
 dev_dependencies:
-  expect:
-    path: ../expect
+  expect: any
   json_rpc_2: any
   path: any
   test: any
diff --git a/runtime/tools/wiki/xref_extractor/pubspec.yaml b/runtime/tools/wiki/xref_extractor/pubspec.yaml
index ec9652d..11fd5ef 100644
--- a/runtime/tools/wiki/xref_extractor/pubspec.yaml
+++ b/runtime/tools/wiki/xref_extractor/pubspec.yaml
@@ -7,7 +7,7 @@
   sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  path: ^1.6.0
+  path: any
 
 dev_dependencies:
   lints: any
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index 668c019..094182f 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -3031,9 +3031,9 @@
     if (object != kWriteBarrierValueReg) {
       PushRegister(kWriteBarrierValueReg);
     } else {
-      COMPILE_ASSERT(S2 != kWriteBarrierValueReg);
       COMPILE_ASSERT(S3 != kWriteBarrierValueReg);
-      objectForCall = (value == S2) ? S3 : S2;
+      COMPILE_ASSERT(S4 != kWriteBarrierValueReg);
+      objectForCall = (value == S3) ? S4 : S3;
       PushRegisterPair(kWriteBarrierValueReg, objectForCall);
       mv(objectForCall, object);
     }
diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc
index b9fc91d..db65792 100644
--- a/runtime/vm/compiler/stub_code_compiler_riscv.cc
+++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc
@@ -272,12 +272,12 @@
 //   Stack: set up for native call (SP), aligned, CSP < SP
 //
 // On exit:
-//   S2: clobbered, although normally callee-saved
+//   S3: clobbered, although normally callee-saved
 //   Stack: preserved, CSP == SP
 void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
     Assembler* assembler) {
-  COMPILE_ASSERT(IsAbiPreservedRegister(S2));
-  __ mv(S2, RA);
+  COMPILE_ASSERT(IsAbiPreservedRegister(S3));
+  __ mv(S3, RA);
   __ LoadImmediate(T1, target::Thread::exit_through_ffi());
   __ TransitionGeneratedToNative(T0, FPREG, T1 /*volatile*/,
                                  /*enter_safepoint=*/true);
@@ -294,7 +294,7 @@
   __ jalr(T0);
 
   __ TransitionNativeToGenerated(T1, /*leave_safepoint=*/true);
-  __ jr(S2);
+  __ jr(S3);
 }
 
 #if !defined(DART_PRECOMPILER)
@@ -1321,7 +1321,9 @@
   __ lx(TMP2, Address(A3, target::Thread::invoke_dart_code_stub_offset()));
   __ PushRegister(TMP2);
 
-#if defined(USING_SHADOW_CALL_STACK)
+#if defined(DART_TARGET_OS_FUCHSIA)
+  __ sx(S2, Address(A3, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
 
@@ -3032,7 +3034,9 @@
   __ mv(SP, A1);                 // Stack pointer.
   __ mv(FP, A2);                 // Frame_pointer.
   __ mv(THR, A3);
-#if defined(USING_SHADOW_CALL_STACK)
+#if defined(DART_TARGET_OS_FUCHSIA)
+  __ lx(S2, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
   Label exit_through_non_ffi;
diff --git a/runtime/vm/constants_riscv.h b/runtime/vm/constants_riscv.h
index 91e9d78..435c5f8 100644
--- a/runtime/vm/constants_riscv.h
+++ b/runtime/vm/constants_riscv.h
@@ -61,7 +61,7 @@
   A5 = 15,  // PP, untagged
   A6 = 16,
   A7 = 17,
-  S2 = 18,
+  S2 = 18,  // ShadowCallStack
   S3 = 19,
   S4 = 20,  // ARGS_DESC_REG
   S5 = 21,  // IC_DATA_REG
@@ -192,10 +192,10 @@
 // Registers in addition to those listed in TypeTestABI used inside the
 // implementation of type testing stubs that are _not_ preserved.
 struct TTSInternalRegs {
-  static constexpr Register kInstanceTypeArgumentsReg = S2;
-  static constexpr Register kScratchReg = S3;
-  static constexpr Register kSubTypeArgumentReg = S4;
-  static constexpr Register kSuperTypeArgumentReg = S5;
+  static constexpr Register kInstanceTypeArgumentsReg = S3;
+  static constexpr Register kScratchReg = S4;
+  static constexpr Register kSubTypeArgumentReg = S5;
+  static constexpr Register kSuperTypeArgumentReg = S6;
 
   // Must be pushed/popped whenever generic type arguments are being checked as
   // they overlap with registers in TypeTestABI.
@@ -210,10 +210,10 @@
 // Registers in addition to those listed in TypeTestABI used inside the
 // implementation of subtype test cache stubs that are _not_ preserved.
 struct STCInternalRegs {
-  static constexpr Register kInstanceCidOrSignatureReg = S2;
-  static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S3;
-  static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S4;
-  static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S5;
+  static constexpr Register kInstanceCidOrSignatureReg = S3;
+  static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S4;
+  static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S5;
+  static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S6;
 
   static const intptr_t kInternalRegisters =
       (1 << kInstanceCidOrSignatureReg) |
@@ -443,15 +443,30 @@
                                          R(S6) | R(S7) | R(S8) | R(S9) |
                                          R(S10) | R(S11);
 constexpr int kAbiPreservedCpuRegCount = 11;
+
+#if defined(DART_TARGET_OS_FUCHSIA)
+// We rely on X18 not being touched by Dart generated assembly or stubs at all.
+// We rely on that any calls into C++ also preserve X18.
+constexpr intptr_t kReservedCpuRegisters =
+    R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
+    R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
+    R(FAR_TMP) | R(18);
+constexpr intptr_t kNumberOfReservedCpuRegisters = 15;
+#else
 constexpr intptr_t kReservedCpuRegisters =
     R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
     R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
     R(FAR_TMP);
 constexpr intptr_t kNumberOfReservedCpuRegisters = 14;
+#endif
 // CPU registers available to Dart allocator.
 constexpr RegList kDartAvailableCpuRegs =
     kAllCpuRegistersList & ~kReservedCpuRegisters;
+#if defined(DART_TARGET_OS_FUCHSIA)
+constexpr int kNumberOfDartAvailableCpuRegs = 17;
+#else
 constexpr int kNumberOfDartAvailableCpuRegs = 18;
+#endif
 // Registers X8-15 (S0-1,A0-5) have more compressed instructions available.
 constexpr int kRegisterAllocationBias = 8;
 // Registers available to Dart that are not preserved by runtime calls.
@@ -511,7 +526,8 @@
   static constexpr Register kSecondReturnReg = A1;
   static constexpr FpuRegister kReturnFpuReg = FA0;
 
-  static constexpr Register kFfiAnyNonAbiRegister = S2;  // S0=FP, S1=THR
+  // S0=FP, S1=THR, S2=ShadowCallStack
+  static constexpr Register kFfiAnyNonAbiRegister = S3;
   static constexpr Register kFirstNonArgumentRegister = T0;
   static constexpr Register kSecondNonArgumentRegister = T1;
   static constexpr Register kStackPointerRegister = SPREG;
diff --git a/runtime/vm/instructions_riscv.cc b/runtime/vm/instructions_riscv.cc
index 3a7d2a8..e753c2f 100644
--- a/runtime/vm/instructions_riscv.cc
+++ b/runtime/vm/instructions_riscv.cc
@@ -418,16 +418,16 @@
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
   // Calls to the type testing stubs look like:
-  //   lx s3, ...
+  //   lx s4, ...
   //   lx Rn, idx(pp)
-  //   jalr s3
+  //   jalr s4
   // where Rn = TypeTestABI::kSubtypeTestCacheReg.
 
   // Ensure the caller of the type testing stub (whose return address is [pc_])
   // branched via `blr R9` or a pc-relative call.
-  if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9982) {  // jalr s3
+  if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9a02) {  // jalr s4
     // indirect call
-    //     xxxx c.jalr s3
+    //     xxxx c.jalr s4
     Register reg;
     intptr_t pool_index = -1;
     InstructionPattern::DecodeLoadWordFromPool(pc_ - 2, &reg, &pool_index);
diff --git a/sdk/lib/_internal/wasm/lib/class_id.dart b/sdk/lib/_internal/wasm/lib/class_id.dart
index 49e0f2a..2e16f69 100644
--- a/sdk/lib/_internal/wasm/lib/class_id.dart
+++ b/sdk/lib/_internal/wasm/lib/class_id.dart
@@ -18,6 +18,8 @@
   external static int get cidObject;
   @pragma("wasm:class-id", "dart.async#Future")
   external static int get cidFuture;
+  @pragma("wasm:class-id", "dart.core#Function")
+  external static int get cidFunction;
 
   // Class IDs for RTI Types.
   @pragma("wasm:class-id", "dart.core#_NeverType")
diff --git a/sdk/lib/_internal/wasm/lib/type.dart b/sdk/lib/_internal/wasm/lib/type.dart
index 693eba3..046c15b 100644
--- a/sdk/lib/_internal/wasm/lib/type.dart
+++ b/sdk/lib/_internal/wasm/lib/type.dart
@@ -13,6 +13,7 @@
 // file:
 //   * [_Type.asNonNullable]
 //   * [_FutureOrType.asFuture].
+// TODO(joshualitt): Make `Function` a canonical type.
 abstract class _Type implements Type {
   final bool isNullable;
 
@@ -30,7 +31,9 @@
 
   T as<T>() => unsafeCast<T>(this);
 
-  _Type get asNonNullable;
+  _Type get asNonNullable => isNullable ? _asNonNullable : this;
+
+  _Type get _asNonNullable;
 
   @override
   bool operator ==(Object other) => ClassID.getID(this) == ClassID.getID(other);
@@ -44,7 +47,7 @@
   const _NeverType() : super(false);
 
   @override
-  _Type get asNonNullable => this;
+  _Type get _asNonNullable => this;
 
   @override
   String toString() => 'Never';
@@ -55,7 +58,7 @@
   const _DynamicType() : super(true);
 
   @override
-  _Type get asNonNullable => throw '`dynamic` type is always nullable.';
+  _Type get _asNonNullable => throw '`dynamic` type is always nullable.';
 
   @override
   String toString() => 'dynamic';
@@ -66,7 +69,7 @@
   const _VoidType() : super(true);
 
   @override
-  _Type get asNonNullable => throw '`void` type is always nullable.';
+  _Type get _asNonNullable => throw '`void` type is always nullable.';
 
   @override
   String toString() => 'void';
@@ -77,7 +80,7 @@
   const _NullType() : super(true);
 
   @override
-  _Type get asNonNullable => const _NeverType();
+  _Type get _asNonNullable => const _NeverType();
 
   @override
   String toString() => 'Null';
@@ -94,8 +97,7 @@
       _InterfaceType(ClassID.cidFuture, isNullable, [typeArgument]);
 
   @override
-  _Type get asNonNullable {
-    if (!isNullable) return this;
+  _Type get _asNonNullable {
     if (!typeArgument.isNullable) return _FutureOrType(false, typeArgument);
     throw '`$this` cannot be non nullable.';
   }
@@ -137,7 +139,7 @@
       : super(isNullable);
 
   @override
-  _Type get asNonNullable => _InterfaceType(classId, false, typeArguments);
+  _Type get _asNonNullable => _InterfaceType(classId, false, typeArguments);
 
   @override
   bool operator ==(Object o) {
@@ -171,7 +173,7 @@
     if (typeArguments.isNotEmpty) {
       s.write("<");
       for (int i = 0; i < typeArguments.length; i++) {
-        if (i > 0) s.write(",");
+        if (i > 0) s.write(", ");
         s.write(typeArguments[i]);
       }
       s.write(">");
@@ -181,25 +183,126 @@
   }
 }
 
-// TODO(joshualitt): Implement.
-@pragma("wasm:entry-point")
-class _FunctionType extends _Type {
-  const _FunctionType(bool isNullable) : super(isNullable);
+class _NamedParameter {
+  final String name;
+  final _Type type;
+  final bool isRequired;
+
+  @pragma("wasm:entry-point")
+  const _NamedParameter(this.name, this.type, this.isRequired);
 
   @override
-  _Type get asNonNullable => throw 'unimplemented';
+  bool operator ==(Object o) {
+    if (ClassID.getID(this) != ClassID.getID(o)) return false;
+    _NamedParameter other = unsafeCast<_NamedParameter>(o);
+    return this.name == other.name &&
+        this.type == other.type &&
+        isRequired == other.isRequired;
+  }
 
   @override
-  String toString() => 'FunctionType';
+  int get hashCode {
+    int hash = mix64(ClassID.getID(this));
+    hash = mix64(hash ^ name.hashCode);
+    hash = mix64(hash ^ type.hashCode);
+    return mix64(hash ^ (isRequired ? 1 : 0));
+  }
+
+  @override
+  String toString() {
+    StringBuffer s = StringBuffer();
+    if (isRequired) s.write('required ');
+    s.write(type);
+    s.write(' ');
+    s.write(name);
+    return s.toString();
+  }
 }
 
-// TODO(joshualitt): Implement.
+class _FunctionType extends _Type {
+  final _Type returnType;
+  final List<_Type> positionalParameters;
+  final int requiredParameterCount;
+  final List<_NamedParameter> namedParameters;
+
+  @pragma("wasm:entry-point")
+  const _FunctionType(this.returnType, this.positionalParameters,
+      this.requiredParameterCount, this.namedParameters, bool isNullable)
+      : super(isNullable);
+
+  @override
+  _Type get _asNonNullable => _FunctionType(returnType, positionalParameters,
+      requiredParameterCount, namedParameters, false);
+
+  bool operator ==(Object o) {
+    if (!(super == o)) return false;
+    _FunctionType other = unsafeCast<_FunctionType>(o);
+    if (isNullable != other.isNullable) return false;
+    if (returnType != other.returnType) ;
+    if (positionalParameters.length != other.positionalParameters.length) {
+      return false;
+    }
+    if (requiredParameterCount != other.requiredParameterCount) return false;
+    if (namedParameters.length != other.namedParameters.length) return false;
+    for (int i = 0; i < positionalParameters.length; i++) {
+      if (positionalParameters[i] != other.positionalParameters[i]) {
+        return false;
+      }
+    }
+    for (int i = 0; i < namedParameters.length; i++) {
+      if (namedParameters[i] != other.namedParameters[i]) return false;
+    }
+    return true;
+  }
+
+  @override
+  int get hashCode {
+    int hash = super.hashCode;
+    hash = mix64(hash ^ (isNullable ? 1 : 0));
+    hash = mix64(hash ^ returnType.hashCode);
+    for (int i = 0; i < positionalParameters.length; i++) {
+      hash = mix64(hash ^ positionalParameters[i].hashCode);
+    }
+    hash = mix64(hash ^ requiredParameterCount);
+    for (int i = 0; i < namedParameters.length; i++) {
+      hash = mix64(hash ^ namedParameters[i].hashCode);
+    }
+    return hash;
+  }
+
+  @override
+  String toString() {
+    StringBuffer s = StringBuffer();
+    s.write(returnType);
+    s.write(" Function(");
+    for (int i = 0; i < positionalParameters.length; i++) {
+      if (i > 0) s.write(", ");
+      if (i == requiredParameterCount) s.write("[");
+      s.write(positionalParameters[i]);
+    }
+    if (requiredParameterCount < positionalParameters.length) s.write("]");
+    if (namedParameters.isNotEmpty) {
+      if (positionalParameters.isNotEmpty) s.write(", ");
+      s.write("{");
+      for (int i = 0; i < namedParameters.length; i++) {
+        if (i > 0) s.write(", ");
+        s.write(namedParameters[i]);
+      }
+      s.write("}");
+    }
+    s.write(")");
+    if (isNullable) s.write("?");
+    return s.toString();
+  }
+}
+
+// TODO(joshualitt): Implement. This should probably extend _FunctionType.
 @pragma("wasm:entry-point")
-class _GenericFunctionType extends _FunctionType {
+class _GenericFunctionType extends _Type {
   const _GenericFunctionType(bool isNullable) : super(isNullable);
 
   @override
-  _Type get asNonNullable => throw 'unimplemented';
+  _Type get _asNonNullable => throw 'unimplemented';
 
   @override
   String toString() => 'GenericFunctionType';
@@ -217,14 +320,16 @@
     return _TypeUniverse._(_getSubtypeMap());
   }
 
-  bool isObjectQuestionType(_Type t) => isObjectType(t) && t.isNullable;
-
-  bool isObjectType(_Type t) {
+  bool isSpecificInterfaceType(_Type t, int classId) {
     if (!t.isInterface) return false;
     _InterfaceType type = t.as<_InterfaceType>();
-    return type.classId == ClassID.cidObject;
+    return type.classId == classId;
   }
 
+  bool isObjectQuestionType(_Type t) => isObjectType(t) && t.isNullable;
+
+  bool isObjectType(_Type t) => isSpecificInterfaceType(t, ClassID.cidObject);
+
   bool isTopType(_Type type) {
     return isObjectQuestionType(type) || type.isDynamic || type.isVoid;
   }
@@ -233,6 +338,9 @@
     return type.isNever;
   }
 
+  bool isFunctionType(_Type t) =>
+      isSpecificInterfaceType(t, ClassID.cidFunction);
+
   bool isInterfaceSubtype(_InterfaceType s, _InterfaceType t) {
     int sId = s.classId;
     int tId = t.classId;
@@ -252,6 +360,72 @@
     return true;
   }
 
+  bool isFunctionSubtype(_FunctionType s, _FunctionType t) {
+    if (!isSubtype(s.returnType, t.returnType)) return false;
+
+    // Check [s] does not have more required positional arguments than [t].
+    int sRequiredCount = s.requiredParameterCount;
+    int tRequiredCount = t.requiredParameterCount;
+    if (sRequiredCount > tRequiredCount) {
+      return false;
+    }
+
+    // Check [s] has enough required and optional positional arguments to
+    // potentially be a valid subtype of [t].
+    List<_Type> sPositional = s.positionalParameters;
+    List<_Type> tPositional = t.positionalParameters;
+    int sPositionalLength = sPositional.length;
+    int tPositionalLength = tPositional.length;
+    if (sPositionalLength < tPositionalLength) {
+      return false;
+    }
+
+    // Check all [t] positional arguments are subtypes of [s] positional
+    // arguments.
+    for (int i = 0; i < tPositionalLength; i++) {
+      _Type sParameter = sPositional[i];
+      _Type tParameter = tPositional[i];
+      if (!isSubtype(tParameter, sParameter)) {
+        return false;
+      }
+    }
+
+    // Check that [t]'s named arguments are subtypes of [s]'s named arguments.
+    // This logic assumes the named arguments are stored in sorted order.
+    List<_NamedParameter> sNamed = s.namedParameters;
+    List<_NamedParameter> tNamed = t.namedParameters;
+    int sNamedLength = sNamed.length;
+    int tNamedLength = tNamed.length;
+    int sIndex = 0;
+    for (int tIndex = 0; tIndex < tNamedLength; tIndex++) {
+      _NamedParameter tNamedParameter = tNamed[tIndex];
+      String tName = tNamedParameter.name;
+      while (true) {
+        if (sIndex >= sNamedLength) return false;
+        _NamedParameter sNamedParameter = sNamed[sIndex];
+        String sName = sNamedParameter.name;
+        sIndex++;
+        int sNameComparedToTName = sName.compareTo(tName);
+        if (sNameComparedToTName > 0) return false;
+        bool sIsRequired = sNamedParameter.isRequired;
+        if (sNameComparedToTName < 0) {
+          if (sIsRequired) return false;
+          continue;
+        }
+        bool tIsRequired = tNamedParameter.isRequired;
+        if (sIsRequired && !tIsRequired) return false;
+        if (!isSubtype(tNamedParameter.type, sNamedParameter.type)) {
+          return false;
+        }
+        break;
+      }
+    }
+    while (sIndex < sNamedLength) {
+      if (sNamed[sIndex].isRequired) return false;
+    }
+    return true;
+  }
+
   // Subtype check based off of sdk/lib/_internal/js_runtime/lib/rti.dart.
   // Returns true if [s] is a subtype of [t], false otherwise.
   bool isSubtype(_Type s, _Type t) {
@@ -312,7 +486,7 @@
 
     // Right Nullable:
     if (t.isNullable) {
-      return isSubtype(s, const _NullType()) || isSubtype(s, t.asNonNullable);
+      return isSubtype(s, t.asNonNullable);
     }
 
     // Left Promoted Variable does not apply at runtime.
@@ -321,10 +495,19 @@
     // TODO(joshualitt): Implement case.
 
     // Function Type / Function:
-    // TODO(joshualitt): Implement case.
+    if ((s.isFunction || s.isGenericFunction) && isFunctionType(t)) {
+      return true;
+    }
 
     // Positional Function Types + Named Function Types:
-    // TODO(joshualitt): Implement case.
+    if (s.isGenericFunction && t.isGenericFunction) {
+      // TODO(joshualitt): Implement case.
+      return true;
+    }
+
+    if (s.isFunction && t.isFunction) {
+      return isFunctionSubtype(s.as<_FunctionType>(), t.as<_FunctionType>());
+    }
 
     // Interface Compositionality + Super-Interface:
     if (s.isInterface &&
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index ce77e95..0f57f47 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -417,3 +417,76 @@
   JS('', '#.then(#, #)', jsPromise, success, error);
   return completer.future;
 }
+
+Object? _getConstructor(String constructorName) =>
+    getProperty(globalThis, constructorName);
+
+/// Like [instanceof] only takes a [String] for the object name instead of a
+/// constructor object.
+bool instanceOfString(Object? element, String objectType) {
+  Object? constructor = _getConstructor(objectType);
+  return constructor != null && instanceof(element, constructor);
+}
+
+/// Returns the prototype of a given object. Equivalent to
+/// `Object.getPrototypeOf`.
+Object? objectGetPrototypeOf(Object? object) =>
+    JS('', 'Object.getPrototypeOf(#)', object);
+
+/// Returns the `Object` prototype. Equivalent to `Object.prototype`.
+Object? get objectPrototype => JS('', 'Object.prototype');
+
+/// Returns the keys for a given object. Equivalent to `Object.keys(object)`.
+List<Object?> objectKeys(Object? object) => JS('', 'Object.keys(#)', object);
+
+/// Returns `true` if a given object is a JavaScript array.
+bool isJavaScriptArray(value) => instanceOfString(value, 'Array');
+
+/// Returns `true` if a given object is a simple JavaScript object.
+bool isJavaScriptSimpleObject(value) {
+  final Object? proto = objectGetPrototypeOf(value);
+  return proto == null || proto == objectPrototype;
+}
+
+/// Effectively the inverse of [jsify], [dartify] Takes a JavaScript object, and
+/// converts it to a Dart based object. Only JS primitives, arrays, or 'map'
+/// like JS objects are supported.
+Object? dartify(Object? o) {
+  var _convertedObjects = HashMap.identity();
+  Object? convert() {
+    if (_convertedObjects.containsKey(o)) {
+      return _convertedObjects[o];
+    }
+    if (o == null || o is bool || o is num || o is String) return o;
+    if (isJavaScriptSimpleObject(o)) {
+      Map<Object?, Object?> dartObject = {};
+      _convertedObjects[o] = dartObject;
+      List<Object?> originalKeys = objectKeys(o);
+      List<Object?> dartKeys = [];
+      for (Object? key in originalKeys) {
+        dartKeys.add(dartify(key));
+      }
+      for (int i = 0; i < originalKeys.length; i++) {
+        Object? jsKey = originalKeys[i];
+        Object? dartKey = dartKeys[i];
+        if (jsKey != null) {
+          dartObject[dartKey] = dartify(getProperty(o, jsKey));
+        }
+      }
+      return dartObject;
+    }
+    if (isJavaScriptArray(o)) {
+      List<Object?> dartObject = [];
+      _convertedObjects[o] = dartObject;
+      int length = getProperty(o, 'length');
+      for (int i = 0; i < length; i++) {
+        dartObject.add(dartify(getProperty(o, i)));
+      }
+      return dartObject;
+    }
+    throw ArgumentError(
+        "JavaScriptObject $o must be a primitive, simple object, or array");
+  }
+
+  return convert();
+}
diff --git a/tests/lib/js/js_util/dartify_test.dart b/tests/lib/js/js_util/dartify_test.dart
new file mode 100644
index 0000000..9fef877
--- /dev/null
+++ b/tests/lib/js/js_util/dartify_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests the dartify functionality of the js_util library.
+
+@JS()
+library js_util_jsify_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/expect.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+main() {
+  eval(r"""
+    globalThis.arrayData = [1, 2, false, 4, 'hello', 6, [1, 2], {'foo': 'bar'}];
+    globalThis.recArrayData = [];
+    globalThis.recArrayData = [globalThis.recArrayData];
+    globalThis.objectData = {
+      'a': 1,
+      'b': [1, 2, 3],
+      'c': {
+        'a': true,
+        'b': 'foo',
+      },
+    };
+    globalThis.recObjectData = {};
+    globalThis.recObjectData = {'foo': globalThis.recObjectData}
+    globalThis.throwData = function() {};
+    """);
+
+  test('convert an array', () {
+    Object? jsArray = js_util.getProperty(js_util.globalThis, 'arrayData');
+    Object? dartArray = js_util.dartify(jsArray);
+    List<Object?> expectedValues = [
+      1,
+      2,
+      false,
+      4,
+      'hello',
+      6,
+      [1, 2],
+      {'foo': 'bar'}
+    ];
+    Expect.deepEquals(expectedValues, dartArray);
+  });
+
+  test('convert a recursive array', () {
+    Object? jsArray = js_util.getProperty(js_util.globalThis, 'recArrayData');
+    Object? dartArray = js_util.dartify(jsArray);
+    List<Object?> expectedValues = [[]];
+    Expect.deepEquals(expectedValues, dartArray);
+  });
+
+  test('convert an object literal', () {
+    Object? jsObject = js_util.getProperty(js_util.globalThis, 'objectData');
+    Object? dartObject = js_util.dartify(jsObject);
+    Map<Object?, Object?> expectedValues = {
+      'a': 1,
+      'b': [1, 2, 3],
+      'c': {
+        'a': true,
+        'b': 'foo',
+      },
+    };
+    Expect.deepEquals(expectedValues, dartObject);
+  });
+
+  test('convert a recursive object literal', () {
+    Object? jsObject = js_util.getProperty(js_util.globalThis, 'recObjectData');
+    Object? dartObject = js_util.dartify(jsObject);
+    Map<Object?, Object?> expectedValues = {
+      'foo': {},
+    };
+    Expect.deepEquals(expectedValues, dartObject);
+  });
+
+  test('throws if object is not an object literal or array', () {
+    expect(
+        () => js_util
+            .dartify(js_util.getProperty(js_util.globalThis, 'throwData')),
+        throwsArgumentError);
+  });
+}
diff --git a/tests/lib/lib_dart2js.status b/tests/lib/lib_dart2js.status
index b1d2d3b..c7caca5 100644
--- a/tests/lib/lib_dart2js.status
+++ b/tests/lib/lib_dart2js.status
@@ -88,6 +88,7 @@
 html/js_typed_interop_window_property_test: SkipByDesign
 html/js_util_test: SkipByDesign
 html/postmessage_structured_test: SkipByDesign
+js/js_util/dartify_test: SkipByDesign
 
 [ $compiler == dart2js && ($runtime == chrome || $runtime == ff) ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
diff --git a/tests/lib_2/js/js_util/dartify_test.dart b/tests/lib_2/js/js_util/dartify_test.dart
new file mode 100644
index 0000000..9fef877
--- /dev/null
+++ b/tests/lib_2/js/js_util/dartify_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests the dartify functionality of the js_util library.
+
+@JS()
+library js_util_jsify_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/expect.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+main() {
+  eval(r"""
+    globalThis.arrayData = [1, 2, false, 4, 'hello', 6, [1, 2], {'foo': 'bar'}];
+    globalThis.recArrayData = [];
+    globalThis.recArrayData = [globalThis.recArrayData];
+    globalThis.objectData = {
+      'a': 1,
+      'b': [1, 2, 3],
+      'c': {
+        'a': true,
+        'b': 'foo',
+      },
+    };
+    globalThis.recObjectData = {};
+    globalThis.recObjectData = {'foo': globalThis.recObjectData}
+    globalThis.throwData = function() {};
+    """);
+
+  test('convert an array', () {
+    Object? jsArray = js_util.getProperty(js_util.globalThis, 'arrayData');
+    Object? dartArray = js_util.dartify(jsArray);
+    List<Object?> expectedValues = [
+      1,
+      2,
+      false,
+      4,
+      'hello',
+      6,
+      [1, 2],
+      {'foo': 'bar'}
+    ];
+    Expect.deepEquals(expectedValues, dartArray);
+  });
+
+  test('convert a recursive array', () {
+    Object? jsArray = js_util.getProperty(js_util.globalThis, 'recArrayData');
+    Object? dartArray = js_util.dartify(jsArray);
+    List<Object?> expectedValues = [[]];
+    Expect.deepEquals(expectedValues, dartArray);
+  });
+
+  test('convert an object literal', () {
+    Object? jsObject = js_util.getProperty(js_util.globalThis, 'objectData');
+    Object? dartObject = js_util.dartify(jsObject);
+    Map<Object?, Object?> expectedValues = {
+      'a': 1,
+      'b': [1, 2, 3],
+      'c': {
+        'a': true,
+        'b': 'foo',
+      },
+    };
+    Expect.deepEquals(expectedValues, dartObject);
+  });
+
+  test('convert a recursive object literal', () {
+    Object? jsObject = js_util.getProperty(js_util.globalThis, 'recObjectData');
+    Object? dartObject = js_util.dartify(jsObject);
+    Map<Object?, Object?> expectedValues = {
+      'foo': {},
+    };
+    Expect.deepEquals(expectedValues, dartObject);
+  });
+
+  test('throws if object is not an object literal or array', () {
+    expect(
+        () => js_util
+            .dartify(js_util.getProperty(js_util.globalThis, 'throwData')),
+        throwsArgumentError);
+  });
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 1f09063..39852b5 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -86,6 +86,7 @@
 html/js_typed_interop_window_property_test: SkipByDesign
 html/js_util_test: SkipByDesign
 html/postmessage_structured_test: SkipByDesign
+js/js_util/dartify_test: SkipByDesign
 
 [ $compiler == dart2js && ($runtime == chrome || $runtime == ff) ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
diff --git a/tools/VERSION b/tools/VERSION
index 9a42697..9ac4440 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 121
+PRERELEASE 122
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index c1b6308..cea81af 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -128,6 +128,9 @@
   inference-update-1:
     help: "Horizontal type inference for function expressions passed to generic invocations."
 
+  inference-update-2:
+    help: "Type promotion for fields"
+
 # Experiment flag only used for testing.
   test-experiment:
     help: >-
diff --git a/tools/package_deps/bin/package_deps.dart b/tools/package_deps/bin/package_deps.dart
index 8814aa7..48bf5b0 100644
--- a/tools/package_deps/bin/package_deps.dart
+++ b/tools/package_deps/bin/package_deps.dart
@@ -327,18 +327,10 @@
     // for pkg/ packages.
     if (!publishable) {
       for (PubDep dep in [..._declaredPubDeps, ..._declaredDevPubDeps]) {
-        if (pkgPackages.contains(dep.name) && dep is! PathPubDep) {
-          // check to see if there is a dependency_override to a path dependency
-          final override = _declaredOverridePubDeps
-              .singleWhereOrNull((element) => element.name == dep.name);
-          if (override != null && override is PathPubDep) {
-            continue;
-          }
-
-          out('  Prefer a relative path dep for pkg/ packages:');
-          out('    $dep');
-          fail = true;
-        }
+        if (dep is AnyPubDep) continue;
+        out('  Prefer `any` dependencies for unpublished packages');
+        out('    $dep');
+        fail = true;
       }
     }
 
@@ -530,7 +522,7 @@
 
   static PubDep parse(String name, Object dep) {
     if (dep is String) {
-      return SemverPubDep(name, dep);
+      return (dep == 'any') ? AnyPubDep(name) : SemverPubDep(name, dep);
     } else if (dep is Map) {
       if (dep.containsKey('path')) {
         return PathPubDep(name, dep['path']);
@@ -543,6 +535,13 @@
   }
 }
 
+class AnyPubDep extends PubDep {
+  AnyPubDep(String name) : super(name);
+
+  @override
+  String toString() => '$name: any';
+}
+
 class SemverPubDep extends PubDep {
   final String value;
 
diff --git a/tools/utils.py b/tools/utils.py
index d3401f1..9141d93 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -265,6 +265,9 @@
         return True
     if arch.startswith('sim'):
         return False
+    if arch.endswith('c'):
+        # Strip 'compressed' suffix.
+        arch = arch[:-1]
     if arch in HostArchitectures():
         return False
     return True