Version 2.19.0-0.0.dev

Merge commit '939134338742c86e8aff177cd1703d3261684398' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b8f7c1..55f8cdd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,71 +1,15 @@
 ## 2.19.0
 
-#### Dart command line
-
-- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
-  The standalone `dartanalyzer` tool has been removed as previously
-  announced. `dartanalyzer` is replaced by the `dart analyze` command.
-
 ### Language
 
-- **Breaking Change** [#48167](https://github.com/dart-lang/sdk/issues/48167):
-  Mixin of classes that don't extend `Object` is no longer supported:
-  ```dart
-  class Base {}
-  class Mixin extends Base {}
-  class C extends Base with Mixin {}
-  ```
-  This should instead be written using a mixin declaration of `Mixin`:
-  ```dart
-  class Base {}
-  mixin Mixin on Base {}
-  class C extends Base with Mixin {}
-  ```
-  This feature has not been supported in most compilation targets for some
-  time but is now completely removed.
-
 ### Libraries
 
-#### `dart:async`
-
-- The `Stream.fromIterable` stream can now be listened to more than once.
-
-### `dart:collection`
-
-- Deprecates `BidirectionalIterator`.
-
 ### `dart:developer`
 
 - Deprecates `UserTag.MAX_USER_TAGS` in favor of `UserTag.maxUserTags`.
 
-### Dart VM
-
-Implementation of `async`/`async*`/`sync*` is revamped in Dart VM,
-both in JIT and AOT modes. This also affects Flutter except Flutter Web.
-
-Besides smaller code size and better performance of async methods,
-the new implementation carries a few subtle changes in behavior:
-
-- If `async` method returns before reaching the first `await`, it now returns a completed Future.
-  Previously `async` methods completed resulting Future in separate microtasks.
-
-- Stack traces no longer have duplicate entries for `async` methods.
-
-- New implementation now correctly throws an error if `null` occurs as
-  an argument of a logical expression (`&&` and `||`) which also contains
-  an `await`.
-
-- New implementation avoids unnecessary extending the liveness of local
-  variables in `async`/`async*`/`sync*` methods, which means that unused
-  objects stored in local variables in such methods might be garbage
-  collected earlier than they were before
-  (see issue [#36983](https://github.com/dart-lang/sdk/issues/36983) for details).
-
-
 ### Tools
 
-#### Dart command line
-
 #### Linter
 
 Updated the Linter to `1.26.0`, which includes changes that
@@ -131,8 +75,32 @@
    }
    ```
 
+- **Breaking Change** [#48167](https://github.com/dart-lang/sdk/issues/48167):
+  Mixin of classes that don't extend `Object` is no longer supported:
+  ```dart
+  class Base {}
+  class Mixin extends Base {}
+  class C extends Base with Mixin {}
+  ```
+  This should instead be written using a mixin declaration of `Mixin`:
+  ```dart
+  class Base {}
+  mixin Mixin on Base {}
+  class C extends Base with Mixin {}
+  ```
+  This feature has not been supported in most compilation targets for some
+  time but is now completely removed.
+
 ### Core libraries
 
+#### `dart:async`
+
+- The `Stream.fromIterable` stream can now be listened to more than once.
+
+### `dart:collection`
+
+- Deprecates `BidirectionalIterator`.
+
 #### `dart:html`
 
 - Add `connectionState` attribute and `connectionstatechange` listener to
@@ -202,6 +170,29 @@
 - Allow omitting the `unencodedPath` positional argument to `Uri.http` and
   `Uri.https` to default to an empty path.
 
+### Dart VM
+
+Implementation of `async`/`async*`/`sync*` is revamped in Dart VM,
+both in JIT and AOT modes. This also affects Flutter except Flutter Web.
+
+Besides smaller code size and better performance of async methods,
+the new implementation carries a few subtle changes in behavior:
+
+- If `async` method returns before reaching the first `await`, it now returns a completed Future.
+  Previously `async` methods completed resulting Future in separate microtasks.
+
+- Stack traces no longer have duplicate entries for `async` methods.
+
+- New implementation now correctly throws an error if `null` occurs as
+  an argument of a logical expression (`&&` and `||`) which also contains
+  an `await`.
+
+- New implementation avoids unnecessary extending the liveness of local
+  variables in `async`/`async*`/`sync*` methods, which means that unused
+  objects stored in local variables in such methods might be garbage
+  collected earlier than they were before
+  (see issue [#36983](https://github.com/dart-lang/sdk/issues/36983) for details).
+
 ### Tools
 
 #### Dart command line
@@ -211,6 +202,10 @@
   announced. `dart2js` is replaced by the `dart compile js` command, `dartdevc`
   is no longer exposed as a command-line tool.
 
+- **Breaking change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+  The standalone `dartanalyzer` tool has been removed as previously
+  announced. `dartanalyzer` is replaced by the `dart analyze` command.
+
 #### Linter
 
 Updated the Linter to `1.25.0`, which includes changes that
diff --git a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
index 82a4176..188f29b 100644
--- a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
@@ -35,6 +35,17 @@
       (ancestor) => containerKinds.contains(ancestor.kind));
 }
 
+/// Gets a user-friendly display name for [element].
+String _getDisplayName(Element element) {
+  return element is CompilationUnitElement
+      ? element.source.shortName
+      : element is PropertyAccessorElement
+          ? element.isGetter
+              ? 'get ${element.displayName}'
+              : 'set ${element.displayName}'
+          : element.displayName;
+}
+
 /// A [CallHierarchyItem] and a set of ranges that call to or from it.
 class CallHierarchyCalls {
   final CallHierarchyItem item;
@@ -109,16 +120,6 @@
     return SourceRange(elementImpl.codeOffset!, elementImpl.codeLength!);
   }
 
-  static String _getDisplayName(Element element) {
-    return element is CompilationUnitElement
-        ? element.source.shortName
-        : element is PropertyAccessorElement
-            ? element.isGetter
-                ? 'get ${element.displayName}'
-                : 'set ${element.displayName}'
-            : element.displayName;
-  }
-
   /// Returns the [SourceRange] of the name for [element].
   static SourceRange _nameRangeForElement(Element element) {
     // For synthetic items (like implicit constructors), use the nonSynthetic
@@ -185,6 +186,9 @@
 
   /// Finds incoming calls to [target], returning the elements that call them
   /// and ranges of those calls within.
+  ///
+  /// Returns an empty list if [target] is not valid, including if source code
+  /// has changed and its offset is no longer correct.
   Future<List<CallHierarchyCalls>> findIncomingCalls(
     CallHierarchyItem target,
     SearchEngine searchEngine,
@@ -192,7 +196,7 @@
     assert(target.file == _result.path);
     final node = _findTargetNode(target.nameRange.offset);
     var element = _getElementOfNode(node);
-    if (element == null) {
+    if (element == null || !_isMatchingElement(element, target)) {
       return [];
     }
 
@@ -242,12 +246,18 @@
 
   /// Finds outgoing calls from [target], returning the elements that are called
   /// and the ranges that call them.
+  ///
+  /// Returns an empty list if [target] is not valid, including if source code
+  /// has changed and its offset is no longer correct.
   Future<List<CallHierarchyCalls>> findOutgoingCalls(
     CallHierarchyItem target,
   ) async {
     assert(target.file == _result.path);
     final node = _findTargetNode(target.nameRange.offset);
-    if (node == null) {
+    final element = _getElementOfNode(node);
+    if (node == null ||
+        element == null ||
+        !_isMatchingElement(element, target)) {
       return [];
     }
 
@@ -359,6 +369,15 @@
     return element;
   }
 
+  /// Checks whether [element] is a match for [target].
+  ///
+  /// This is used to ensure calls are only returned for the expected target
+  /// if source code has changed since the earlier request that provided
+  /// [target] to the client.
+  bool _isMatchingElement(Element element, CallHierarchyItem target) {
+    return _getDisplayName(element) == target.displayName;
+  }
+
   /// Returns the [SourceRange] to use for [node].
   ///
   /// The returned range covers only the name of the target and does not include
diff --git a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
index d0d5519..486abe6 100644
--- a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
@@ -69,6 +69,19 @@
   SourceRange entireRange(String code) =>
       SourceRange(0, withoutMarkers(code).length);
 
+  Future<CallHierarchyItem?> findTarget(String code) async {
+    final marker = code.indexOf('^');
+    expect(marker, greaterThanOrEqualTo(0));
+    addTestSource(withoutMarkers(code));
+
+    final result = await getResolvedUnit(testFile);
+
+    return DartCallHierarchyComputer(result).findTarget(marker);
+  }
+
+  Future<ResolvedUnitResult> getResolvedUnit(String file) async =>
+      await (await session).getResolvedUnit(file) as ResolvedUnitResult;
+
   // Gets the expected range that follows the string [prefix] in [code] with a
   // length of [match.length].
   SourceRange rangeAfterPrefix(String prefix, String code, String match) =>
@@ -111,16 +124,6 @@
     expect(target, matcher);
   }
 
-  Future<CallHierarchyItem?> findTarget(String code) async {
-    final marker = code.indexOf('^');
-    expect(marker, greaterThanOrEqualTo(0));
-    addTestSource(withoutMarkers(code));
-    final result =
-        await (await session).getResolvedUnit(testFile) as ResolvedUnitResult;
-
-    return DartCallHierarchyComputer(result).findTarget(marker);
-  }
-
   @override
   void setUp() {
     super.setUp();
@@ -128,7 +131,7 @@
   }
 
   Future<void> test_args() async {
-    await expectNoTarget('main(int ^a) {}');
+    await expectNoTarget('f(int ^a) {}');
   }
 
   Future<void> test_block() async {
@@ -580,25 +583,18 @@
   late SearchEngine searchEngine;
 
   Future<List<CallHierarchyCalls>> findIncomingCalls(String code) async {
-    final marker = code.indexOf('^');
-    expect(marker, greaterThanOrEqualTo(0));
-    addTestSource(withoutMarkers(code));
-    final session_ = await session;
+    final target = (await findTarget(code))!;
+    return findIncomingCallsForTarget(target);
+  }
 
-    var result = await session_.getResolvedUnit(testFile) as ResolvedUnitResult;
+  Future<List<CallHierarchyCalls>> findIncomingCallsForTarget(
+    CallHierarchyItem target,
+  ) async {
+    final result = await getResolvedUnit(target.file);
     expect(result.errors, isEmpty);
-    var computer = DartCallHierarchyComputer(result);
-    // It's possible that the target is in a different file (because we were
-    // invoked on a call and not a declaration), so fetch the resolved unit
-    // for the target.
-    final target = computer.findTarget(marker)!;
-    if (target.file != testFile) {
-      result =
-          await session_.getResolvedUnit(target.file) as ResolvedUnitResult;
-      expect(result.errors, isEmpty);
-      computer = DartCallHierarchyComputer(result);
-    }
-    return computer.findIncomingCalls(target, searchEngine);
+
+    return DartCallHierarchyComputer(result)
+        .findIncomingCalls(target, searchEngine);
   }
 
   @override
@@ -718,6 +714,28 @@
     );
   }
 
+  Future<void> test_fileModifications() async {
+    final contents = '''
+void o^ne() {}
+void two() {
+  one();
+}
+    ''';
+
+    final target = (await findTarget(contents))!;
+
+    // Ensure there are some results before modification.
+    var calls = await findIncomingCallsForTarget(target);
+    expect(calls, isNotEmpty);
+
+    // Modify the file so that the target offset is no longer the original item.
+    addTestSource(testCode.replaceAll('one()', 'three()'));
+
+    // Ensure there are now no results for the original target.
+    calls = await findIncomingCallsForTarget(target);
+    expect(calls, isEmpty);
+  }
+
   Future<void> test_function() async {
     final contents = '''
 String myFun^ction() => '';
@@ -1068,25 +1086,17 @@
   late String otherFile;
 
   Future<List<CallHierarchyCalls>> findOutgoingCalls(String code) async {
-    final marker = code.indexOf('^');
-    expect(marker, greaterThanOrEqualTo(0));
-    addTestSource(withoutMarkers(code));
-    final session_ = await session;
+    final target = (await findTarget(code))!;
+    return findOutgoingCallsForTarget(target);
+  }
 
-    var result = await session_.getResolvedUnit(testFile) as ResolvedUnitResult;
+  Future<List<CallHierarchyCalls>> findOutgoingCallsForTarget(
+    CallHierarchyItem target,
+  ) async {
+    final result = await getResolvedUnit(target.file);
     expect(result.errors, isEmpty);
-    var computer = DartCallHierarchyComputer(result);
-    // It's possible that the target is in a different file (because we were
-    // invoked on a call and not a declaration), so fetch the resolved unit
-    // for the target.
-    final target = computer.findTarget(marker)!;
-    if (target.file != testFile) {
-      result =
-          await session_.getResolvedUnit(target.file) as ResolvedUnitResult;
-      expect(result.errors, isEmpty);
-      computer = DartCallHierarchyComputer(result);
-    }
-    return computer.findOutgoingCalls(target);
+
+    return DartCallHierarchyComputer(result).findOutgoingCalls(target);
   }
 
   @override
@@ -1180,6 +1190,28 @@
     );
   }
 
+  Future<void> test_fileModifications() async {
+    final contents = '''
+void o^ne() {
+  two();
+}
+void two() {}
+    ''';
+
+    final target = (await findTarget(contents))!;
+
+    // Ensure there are some results before modification.
+    var calls = await findOutgoingCallsForTarget(target);
+    expect(calls, isNotEmpty);
+
+    // Modify the file so that the target offset is no longer the original item.
+    addTestSource(testCode.replaceAll('one()', 'three()'));
+
+    // Ensure there are now no results for the original target.
+    calls = await findOutgoingCallsForTarget(target);
+    expect(calls, isEmpty);
+  }
+
   Future<void> test_function() async {
     final contents = '''
 // ignore_for_file: unused_local_variable
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 616f487..291d453 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -8,7 +8,7 @@
 
 /// The current version of the Dart language (or, for non-stable releases, the
 /// version of the language currently in the process of being developed).
-const _currentVersion = '2.18.0';
+const _currentVersion = '2.19.0';
 
 /// A map containing information about all known experimental flags.
 final _knownFeatures = <String, ExperimentalFeature>{
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
index 020ebfb..156e6d2 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
@@ -24,12 +24,12 @@
     ]);
   }
 
-  test_correct_2_19() async {
+  test_correct_2_190() async {
     await assertErrorsInCode(r'''
-// @dart = 2.19
+// @dart = 2.190
 int i = 0;
 ''', [
-      error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER, 0, 15),
+      error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER, 0, 16),
     ]);
   }
 
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index 99be7f5..d4e4585 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.11.1
+- Call `analyzeFiles` from `handleAffectedFiles` only for files that are
+  analyzed in this analysis context.
+
 ## 0.11.0
 - Using `AnalysisContextCollection` and `AnalysisContext` for analysis.
 
diff --git a/pkg/analyzer_plugin/lib/plugin/plugin.dart b/pkg/analyzer_plugin/lib/plugin/plugin.dart
index fe76e56..3f7bb5d 100644
--- a/pkg/analyzer_plugin/lib/plugin/plugin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/plugin.dart
@@ -198,14 +198,19 @@
   /// one or more files. The implementation may check if these files should
   /// be analyzed, do such analysis, and send diagnostics.
   ///
-  /// By default invokes [analyzeFiles].
+  /// By default invokes [analyzeFiles] only for files that are analyzed in
+  /// this [analysisContext].
   Future<void> handleAffectedFiles({
     required AnalysisContext analysisContext,
     required List<String> paths,
   }) async {
+    final analyzedPaths = paths
+        .where(analysisContext.contextRoot.isAnalyzed)
+        .toList(growable: false);
+
     await analyzeFiles(
       analysisContext: analysisContext,
-      paths: paths,
+      paths: analyzedPaths,
     );
   }
 
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index 2b61963..ad43abd 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,6 +1,6 @@
 name: analyzer_plugin
 description: A framework and support code for building plugins for the analysis server.
-version: 0.11.0
+version: 0.11.1
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer_plugin
 
 environment:
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 71d843e..04e84d6 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
@@ -55,17 +55,17 @@
           name: 'alternative-invalidation-strategy',
           isEnabledByDefault: false,
           isExpired: false,
-          enabledVersion: const Version(2, 18),
-          experimentEnabledVersion: const Version(2, 18),
-          experimentReleasedVersion: const Version(2, 18));
+          enabledVersion: const Version(2, 19),
+          experimentEnabledVersion: const Version(2, 19),
+          experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag constFunctions = const ExperimentalFlag(
       name: 'const-functions',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag constantUpdate2018 = const ExperimentalFlag(
       name: 'constant-update-2018',
@@ -111,9 +111,9 @@
       name: 'extension-types',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag genericMetadata = const ExperimentalFlag(
       name: 'generic-metadata',
@@ -135,17 +135,17 @@
       name: 'inference-update-2',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag macros = const ExperimentalFlag(
       name: 'macros',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag namedArgumentsAnywhere = const ExperimentalFlag(
       name: 'named-arguments-anywhere',
@@ -199,9 +199,9 @@
       name: 'test-experiment',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag tripleShift = const ExperimentalFlag(
       name: 'triple-shift',
@@ -215,17 +215,17 @@
       name: 'value-class',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 
   static const ExperimentalFlag variance = const ExperimentalFlag(
       name: 'variance',
       isEnabledByDefault: false,
       isExpired: false,
-      enabledVersion: const Version(2, 18),
-      experimentEnabledVersion: const Version(2, 18),
-      experimentReleasedVersion: const Version(2, 18));
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
 }
 
 /// Interface for accessing the global state of experimental features.
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 3481e23..db71521 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -110,11 +110,6 @@
 final ExpectationSet staticExpectationSet =
     new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
 
-class Flags {
-  /// The expected result of the advanced invalidation.
-  static const String advancedInvalidation = 'advancedInvalidation';
-}
-
 const String EXPECTATIONS = '''
 [
   {
@@ -370,18 +365,18 @@
           "incrementalSerialization",
           "nnbdMode",
         ]);
-        result = await new NewWorldTest().newWorldTest(
-          data,
-          context,
-          map["worlds"],
-          map["modules"],
-          map["omitPlatform"],
-          map["target"],
-          map["forceLateLoweringForTesting"] ?? false,
-          map["trackWidgetCreation"] ?? false,
-          map["incrementalSerialization"],
-          map["nnbdMode"] == "strong" ? NnbdMode.Strong : NnbdMode.Weak,
-        );
+        result = await new NewWorldTest(
+          data: data,
+          context: context,
+          omitPlatform: map["omitPlatform"] != false,
+          forceLateLoweringForTesting:
+              map["forceLateLoweringForTesting"] ?? false,
+          trackWidgetCreation: map["trackWidgetCreation"] ?? false,
+          incrementalSerialization: map["incrementalSerialization"] ?? false,
+          nnbdMode:
+              map["nnbdMode"] == "strong" ? NnbdMode.Strong : NnbdMode.Weak,
+          targetName: map["target"],
+        ).newWorldTest();
         break;
       default:
         throw "Unexpected type: ${map['type']}";
@@ -532,7 +527,404 @@
   return moduleResult;
 }
 
+String doStringReplacements(String input) {
+  Version enableNonNullableVersion =
+      ExperimentalFlag.nonNullable.experimentEnabledVersion;
+  String output = input.replaceAll("%NNBD_VERSION_MARKER%",
+      "${enableNonNullableVersion.major}.${enableNonNullableVersion.minor}");
+  return output;
+}
+
+class ExpressionCompilation {
+  final bool errors;
+  final bool warnings;
+  final String uri;
+  final String expression;
+
+  ExpressionCompilation(
+      {required this.errors,
+      required this.warnings,
+      required this.uri,
+      required this.expression});
+
+  static ExpressionCompilation create(Map yaml) {
+    Set<String> keys = new Set<String>.from(yaml.keys);
+
+    bool errors = checkTypeOrNull<bool>(yaml, keys, "errors") ?? false;
+    bool warnings = checkTypeOrNull<bool>(yaml, keys, "warnings") ?? false;
+    String uri = checkType<String>(yaml, keys, "uri");
+    String expression = checkType<String>(yaml, keys, "expression");
+
+    if (keys.isNotEmpty) {
+      throw "Unknown key(s) for ExpressionCompilation: $keys";
+    }
+    return new ExpressionCompilation(
+        errors: errors, warnings: warnings, uri: uri, expression: expression);
+  }
+}
+
+T checkType<T>(Map world, Set<String> keys, String key, {Set<T>? options}) {
+  dynamic data = world[key];
+  keys.remove(key);
+  if (data == null) throw "Expected '$key' to have non-null value.";
+  if (data is! T) throw "Expected '$key' to be a '$T'.";
+  if (options != null) {
+    if (!options.contains(data)) {
+      throw "Got '$data' for '$key' but expected one of $options";
+    }
+  }
+  return data;
+}
+
+T? checkTypeOrNull<T>(Map world, Set<String> keys, String key,
+    {Set<T>? options}) {
+  dynamic data = world[key];
+  keys.remove(key);
+  if (data == null) return null;
+  if (data is! T) {
+    throw "Expected '$key' to be a '$T' but was '${data.runtimeType}'";
+  }
+  if (options != null) {
+    if (!options.contains(data)) {
+      throw "Got '$data' for '$key' but expected one of $options";
+    }
+  }
+  return data;
+}
+
+T? checkTypeEnumOrNull<T extends Enum>(
+    Map world, Set<String> keys, String key, List<T> enums) {
+  String? enumValue = checkTypeOrNull<String>(world, keys, key,
+      options: new Set<String>.from(enums.map((e) => e.name)));
+  if (enumValue == null) return null;
+  return enums.where((element) => element.name == enumValue).single;
+}
+
+List<T>? checkTypeListOrNull<T>(Map world, Set<String> keys, String key) {
+  List? list = checkTypeOrNull<List>(world, keys, key);
+  if (list == null) return null;
+  try {
+    return new List<T>.from(list);
+  } catch (e) {
+    throw "Expected the list to contain '$T' for '$key' but failed: $e";
+  }
+}
+
+Map<K, V>? checkTypeMapOrNull<K, V>(Map world, Set<String> keys, String key) {
+  Map? map = checkTypeOrNull<Map>(world, keys, key);
+  if (map == null) return null;
+  try {
+    return new Map<K, V>.from(map);
+  } catch (e) {
+    throw "Expected the map to contain '<$K, $V>' for '$key' but failed: $e";
+  }
+}
+
+Map<K, List<V>>? checkTypeMapListOrNull<K, V>(
+    Map world, Set<String> keys, String key) {
+  Map? map = checkTypeOrNull<Map>(world, keys, key);
+  if (map == null) return null;
+  try {
+    Map<K, List<V>> result = {};
+    for (var entry in map.entries) {
+      result[entry.key] = new List<V>.from(entry.value);
+    }
+    return result;
+  } catch (e) {
+    throw "Expected the map to contain '<$K, $V>' for '$key' but failed: $e";
+  }
+}
+
+List<T>? checkTypeSingletonOrListOrNull<T>(
+    Map world, Set<String> keys, String key) {
+  dynamic data = world[key];
+  keys.remove(key);
+
+  if (data == null) return null;
+  if (data is T) return [data];
+  if (data is List) {
+    try {
+      return new List<T>.from(data);
+    } catch (e) {
+      throw "Expected the list to contain '$T' for '$key' but failed: $e";
+    }
+  }
+  throw "Expected '$key' to be a '$T' or List<$T>";
+}
+
+List<T> checkTypeSingletonOrList<T>(Map world, Set<String> keys, String key) {
+  List<T>? data = checkTypeSingletonOrListOrNull(world, keys, key);
+  if (data == null) throw "Expected non-null value for '$key'";
+  return data;
+}
+
+class World {
+  final List<String>? modules;
+  final bool updateWorldType;
+  final bool noFullComponent;
+  final bool? expectInitializeFromDill;
+  final Map<String, String?> sources;
+  final bool useBadSdk;
+  final bool enableStringReplacement;
+  final String? packageConfigFile;
+  final String? experiments;
+  final String? nnbdModeString;
+  final List<String> entries;
+  final bool outlineOnly;
+  final bool skipOutlineBodyCheck;
+  final bool fromComponent;
+  final List<String>? invalidate;
+  final bool simulateTransformer;
+  final bool? expectInitializationError;
+  final bool compareToPrevious;
+  final List<String>? uriToSourcesDoesntInclude;
+  final List<String>? uriToSourcesOnlyIncludes;
+  final bool skipClassHierarchyTest;
+  final bool expectsPlatform;
+  final int? expectedLibraryCount;
+  final int? expectedSyntheticLibraryCount;
+  final bool warnings;
+  final bool errors;
+  final List<String>? neededDillLibraries;
+  final Map<String, List<String>>? expectedContent;
+  final bool incrementalSerializationDoesWork;
+
+  /// The expected result of the advanced invalidation.
+  final AdvancedInvalidationResult? advancedInvalidation;
+
+  final bool checkEntries;
+  final bool checkInvalidatedFiles;
+  final List<String>? expectedInvalidatedUri;
+  final int? expectSameErrorsAsWorld;
+  final List<ExpressionCompilation>? expressionCompilation;
+  final bool compareWithFromScratch;
+
+  /// Don't check for equality when we allow it to be different
+  /// (e.g. when the old one contains more, and the new one doesn't).
+  final bool brandNewIncrementalSerializationAllowDifferent;
+
+  final List<String>? serializationShouldNotInclude;
+
+  World({
+    required this.modules,
+    required this.updateWorldType,
+    required this.noFullComponent,
+    required this.expectInitializeFromDill,
+    required this.sources,
+    required this.useBadSdk,
+    required this.enableStringReplacement,
+    required this.packageConfigFile,
+    required this.experiments,
+    required this.nnbdModeString,
+    required this.entries,
+    required this.outlineOnly,
+    required this.skipOutlineBodyCheck,
+    required this.fromComponent,
+    required this.invalidate,
+    required this.simulateTransformer,
+    required this.expectInitializationError,
+    required this.compareToPrevious,
+    required this.uriToSourcesDoesntInclude,
+    required this.uriToSourcesOnlyIncludes,
+    required this.skipClassHierarchyTest,
+    required this.expectsPlatform,
+    required this.expectedLibraryCount,
+    required this.expectedSyntheticLibraryCount,
+    required this.advancedInvalidation,
+    required this.checkEntries,
+    required this.checkInvalidatedFiles,
+    required this.expectedInvalidatedUri,
+    required this.expectSameErrorsAsWorld,
+    required this.expressionCompilation,
+    required this.compareWithFromScratch,
+    required this.brandNewIncrementalSerializationAllowDifferent,
+    required this.warnings,
+    required this.errors,
+    required this.neededDillLibraries,
+    required this.expectedContent,
+    required this.incrementalSerializationDoesWork,
+    required this.serializationShouldNotInclude,
+  });
+
+  static World create(Map world) {
+    Set<String> keys = new Set<String>.from(world.keys);
+
+    List<String>? modules = checkTypeListOrNull<String>(world, keys, "modules");
+
+    String? worldType =
+        checkTypeOrNull(world, keys, "worldType", options: {"updated"});
+    bool updateWorldType = worldType == "updated";
+
+    bool noFullComponent =
+        checkTypeOrNull<bool>(world, keys, "noFullComponent") ?? false;
+
+    bool? expectInitializeFromDill =
+        checkTypeOrNull<bool>(world, keys, "expectInitializeFromDill");
+
+    Map<String, String?> sources =
+        checkTypeMapOrNull<String, String?>(world, keys, "sources") ?? {};
+
+    bool useBadSdk = checkTypeOrNull<bool>(world, keys, "badSdk") ?? false;
+
+    bool enableStringReplacement =
+        checkTypeOrNull<bool>(world, keys, "enableStringReplacement") ?? false;
+
+    String? packageConfigFile =
+        checkTypeOrNull<String>(world, keys, "packageConfigFile");
+
+    String? experiments = checkTypeOrNull<String>(world, keys, "experiments");
+
+    String? nnbdModeString =
+        checkTypeOrNull<String>(world, keys, "nnbdMode", options: {"strong"});
+
+    List<String> entries =
+        checkTypeSingletonOrList<String>(world, keys, "entry");
+
+    bool outlineOnly =
+        checkTypeOrNull<bool>(world, keys, "outlineOnly") ?? false;
+
+    bool skipOutlineBodyCheck =
+        checkTypeOrNull<bool>(world, keys, "skipOutlineBodyCheck") ?? false;
+
+    bool fromComponent =
+        checkTypeOrNull<bool>(world, keys, "fromComponent") ?? false;
+
+    List<String>? invalidate =
+        checkTypeListOrNull<String>(world, keys, "invalidate");
+
+    bool simulateTransformer =
+        checkTypeOrNull<bool>(world, keys, "simulateTransformer") ?? false;
+
+    bool? expectInitializationError =
+        checkTypeOrNull<bool>(world, keys, "expectInitializationError");
+
+    bool compareToPrevious =
+        checkTypeOrNull<bool>(world, keys, "compareToPrevious") ?? false;
+
+    List<String>? uriToSourcesDoesntInclude =
+        checkTypeListOrNull<String>(world, keys, "uriToSourcesDoesntInclude");
+
+    List<String>? uriToSourcesOnlyIncludes =
+        checkTypeListOrNull<String>(world, keys, "uriToSourcesOnlyIncludes");
+
+    bool skipClassHierarchyTest =
+        checkTypeOrNull<bool>(world, keys, "skipClassHierarchyTest") ?? false;
+
+    bool expectsPlatform =
+        checkTypeOrNull<bool>(world, keys, "expectsPlatform") ?? false;
+
+    int? expectedLibraryCount =
+        checkTypeOrNull<int>(world, keys, "expectedLibraryCount");
+
+    int? expectedSyntheticLibraryCount =
+        checkTypeOrNull<int>(world, keys, "expectedSyntheticLibraryCount");
+
+    /// The expected result of the advanced invalidation.
+    AdvancedInvalidationResult? advancedInvalidation =
+        checkTypeEnumOrNull<AdvancedInvalidationResult>(world, keys,
+            "advancedInvalidation", AdvancedInvalidationResult.values);
+
+    bool checkEntries =
+        checkTypeOrNull<bool>(world, keys, "checkEntries") ?? true;
+
+    bool checkInvalidatedFiles =
+        checkTypeOrNull<bool>(world, keys, "checkInvalidatedFiles") ?? true;
+
+    List<String>? expectedInvalidatedUri =
+        checkTypeListOrNull<String>(world, keys, "expectedInvalidatedUri");
+
+    int? expectSameErrorsAsWorld =
+        checkTypeOrNull<int>(world, keys, "expectSameErrorsAsWorld");
+
+    List<Map>? expressionCompilationRaw = checkTypeSingletonOrListOrNull<Map>(
+        world, keys, "expressionCompilation");
+    List<ExpressionCompilation>? expressionCompilation =
+        expressionCompilationRaw
+            ?.map((e) => ExpressionCompilation.create(e))
+            .toList();
+
+    bool compareWithFromScratch =
+        checkTypeOrNull<bool>(world, keys, "compareWithFromScratch") ?? false;
+
+    bool brandNewIncrementalSerializationAllowDifferent = checkTypeOrNull<bool>(
+            world, keys, "brandNewIncrementalSerializationAllowDifferent") ??
+        false;
+
+    bool warnings = checkTypeOrNull<bool>(world, keys, "warnings") ?? false;
+
+    bool errors = checkTypeOrNull<bool>(world, keys, "errors") ?? false;
+
+    List<String>? neededDillLibraries =
+        checkTypeListOrNull<String>(world, keys, "neededDillLibraries");
+
+    Map<String, List<String>>? expectedContent =
+        checkTypeMapListOrNull<String, String>(world, keys, "expectedContent");
+
+    bool incrementalSerializationDoesWork = checkTypeOrNull<bool>(
+            world, keys, "incrementalSerializationDoesWork") ??
+        false;
+
+    List<String>? serializationShouldNotInclude = checkTypeListOrNull<String>(
+        world, keys, "serializationShouldNotInclude");
+
+    if (keys.isNotEmpty) {
+      throw "Unknown key(s) for World: $keys";
+    }
+
+    return new World(
+      modules: modules,
+      updateWorldType: updateWorldType,
+      noFullComponent: noFullComponent,
+      expectInitializeFromDill: expectInitializeFromDill,
+      sources: sources,
+      useBadSdk: useBadSdk,
+      enableStringReplacement: enableStringReplacement,
+      packageConfigFile: packageConfigFile,
+      experiments: experiments,
+      nnbdModeString: nnbdModeString,
+      entries: entries,
+      outlineOnly: outlineOnly,
+      skipOutlineBodyCheck: skipOutlineBodyCheck,
+      fromComponent: fromComponent,
+      invalidate: invalidate,
+      simulateTransformer: simulateTransformer,
+      expectInitializationError: expectInitializationError,
+      compareToPrevious: compareToPrevious,
+      uriToSourcesDoesntInclude: uriToSourcesDoesntInclude,
+      uriToSourcesOnlyIncludes: uriToSourcesOnlyIncludes,
+      skipClassHierarchyTest: skipClassHierarchyTest,
+      expectsPlatform: expectsPlatform,
+      expectedLibraryCount: expectedLibraryCount,
+      expectedSyntheticLibraryCount: expectedSyntheticLibraryCount,
+      advancedInvalidation: advancedInvalidation,
+      checkEntries: checkEntries,
+      checkInvalidatedFiles: checkInvalidatedFiles,
+      expectedInvalidatedUri: expectedInvalidatedUri,
+      expectSameErrorsAsWorld: expectSameErrorsAsWorld,
+      expressionCompilation: expressionCompilation,
+      compareWithFromScratch: compareWithFromScratch,
+      brandNewIncrementalSerializationAllowDifferent:
+          brandNewIncrementalSerializationAllowDifferent,
+      warnings: warnings,
+      errors: errors,
+      neededDillLibraries: neededDillLibraries,
+      expectedContent: expectedContent,
+      incrementalSerializationDoesWork: incrementalSerializationDoesWork,
+      serializationShouldNotInclude: serializationShouldNotInclude,
+    );
+  }
+}
+
 class NewWorldTest {
+  final TestData data;
+  final Context context;
+  final bool omitPlatform;
+  final bool forceLateLoweringForTesting;
+  final bool trackWidgetCreation;
+  final bool incrementalSerialization;
+  final NnbdMode nnbdMode;
+  final String? targetName;
+
   // These are fields in a class to make it easier to track down memory leaks
   // via the leak detector test.
   Component? newestWholeComponent;
@@ -541,25 +933,22 @@
   Component? component2;
   Component? component3;
 
-  String doStringReplacements(String input) {
-    Version enableNonNullableVersion =
-        ExperimentalFlag.nonNullable.experimentEnabledVersion;
-    String output = input.replaceAll("%NNBD_VERSION_MARKER%",
-        "${enableNonNullableVersion.major}.${enableNonNullableVersion.minor}");
-    return output;
-  }
+  NewWorldTest({
+    required this.data,
+    required this.context,
+    required this.omitPlatform,
+    required this.forceLateLoweringForTesting,
+    required this.trackWidgetCreation,
+    required this.incrementalSerialization,
+    required this.nnbdMode,
+    required this.targetName,
+  });
 
-  Future<Result<TestData>> newWorldTest(
-      TestData data,
-      Context context,
-      List worlds,
-      Map? modules,
-      bool? omitPlatform,
-      String? targetName,
-      bool forceLateLoweringForTesting,
-      bool trackWidgetCreation,
-      bool? incrementalSerialization,
-      NnbdMode nnbdMode) async {
+  List<World> get worlds =>
+      (data.map["worlds"] as List).map((e) => World.create(e)).toList();
+  Map? get modules => data.map["modules"];
+
+  Future<Result<TestData>> newWorldTest() async {
     final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
 
     TestTargetFlags targetFlags = new TestTargetFlags(
@@ -608,7 +997,7 @@
 
     if (modules != null) {
       moduleData = await createModules(
-          modules, sdkSummaryData, target, originalTarget, sdkSummary,
+          modules!, sdkSummaryData, target, originalTarget, sdkSummary,
           trackNeededDillLibraries: false);
       sdk = newestWholeComponent = new Component();
       new BinaryBuilder(sdkSummaryData,
@@ -619,13 +1008,13 @@
     int worldNum = 0;
     // TODO: When needed, we can do this for warnings too.
     List<Set<String>> worldErrors = [];
-    for (YamlMap world in worlds) {
+    for (World world in worlds) {
       worldNum++;
       print("----------------");
       print("World #$worldNum");
       print("----------------");
       List<Component>? modulesToUse;
-      if (world["modules"] != null) {
+      if (world.modules != null) {
         moduleComponents ??= new Map<String, Component>();
 
         sdk!.adoptChildren();
@@ -634,13 +1023,13 @@
         }
 
         modulesToUse = <Component>[];
-        for (String moduleName in world["modules"]) {
+        for (String moduleName in world.modules!) {
           Component? moduleComponent = moduleComponents[moduleName];
           if (moduleComponent != null) {
             modulesToUse.add(moduleComponent);
           }
         }
-        for (String moduleName in world["modules"]) {
+        for (String moduleName in world.modules!) {
           Component? moduleComponent = moduleComponents[moduleName];
           if (moduleComponent == null) {
             moduleComponent = new Component(nameRoot: sdk!.root);
@@ -655,16 +1044,7 @@
         }
       }
 
-      bool brandNewWorld = true;
-      if (world["worldType"] == "updated") {
-        brandNewWorld = false;
-      }
-      bool noFullComponent = false;
-      if (world["noFullComponent"] == true) {
-        noFullComponent = true;
-      }
-
-      if (brandNewWorld) {
+      if (!world.updateWorldType) {
         fs = new TestMemoryFileSystem(base);
       }
       fs!.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
@@ -676,14 +1056,13 @@
             .writeAsBytesSync(newestWholeComponentData);
         expectInitializeFromDill = true;
       }
-      if (world["expectInitializeFromDill"] != null) {
-        expectInitializeFromDill = world["expectInitializeFromDill"];
+      if (world.expectInitializeFromDill != null) {
+        expectInitializeFromDill = world.expectInitializeFromDill!;
       }
-      if (brandNewWorld) {
-        sourceFiles = new Map<String, String?>.from(world["sources"]);
+      if (!world.updateWorldType) {
+        sourceFiles = new Map<String, String?>.from(world.sources);
       } else {
-        sourceFiles!.addAll(new Map<String, String?>.from(
-            world["sources"] ?? <String, String?>{}));
+        sourceFiles!.addAll(new Map<String, String?>.from(world.sources));
       }
       Uri? packagesUri;
       for (String filename in sourceFiles.keys) {
@@ -692,28 +1071,28 @@
         if (filename == ".dart_tool/package_config.json") {
           packagesUri = uri;
         }
-        if (world["enableStringReplacement"] == true) {
+        if (world.enableStringReplacement) {
           data = doStringReplacements(data);
         }
         fs.entityForUri(uri).writeAsStringSync(data);
       }
-      if (world["packageConfigFile"] != null) {
-        packagesUri = base.resolve(world["packageConfigFile"]);
+      if (world.packageConfigFile != null) {
+        packagesUri = base.resolve(world.packageConfigFile!);
       }
 
-      if (brandNewWorld) {
+      if (!world.updateWorldType) {
         options = getOptions(target: target, sdkSummary: sdkSummary);
         options.nnbdMode = nnbdMode;
         options.fileSystem = fs;
         options.sdkRoot = null;
         options.sdkSummary = sdkSummaryUri;
-        if (world["badSdk"] == true) {
+        if (world.useBadSdk) {
           options.sdkSummary = sdkSummaryUri.resolve("nonexisting.dill");
         }
-        options.omitPlatform = omitPlatform != false;
-        if (world["experiments"] != null) {
+        options.omitPlatform = omitPlatform;
+        if (world.experiments != null) {
           Map<String, bool> flagsFromOptions =
-              parseExperimentalArguments([world["experiments"]]);
+              parseExperimentalArguments([world.experiments!]);
           // Ensure that we run with non-nullable turned off even when the
           // flag is on by default.
           Map<ExperimentalFlag, bool> explicitExperimentalFlags =
@@ -726,8 +1105,8 @@
         }
         // A separate "world" can also change nnbd mode ---
         // notice that the platform is not updated though!
-        if (world["nnbdMode"] != null) {
-          String nnbdMode = world["nnbdMode"];
+        if (world.nnbdModeString != null) {
+          String nnbdMode = world.nnbdModeString!;
           switch (nnbdMode) {
             case "strong":
               options.nnbdMode = NnbdMode.Strong;
@@ -769,32 +1148,21 @@
         }
       };
 
-      List<Uri> entries;
-      if (world["entry"] is String) {
-        entries = [base.resolve(world["entry"])];
-      } else {
-        entries = <Uri>[];
-        List<dynamic> entryList = world["entry"];
-        for (String entry in entryList) {
-          entries.add(base.resolve(entry));
-        }
-      }
-      bool outlineOnly = world["outlineOnly"] == true;
-      bool skipOutlineBodyCheck = world["skipOutlineBodyCheck"] == true;
-      if (brandNewWorld) {
+      List<Uri> entries = world.entries.map((e) => base.resolve(e)).toList();
+      if (!world.updateWorldType) {
         if (incrementalSerialization == true) {
           incrementalSerializer = new IncrementalSerializer();
         }
-        if (world["fromComponent"] == true) {
+        if (world.fromComponent) {
           compiler = new TestIncrementalCompiler.fromComponent(
               options,
               entries.first,
               (modulesToUse != null) ? sdk : newestWholeComponent,
-              outlineOnly,
+              world.outlineOnly,
               incrementalSerializer);
         } else {
           compiler = new TestIncrementalCompiler(options, entries.first,
-              initializeFrom, outlineOnly, incrementalSerializer);
+              initializeFrom, world.outlineOnly, incrementalSerializer);
 
           if (modulesToUse != null) {
             throw "You probably shouldn't do this! "
@@ -804,8 +1172,8 @@
       }
 
       List<Uri> invalidated = <Uri>[];
-      if (world["invalidate"] != null) {
-        for (String filename in world["invalidate"]) {
+      if (world.invalidate != null) {
+        for (String filename in world.invalidate!) {
           Uri uri = base.resolve(filename);
           invalidated.add(uri);
           compiler!.invalidate(uri);
@@ -820,14 +1188,15 @@
       Stopwatch stopwatch = new Stopwatch()..start();
       IncrementalCompilerResult? compilerResult = await compiler!.computeDelta(
           entryPoints: entries,
-          fullComponent:
-              brandNewWorld ? false : (noFullComponent ? false : true),
+          fullComponent: !world.updateWorldType
+              ? false
+              : (world.noFullComponent ? false : true),
           trackNeededDillLibraries: modulesToUse != null,
-          simulateTransformer: world["simulateTransformer"]);
+          simulateTransformer: world.simulateTransformer);
       component = compilerResult.component;
       // compilerResult is null'ed out at the end to avoid any
       // "artificial memory leak" on that account.
-      if (outlineOnly && !skipOutlineBodyCheck) {
+      if (world.outlineOnly && !world.skipOutlineBodyCheck) {
         for (Library lib in component!.libraries) {
           for (Class c in lib.classes) {
             for (Procedure p in c.procedures) {
@@ -847,19 +1216,20 @@
       Result<TestData>? result = performErrorAndWarningCheck(world, data,
           gotError, formattedErrors, gotWarning, formattedWarnings);
       if (result != null) return result;
-      if (world["expectInitializationError"] != null) {
+      bool? expectInitializationError = world.expectInitializationError;
+      if (expectInitializationError != null) {
         Set<String> seenInitializationError = seenDiagnosticCodes.intersection({
           "InitializeFromDillNotSelfContainedNoDump",
           "InitializeFromDillNotSelfContained",
           "InitializeFromDillUnknownProblem",
           "InitializeFromDillUnknownProblemNoDump",
         });
-        if (world["expectInitializationError"] == true) {
+        if (expectInitializationError) {
           if (seenInitializationError.isEmpty) {
             return new Result<TestData>(data, MissingInitializationError,
                 "Expected to see an initialization error but didn't.");
           }
-        } else if (world["expectInitializationError"] == false) {
+        } else {
           if (seenInitializationError.isNotEmpty) {
             return new Result<TestData>(
                 data,
@@ -867,9 +1237,6 @@
                 "Expected not to see an initialization error but did: "
                 "$seenInitializationError.");
           }
-        } else {
-          throw "Unsupported value for 'expectInitializationError': "
-              "${world["expectInitializationError"]}";
         }
       }
       util.throwOnEmptyMixinBodies(component!);
@@ -886,7 +1253,7 @@
       Result? nnbdCheck = checkNNBDSettings(component!);
       if (nnbdCheck != null) return nnbdCheck.copyWithOutput(data);
 
-      if (!noFullComponent) {
+      if (!world.noFullComponent) {
         Set<Library> allLibraries = new Set<Library>();
         for (Library lib in component!.libraries) {
           computeAllReachableLibrariesFor(lib, allLibraries);
@@ -917,7 +1284,7 @@
       result = checkExpectFile(data, worldNum, "", context, actualSerialized);
       if (result != null) return result;
 
-      if (world["compareToPrevious"] == true && newestWholeComponent != null) {
+      if (world.compareToPrevious && newestWholeComponent != null) {
         EquivalenceResult result = checkEquivalence(
             newestWholeComponent!, component!,
             strategy: const Strategy());
@@ -930,8 +1297,8 @@
       newestWholeComponentData = util.postProcess(component!);
       newestWholeComponent = component;
 
-      if (world["uriToSourcesDoesntInclude"] != null) {
-        for (String filename in world["uriToSourcesDoesntInclude"]) {
+      if (world.uriToSourcesDoesntInclude != null) {
+        for (String filename in world.uriToSourcesDoesntInclude!) {
           Uri uri = base.resolve(filename);
           if (component!.uriToSource[uri] != null) {
             return new Result<TestData>(
@@ -942,9 +1309,9 @@
           }
         }
       }
-      if (world["uriToSourcesOnlyIncludes"] != null) {
+      if (world.uriToSourcesOnlyIncludes != null) {
         Set<Uri> allowed = {};
-        for (String filename in world["uriToSourcesOnlyIncludes"]) {
+        for (String filename in world.uriToSourcesOnlyIncludes!) {
           Uri uri = base.resolve(filename);
           allowed.add(uri);
         }
@@ -963,7 +1330,7 @@
         }
       }
 
-      if (world["skipClassHierarchyTest"] != true) {
+      if (!world.skipClassHierarchyTest) {
         result = checkClassHierarchy(compilerResult, data, worldNum, context);
         if (result != null) return result;
       }
@@ -972,7 +1339,7 @@
       int nonSyntheticPlatformLibraries =
           countNonSyntheticPlatformLibraries(component!);
       int syntheticLibraries = countSyntheticLibraries(component!);
-      if (world["expectsPlatform"] == true) {
+      if (world.expectsPlatform) {
         if (nonSyntheticPlatformLibraries < 5) {
           return new Result<TestData>(
               data,
@@ -990,45 +1357,44 @@
               "but got $nonSyntheticPlatformLibraries.");
         }
       }
-      if (world["expectedLibraryCount"] != null) {
+      if (world.expectedLibraryCount != null) {
         if (nonSyntheticLibraries - nonSyntheticPlatformLibraries !=
-            world["expectedLibraryCount"]) {
+            world.expectedLibraryCount!) {
           return new Result<TestData>(
               data,
               LibraryCountMismatch,
-              "Expected ${world["expectedLibraryCount"]} non-synthetic "
+              "Expected ${world.expectedLibraryCount} non-synthetic "
               "libraries, got "
               "${nonSyntheticLibraries - nonSyntheticPlatformLibraries} "
               "(not counting platform libraries)");
         }
       }
-      if (world["expectedSyntheticLibraryCount"] != null) {
-        if (syntheticLibraries != world["expectedSyntheticLibraryCount"]) {
+      if (world.expectedSyntheticLibraryCount != null) {
+        if (syntheticLibraries != world.expectedSyntheticLibraryCount!) {
           return new Result<TestData>(
               data,
               LibraryCountMismatch,
-              "Expected ${world["expectedSyntheticLibraryCount"]} synthetic "
+              "Expected ${world.expectedSyntheticLibraryCount} synthetic "
               "libraries, got ${syntheticLibraries}");
         }
       }
 
-      String? expectedAdvancedInvalidation = world[Flags.advancedInvalidation];
-      if (expectedAdvancedInvalidation != null) {
+      if (world.advancedInvalidation != null) {
         AdvancedInvalidationResult? actualAdvancedInvalidation =
             compiler.recorderForTesting.advancedInvalidationResult;
-        if (expectedAdvancedInvalidation != actualAdvancedInvalidation?.name) {
+        if (world.advancedInvalidation != actualAdvancedInvalidation) {
           return new Result<TestData>(
               data,
               UnexpectedAdvancedInvalidation,
-              "Expected ${Flags.advancedInvalidation}: "
-              "$expectedAdvancedInvalidation, "
-              "${Flags.advancedInvalidation}: "
-              "${actualAdvancedInvalidation?.name}.");
+              "Expected advancedInvalidation: "
+              "${world.advancedInvalidation}, "
+              "advancedInvalidation: "
+              "${actualAdvancedInvalidation}.");
         }
       }
 
-      if (!noFullComponent) {
-        if (world["checkEntries"] != false) {
+      if (!world.noFullComponent) {
+        if (world.checkEntries) {
           List<Library> entryLib = component!.libraries
               .where((Library lib) =>
                   entries.contains(lib.importUri) ||
@@ -1060,20 +1426,20 @@
         Expect.isFalse(compiler.initializedIncrementalSerializerForTesting);
       }
 
-      if (world["checkInvalidatedFiles"] != false) {
+      if (world.checkInvalidatedFiles) {
         Set<Uri>? filteredInvalidated =
             compiler.getFilteredInvalidatedImportUrisForTesting(invalidated);
-        if (world["invalidate"] != null) {
+        if (world.invalidate != null) {
           Expect.equals(
-              world["invalidate"].length, filteredInvalidated?.length ?? 0);
-          List? expectedInvalidatedUri = world["expectedInvalidatedUri"];
-          if (expectedInvalidatedUri != null) {
-            Expect.setEquals(expectedInvalidatedUri.map((s) => base.resolve(s)),
+              world.invalidate!.length, filteredInvalidated?.length ?? 0);
+          if (world.expectedInvalidatedUri != null) {
+            Expect.setEquals(
+                world.expectedInvalidatedUri!.map((s) => base.resolve(s)),
                 filteredInvalidated!);
           }
         } else {
           Expect.isNull(filteredInvalidated);
-          Expect.isNull(world["expectedInvalidatedUri"]);
+          Expect.isNull(world.expectedInvalidatedUri);
         }
       }
       Result<List<int>?> serializationResult = checkIncrementalSerialization(
@@ -1085,10 +1451,9 @@
 
       worldErrors.add(formattedErrors.toSet());
       assert(worldErrors.length == worldNum);
-      if (world["expectSameErrorsAsWorld"] != null) {
-        int expectSameErrorsAsWorld = world["expectSameErrorsAsWorld"];
+      if (world.expectSameErrorsAsWorld != null) {
         checkErrorsAndWarnings(
-          worldErrors[expectSameErrorsAsWorld - 1],
+          worldErrors[world.expectSameErrorsAsWorld! - 1],
           formattedErrors,
           {},
           {},
@@ -1105,13 +1470,13 @@
         formattedWarnings.clear();
       }
 
-      if (!noFullComponent) {
+      if (!world.noFullComponent) {
         clearPrevErrorsEtc();
         IncrementalCompilerResult? compilerResult2 =
             await compiler.computeDelta(
                 entryPoints: entries,
                 fullComponent: true,
-                simulateTransformer: world["simulateTransformer"]);
+                simulateTransformer: world.simulateTransformer);
         component2 = compilerResult2.component;
         compilerResult2 = null;
         Result<TestData>? result = performErrorAndWarningCheck(world, data,
@@ -1152,37 +1517,29 @@
         }
       }
 
-      if (world["expressionCompilation"] != null) {
-        List compilations;
-        if (world["expressionCompilation"] is List) {
-          compilations = world["expressionCompilation"];
-        } else {
-          compilations = [world["expressionCompilation"]];
-        }
+      if (world.expressionCompilation != null) {
         int expressionCompilationNum = 0;
-        for (Map compilation in compilations) {
+        for (ExpressionCompilation compilation
+            in world.expressionCompilation!) {
           expressionCompilationNum++;
           clearPrevErrorsEtc();
-          bool expectErrors = compilation["errors"] ?? false;
-          bool expectWarnings = compilation["warnings"] ?? false;
-          Uri uri = base.resolve(compilation["uri"]);
-          String expression = compilation["expression"];
+          Uri uri = base.resolve(compilation.uri);
           Procedure procedure = (await compiler.compileExpression(
-              expression, {}, [], "debugExpr", uri))!;
-          if (gotError && !expectErrors) {
+              compilation.expression, {}, [], "debugExpr", uri))!;
+          if (gotError && !compilation.errors) {
             return new Result<TestData>(data, UnexpectedErrors,
                 "Got error(s) on expression compilation: ${formattedErrors}.");
-          } else if (!gotError && expectErrors) {
+          } else if (!gotError && compilation.errors) {
             return new Result<TestData>(
                 data, MissingErrors, "Didn't get any errors.");
           }
-          if (gotWarning && !expectWarnings) {
+          if (gotWarning && !compilation.warnings) {
             return new Result<TestData>(
                 data,
                 UnexpectedWarnings,
                 "Got warning(s) on expression compilation: "
                 "${formattedWarnings}.");
-          } else if (!gotWarning && expectWarnings) {
+          } else if (!gotWarning && compilation.warnings) {
             return new Result<TestData>(
                 data, MissingWarnings, "Didn't get any warnings.");
           }
@@ -1196,9 +1553,8 @@
         }
       }
 
-      if (!noFullComponent &&
-          (incrementalSerialization == true ||
-              world["compareWithFromScratch"] == true)) {
+      if (!world.noFullComponent &&
+          (incrementalSerialization == true || world.compareWithFromScratch)) {
         // Do compile from scratch and compare.
         clearPrevErrorsEtc();
         TestIncrementalCompiler? compilerFromScratch;
@@ -1208,12 +1564,16 @@
           incrementalSerializer2 = new IncrementalSerializer();
         }
 
-        if (world["fromComponent"] == true || modulesToUse != null) {
+        if (world.fromComponent || modulesToUse != null) {
           compilerFromScratch = new TestIncrementalCompiler.fromComponent(
-              options, entries.first, sdk, outlineOnly, incrementalSerializer2);
+              options,
+              entries.first,
+              sdk,
+              world.outlineOnly,
+              incrementalSerializer2);
         } else {
           compilerFromScratch = new TestIncrementalCompiler(options,
-              entries.first, null, outlineOnly, incrementalSerializer2);
+              entries.first, null, world.outlineOnly, incrementalSerializer2);
         }
 
         if (modulesToUse != null) {
@@ -1226,7 +1586,7 @@
             await compilerFromScratch.computeDelta(
                 entryPoints: entries,
                 trackNeededDillLibraries: modulesToUse != null,
-                simulateTransformer: world["simulateTransformer"]);
+                simulateTransformer: world.simulateTransformer);
         component3 = compilerResult3.component;
         compilerResult3 = null;
         compilerFromScratch = null;
@@ -1240,7 +1600,7 @@
         List<int> thisWholeComponent = util.postProcess(component3!);
         print("*****\n\ncomponent3:\n"
             "${componentToStringSdkFiltered(component3!)}\n\n\n");
-        if (world["compareWithFromScratch"] == true) {
+        if (world.compareWithFromScratch) {
           checkIsEqual(newestWholeComponentData, thisWholeComponent);
         }
         checkErrorsAndWarnings(prevFormattedErrors, formattedErrors,
@@ -1268,7 +1628,7 @@
         }
 
         if (incrementalSerializationBytes != null) {
-          if (world["brandNewIncrementalSerializationAllowDifferent"] == true) {
+          if (world.brandNewIncrementalSerializationAllowDifferent) {
             // Don't check for equality when we allow it to be different
             // (e.g. when the old one contains more, and the new one doesn't).
           } else {
@@ -1606,7 +1966,7 @@
     bool? incrementalSerialization,
     Component component,
     IncrementalSerializer? incrementalSerializer,
-    YamlMap world) {
+    World world) {
   if (incrementalSerialization == true) {
     Component c = new Component(nameRoot: component.root)
       ..setMainMethodAndMode(null, false, component.mode);
@@ -1622,7 +1982,7 @@
           "Incremental serialization added libraries!");
     }
     if (librariesBefore == librariesAfter &&
-        world["incrementalSerializationDoesWork"] == true) {
+        world.incrementalSerializationDoesWork) {
       return new Result<List<int>>(null, IncrementalSerializationError,
           "Incremental serialization didn't remove any libraries!");
     }
@@ -1650,12 +2010,10 @@
       new BinaryBuilder(bytes, filename: null).readComponent(loadedComponent);
 
       // Check that it doesn't contain anything we said it shouldn't.
-      if (world["serializationShouldNotInclude"] is List) {
-        List serializationShouldNotInclude =
-            world["serializationShouldNotInclude"];
+      if (world.serializationShouldNotInclude != null) {
         Set<Uri> includedImportUris =
             loadedComponent.libraries.map((l) => l.importUri).toSet();
-        for (String uriString in serializationShouldNotInclude) {
+        for (String uriString in world.serializationShouldNotInclude!) {
           Uri uri = Uri.parse(uriString);
           if (includedImportUris.contains(uri)) {
             return new Result<List<int>>(
@@ -1730,17 +2088,16 @@
   }
 }
 
-Result? checkExpectedContent(YamlMap world, Component component) {
-  if (world["expectedContent"] != null) {
+Result? checkExpectedContent(World world, Component component) {
+  if (world.expectedContent != null) {
     Map<String, Set<String>> actualContent = buildMapOfContent(component);
-    Map expectedContent = world["expectedContent"];
-    return checkExpectedContentData(actualContent, expectedContent);
+    return checkExpectedContentData(actualContent, world.expectedContent!);
   }
   return null;
 }
 
-Result? checkExpectedContentData(
-    Map<String, Set<String>> actualContent, Map expectedContent) {
+Result? checkExpectedContentData(Map<String, Set<String>> actualContent,
+    Map<String, Iterable<String>> expectedContent) {
   Result<TestData> createFailureResult() {
     return new Result(
         null,
@@ -1758,9 +2115,9 @@
   if (missingKeys.isNotEmpty) {
     return createFailureResult();
   }
-  for (String key in expectedContent.keys) {
-    Set<String> expected = new Set<String>.from(expectedContent[key]);
-    Set<String> actual = actualContent[key]!.toSet();
+  for (MapEntry<String, Iterable<String>> entry in expectedContent.entries) {
+    Set<String> expected = new Set<String>.from(entry.value);
+    Set<String> actual = actualContent[entry.key]!.toSet();
     if (expected.length != actual.length) {
       return createFailureResult();
     }
@@ -1791,8 +2148,8 @@
 }
 
 Result<TestData>? checkNeededDillLibraries(
-    YamlMap world, TestData data, Set<Library>? neededDillLibraries, Uri base) {
-  if (world["neededDillLibraries"] != null) {
+    World world, TestData data, Set<Library>? neededDillLibraries, Uri base) {
+  if (world.neededDillLibraries != null) {
     List<Uri> actualContent = <Uri>[];
     for (Library lib in neededDillLibraries!) {
       if (lib.importUri.isScheme("dart")) continue;
@@ -1800,7 +2157,7 @@
     }
 
     List<Uri> expectedContent = <Uri>[];
-    for (String entry in world["neededDillLibraries"]) {
+    for (String entry in world.neededDillLibraries!) {
       expectedContent.add(base.resolve(entry));
     }
 
@@ -1891,23 +2248,23 @@
 }
 
 Result<TestData>? performErrorAndWarningCheck(
-    YamlMap world,
+    World world,
     TestData data,
     bool gotError,
     Set<String> formattedErrors,
     bool gotWarning,
     Set<String> formattedWarnings) {
-  if (world["errors"] == true && !gotError) {
+  if (world.errors && !gotError) {
     return new Result<TestData>(
         data, MissingErrors, "Expected error, but didn't get any.");
-  } else if (world["errors"] != true && gotError) {
+  } else if (!world.errors && gotError) {
     return new Result<TestData>(
         data, UnexpectedErrors, "Got unexpected error(s): $formattedErrors.");
   }
-  if (world["warnings"] == true && !gotWarning) {
+  if (world.warnings && !gotWarning) {
     return new Result<TestData>(
         data, MissingWarnings, "Expected warning, but didn't get any.");
-  } else if (world["warnings"] != true && gotWarning) {
+  } else if (!world.warnings && gotWarning) {
     return new Result<TestData>(data, UnexpectedWarnings,
         "Got unexpected warnings(s): $formattedWarnings.");
   }
diff --git a/pkg/front_end/testcases/incremental/regress_35215.yaml b/pkg/front_end/testcases/incremental/regress_35215.yaml
index 92e35f0..522b5c8 100644
--- a/pkg/front_end/testcases/incremental/regress_35215.yaml
+++ b/pkg/front_end/testcases/incremental/regress_35215.yaml
@@ -22,7 +22,6 @@
     expectedLibraryCount: 2
     errors: true
   - entry: main.dart
-    worldTypex: updated
     invalidate:
       - b.dart
     sources:
diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart
index fcae847..b959db4 100644
--- a/pkg/kernel/lib/default_language_version.dart
+++ b/pkg/kernel/lib/default_language_version.dart
@@ -9,4 +9,4 @@
 
 import "ast.dart";
 
-Version defaultLanguageVersion = const Version(2, 18);
+Version defaultLanguageVersion = const Version(2, 19);
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index c776db0f..ad7117f 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -6,7 +6,7 @@
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'dart tools/generate_experimental_flags.dart' to update.
 //
-// Current version: 2.18.0
+// Current version: 2.19.0
 
 #include "vm/experimental_features.h"
 
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index be9be59..773062c 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -6,7 +6,7 @@
 // Instead modify 'tools/experimental_features.yaml' and run
 // 'dart tools/generate_experimental_flags.dart' to update.
 //
-// Current version: 2.18.0
+// Current version: 2.19.0
 
 #ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
 #define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
diff --git a/tools/VERSION b/tools/VERSION
index 005f402..e3f65ac 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 2
-MINOR 18
+MINOR 19
 PATCH 0
-PRERELEASE 286
+PRERELEASE 0
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 7ac7dbb..2ddf600 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -103,7 +103,7 @@
 # default 'language' "category" with code generated for both CFE and Analyzer,
 # while other categories can be tailored more specifically.
 
-current-version: '2.18.0'
+current-version: '2.19.0'
 
 features:
   variance: