Version 2.16.0-158.0.dev

Merge commit '44ba8ecdb2e5e9b24de9b63a6ab307240458f991' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index c3a351b..4932c25 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -28,6 +28,7 @@
 import 'package:analysis_server/src/services/completion/dart/relevance_tables.g.dart';
 import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/dart/super_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
@@ -155,6 +156,7 @@
       if (enableOverrideContributor) OverrideContributor(request, builder),
       RedirectingContributor(request, builder),
       StaticMemberContributor(request, builder),
+      SuperFormalContributor(request, builder),
       TypeMemberContributor(request, builder),
       if (enableUriContributor) UriContributor(request, builder),
       VariableNameContributor(request, builder),
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 864f1f9..1dbfe52 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -352,6 +352,9 @@
     var constructorDeclaration =
         node.thisOrAncestorOfType<ConstructorDeclaration>();
     if (constructorDeclaration != null) {
+      if (request.featureSet.isEnabled(Feature.super_parameters)) {
+        _addSuggestion(Keyword.SUPER);
+      }
       _addSuggestion(Keyword.THIS);
     }
     final entity = this.entity;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index a441aa0..b4c063c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -877,6 +877,17 @@
         relevance: relevance));
   }
 
+  /// Add a suggestion to reference a [parameter] in a super formal parameter.
+  void suggestSuperFormalParameter(ParameterElement parameter) {
+    _add(
+      _createSuggestion(
+        parameter,
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: Relevance.superFormalParameter,
+      ),
+    );
+  }
+
   /// Add a suggestion for a top-level [function]. If a [kind] is provided it
   /// will be used as the kind for the suggestion. If the function can only be
   /// referenced using a prefix, then the [prefix] should be provided.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart
new file mode 100644
index 0000000..fdd99bf
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:collection/collection.dart';
+
+/// A contributor that produces suggestions for super formal parameters that
+/// are based on the parameters declared by the invoked super-constructor.
+/// The enclosing declaration is expected to be a constructor.
+class SuperFormalContributor extends DartCompletionContributor {
+  SuperFormalContributor(
+    DartCompletionRequest request,
+    SuggestionBuilder builder,
+  ) : super(request, builder);
+
+  @override
+  Future<void> computeSuggestions() async {
+    var node = request.target.containingNode;
+    if (node is! SuperFormalParameter) {
+      return;
+    }
+
+    var element = node.declaredElement as SuperFormalParameterElementImpl;
+
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+    if (constructor == null) {
+      return;
+    }
+
+    var constructorElement = constructor.declaredElement;
+    constructorElement as ConstructorElementImpl;
+
+    var superConstructor = constructorElement.superConstructor;
+    if (superConstructor == null) {
+      return;
+    }
+
+    if (node.isNamed) {
+      var superConstructorInvocation = constructor.initializers
+          .whereType<SuperConstructorInvocation>()
+          .singleOrNull;
+      var specified = <String>{
+        ...constructorElement.parameters.map((e) => e.name),
+        ...?superConstructorInvocation?.argumentList.arguments
+            .whereType<NamedExpression>()
+            .map((e) => e.name.label.name),
+      };
+      for (var superParameter in superConstructor.parameters) {
+        if (superParameter.isNamed &&
+            !specified.contains(superParameter.name)) {
+          builder.suggestSuperFormalParameter(superParameter);
+        }
+      }
+    }
+
+    if (node.isPositional) {
+      var indexOfThis = element.indexIn(constructorElement);
+      var superPositionalList = superConstructor.parameters
+          .where((parameter) => parameter.isPositional)
+          .toList();
+      if (indexOfThis >= 0 && indexOfThis < superPositionalList.length) {
+        var superPositional = superPositionalList[indexOfThis];
+        builder.suggestSuperFormalParameter(superPositional);
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 1b58a84..34e4921 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -657,6 +657,14 @@
       DataDriven.newInstance,
       ImportLibrary.forType,
     ],
+    CompileTimeErrorCode
+        .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT: [
+      AddSuperConstructorInvocation.newInstance,
+    ],
+    CompileTimeErrorCode
+        .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS: [
+      AddSuperConstructorInvocation.newInstance,
+    ],
     CompileTimeErrorCode.INVALID_ANNOTATION: [
       ImportLibrary.forTopLevelVariable,
       ImportLibrary.forType,
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 432a8b3..c86b091 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -50,6 +50,7 @@
   List<String> get experiments => [
         EnableString.constructor_tearoffs,
         EnableString.named_arguments_anywhere,
+        EnableString.super_parameters,
       ];
 
   String get latestLanguageVersion =>
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 8128659..7bf72fe 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -55,7 +55,7 @@
         ..docSummary.isEqualTo('aaa')
         ..hasSelection(offset: 5)
         ..element.isNotNull.which((e) => e
-          ..isParameter
+          ..kind.isParameter
           ..name.isEqualTo('fff'))
     ]);
   }
@@ -79,7 +79,7 @@
         ..docSummary.isNull
         ..hasSelection(offset: 5)
         ..element.isNotNull.which((e) => e
-          ..isParameter
+          ..kind.isParameter
           ..name.isEqualTo('fff'))
     ]);
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_check.dart b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
index f9cdaf1..4c15bd2 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_check.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
@@ -55,6 +55,20 @@
 
 extension CompletionResponseExtension
     on CheckTarget<CompletionResponseForTesting> {
+  CheckTarget<int> get replacementLength {
+    return nest(
+      value.replacementLength,
+      (selected) => 'has replacementLength ${valueStr(selected)}',
+    );
+  }
+
+  CheckTarget<int> get replacementOffset {
+    return nest(
+      value.replacementOffset,
+      (selected) => 'has replacementOffset ${valueStr(selected)}',
+    );
+  }
+
   CheckTarget<List<CompletionSuggestionForTesting>> get suggestions {
     var suggestions = value.suggestions.map((e) {
       return CompletionSuggestionForTesting(
@@ -67,6 +81,19 @@
       (selected) => 'suggestions ${valueStr(selected)}',
     );
   }
+
+  /// Check that the replacement offset is the completion request offset,
+  /// and the length of the replacement is zero.
+  void hasEmptyReplacement() {
+    hasReplacement(left: 0, right: 0);
+  }
+
+  /// Check that the replacement offset is the completion request offset
+  /// minus [left], and the length of the replacement is `left + right`.
+  void hasReplacement({int left = 0, int right = 0}) {
+    replacementOffset.isEqualTo(value.requestOffset - left);
+    replacementLength.isEqualTo(left + right);
+  }
 }
 
 extension CompletionSuggestionExtension
@@ -113,6 +140,23 @@
     );
   }
 
+  void get isField {
+    kind.isIdentifier;
+    element.isNotNull.kind.isField;
+  }
+
+  void get isParameter {
+    kind.isIdentifier;
+    element.isNotNull.kind.isParameter;
+  }
+
+  CheckTarget<CompletionSuggestionKind> get kind {
+    return nest(
+      value.suggestion.kind,
+      (selected) => 'has kind ${valueStr(selected)}',
+    );
+  }
+
   CheckTarget<String?> get parameterType {
     return nest(
       value.suggestion.parameterType,
@@ -136,6 +180,13 @@
     );
   }
 
+  CheckTarget<String?> get returnType {
+    return nest(
+      value.suggestion.returnType,
+      (selected) => 'has returnType ${valueStr(selected)}',
+    );
+  }
+
   CheckTarget<int> get selectionLength {
     return nest(
       value.suggestion.selectionLength,
@@ -169,8 +220,22 @@
   }
 }
 
+extension CompletionSuggestionKindExtension
+    on CheckTarget<CompletionSuggestionKind> {
+  void get isIdentifier {
+    isEqualTo(CompletionSuggestionKind.IDENTIFIER);
+  }
+}
+
 extension CompletionSuggestionsExtension
     on CheckTarget<Iterable<CompletionSuggestionForTesting>> {
+  CheckTarget<List<String>> get completions {
+    return nest(
+      value.map((e) => e.suggestion.completion).toList(),
+      (selected) => 'completions ${valueStr(selected)}',
+    );
+  }
+
   CheckTarget<Iterable<CompletionSuggestionForTesting>> get namedArguments {
     var result = value
         .where((suggestion) =>
@@ -185,10 +250,6 @@
 }
 
 extension ElementExtension on CheckTarget<Element> {
-  void get isParameter {
-    kind.isEqualTo(ElementKind.PARAMETER);
-  }
-
   CheckTarget<ElementKind> get kind {
     return nest(
       value.kind,
@@ -203,3 +264,13 @@
     );
   }
 }
+
+extension ElementKindExtension on CheckTarget<ElementKind> {
+  void get isField {
+    isEqualTo(ElementKind.FIELD);
+  }
+
+  void get isParameter {
+    isEqualTo(ElementKind.PARAMETER);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
index ff209f1..d63a695 100644
--- a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
@@ -6,9 +6,10 @@
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:test/test.dart';
+import 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'completion_check.dart';
 import 'completion_contributor_util.dart';
 
 void main() {
@@ -31,183 +32,120 @@
   Future<void> test_mixin_constructor() async {
     addTestSource('''
 mixin M {
+  var field = 0;
   M(this.^);
 }
 ''');
-    await computeSuggestions();
-    expect(suggestions, isEmpty);
+
+    var response = await computeSuggestions2();
+    check(response).suggestions.isEmpty;
   }
 
-  Future<void> test_ThisExpression_constructor_param() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+  Future<void> test_replacement_left() async {
     addTestSource('''
-        main() { }
-        class I {X get f => new A();get _g => new A();}
-        class A implements I {
-          A(this.^) {}
-          A.z() {}
-          var b; X _c; static sb;
-          X get d => new A();get _e => new A();
-          // no semicolon between completion point and next statement
-          set s1(I x) {} set _s2(I x) {m(null);}
-          m(X x) {} I _n(X x) {}}
-        class X{}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('b', null);
-    assertSuggestField('_c', 'X');
-    assertNotSuggested('sb');
-    assertNotSuggested('d');
-    assertNotSuggested('_e');
-    assertNotSuggested('f');
-    assertNotSuggested('_g');
-    assertNotSuggested('m');
-    assertNotSuggested('_n');
-    assertNotSuggested('s1');
-    assertNotSuggested('_s2');
-    assertNotSuggested('z');
-    assertNotSuggested('I');
-    assertNotSuggested('A');
-    assertNotSuggested('X');
-    assertNotSuggested('Object');
-    assertNotSuggested('==');
+class A {
+  var field = 0;
+  A(this.f^);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasReplacement(left: 1)
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('field')
+          ..isField
+          ..returnType.isEqualTo('int'),
+      ]);
   }
 
-  Future<void> test_ThisExpression_constructor_param2() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+  Future<void> test_replacement_right() async {
     addTestSource('''
-        main() { }
-        class I {X get f => new A();get _g => new A();}
-        class A implements I {
-          A(this.b^) {}
-          A.z() {}
-          var b; X _c;
-          X get d => new A();get _e => new A();
-          // no semicolon between completion point and next statement
-          set s1(I x) {} set _s2(I x) {m(null);}
-          m(X x) {} I _n(X x) {}}
-        class X{}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
-    expect(replacementLength, 1);
-    assertSuggestField('b', null);
-    assertSuggestField('_c', 'X');
-    assertNotSuggested('d');
-    assertNotSuggested('_e');
-    assertNotSuggested('f');
-    assertNotSuggested('_g');
-    assertNotSuggested('m');
-    assertNotSuggested('_n');
-    assertNotSuggested('s1');
-    assertNotSuggested('_s2');
-    assertNotSuggested('z');
-    assertNotSuggested('I');
-    assertNotSuggested('A');
-    assertNotSuggested('X');
-    assertNotSuggested('Object');
-    assertNotSuggested('==');
+class A {
+  var field = 0;
+  A(this.^f);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasReplacement(right: 1)
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('field')
+          ..isField
+          ..returnType.isEqualTo('int'),
+      ]);
   }
 
-  Future<void> test_ThisExpression_constructor_param3() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+  Future<void> test_suggestions_onlyLocal() async {
     addTestSource('''
-        main() { }
-        class I {X get f => new A();get _g => new A();}
-        class A implements I {
-          A(this.^b) {}
-          A.z() {}
-          var b; X _c;
-          X get d => new A();get _e => new A();
-          // no semicolon between completion point and next statement
-          set s1(I x) {} set _s2(I x) {m(null);}
-          m(X x) {} I _n(X x) {}}
-        class X{}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 1);
-    assertSuggestField('b', null);
-    assertSuggestField('_c', 'X');
-    assertNotSuggested('d');
-    assertNotSuggested('_e');
-    assertNotSuggested('f');
-    assertNotSuggested('_g');
-    assertNotSuggested('m');
-    assertNotSuggested('_n');
-    assertNotSuggested('s1');
-    assertNotSuggested('_s2');
-    assertNotSuggested('z');
-    assertNotSuggested('I');
-    assertNotSuggested('A');
-    assertNotSuggested('X');
-    assertNotSuggested('Object');
-    assertNotSuggested('==');
+class A {
+  var inherited = 0;
+}
+
+class B extends A {
+  var first = 0;
+  var second = 1.2;
+  B(this.^);
+  B.constructor() {}
+  void method() {}
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isField
+          ..returnType.isEqualTo('int'),
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isField
+          ..returnType.isEqualTo('double'),
+      ]);
   }
 
-  Future<void> test_ThisExpression_constructor_param4() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+  Future<void> test_suggestions_onlyNotSpecified_optionalNamed() async {
     addTestSource('''
-        main() { }
-        class I {X get f => new A();get _g => new A();}
-        class A implements I {
-          A(this.b, this.^) {}
-          A.z() {}
-          var b; X _c;
-          X get d => new A();get _e => new A();
-          // no semicolon between completion point and next statement
-          set s1(I x) {} set _s2(I x) {m(null);}
-          m(X x) {} I _n(X x) {}}
-        class X{}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('b');
-    assertSuggestField('_c', 'X');
-    assertNotSuggested('d');
-    assertNotSuggested('_e');
-    assertNotSuggested('f');
-    assertNotSuggested('_g');
-    assertNotSuggested('m');
-    assertNotSuggested('_n');
-    assertNotSuggested('s1');
-    assertNotSuggested('_s2');
-    assertNotSuggested('z');
-    assertNotSuggested('I');
-    assertNotSuggested('A');
-    assertNotSuggested('X');
-    assertNotSuggested('Object');
-    assertNotSuggested('==');
+class Point {
+  final int x;
+  final int y;
+  Point({this.x, this.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('y')
+          ..isField
+          ..returnType.isEqualTo('int'),
+      ]);
   }
 
-  Future<void> test_ThisExpression_constructor_param_optional() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+  Future<void> test_suggestions_onlyNotSpecified_requiredPositional() async {
     addTestSource('''
-        main() { }
-        class Point {
-          int x;
-          int y;
-          Point({this.x, this.^}) {}
-          ''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('y', 'int');
-    assertNotSuggested('x');
-  }
+class Point {
+  final int x;
+  final int y;
+  Point(this.x, this.^);
+}
+''');
 
-  Future<void> test_ThisExpression_constructor_param_positional() async {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-        main() { }
-        class Point {
-          int x;
-          int y;
-          Point({this.x, this.^}) {}
-          ''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('y', 'int');
-    assertNotSuggested('x');
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('y')
+          ..isField
+          ..returnType.isEqualTo('int'),
+      ]);
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 585012d..c2c05ab 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -74,6 +74,17 @@
     var keywords = <Keyword>[
       Keyword.COVARIANT,
       Keyword.DYNAMIC,
+      Keyword.SUPER,
+      Keyword.THIS,
+      Keyword.VOID
+    ];
+    return keywords;
+  }
+
+  List<Keyword> get constructorParameter_language215 {
+    var keywords = <Keyword>[
+      Keyword.COVARIANT,
+      Keyword.DYNAMIC,
       Keyword.THIS,
       Keyword.VOID
     ];
@@ -1018,6 +1029,17 @@
     assertSuggestKeywords(constructorParameter);
   }
 
+  Future<void> test_constructor_param_noPrefix_language215() async {
+    addTestSource(r'''
+// @dart = 2.15
+class A {
+  A(^);
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(constructorParameter_language215);
+  }
+
   Future<void> test_constructor_param_prefix() async {
     addTestSource('class A { A(t^) {}}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/super_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/super_formal_contributor_test.dart
new file mode 100644
index 0000000..ff135e7
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/super_formal_contributor_test.dart
@@ -0,0 +1,471 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/dart/super_formal_contributor.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_check.dart';
+import 'completion_contributor_util.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SuperFormalContributorTest);
+  });
+}
+
+@reflectiveTest
+class SuperFormalContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor(
+    DartCompletionRequest request,
+    SuggestionBuilder builder,
+  ) {
+    return SuperFormalContributor(request, builder);
+  }
+
+  Future<void> test_explicit_optionalNamed_hasArgument_named() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({super.^}) : super(first: 0);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_explicit_optionalNamed_hasArgument_positional() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({super.^}) : super(0);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  /// It is an error, but the user already typed `super.`, so maybe do it.
+  Future<void> test_explicit_requiredPositional_hasArgument_positional() async {
+    addTestSource('''
+class A {
+  A(int first, double second);
+}
+
+class B extends A {
+  B(super.^) : super(0);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_explicitNamed_noOther() async {
+    addTestSource('''
+class A {
+  A.named(int first, double second);
+  A(int third)
+}
+
+class B extends A {
+  B(super.^) : super.named();
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasNamed_notSuper() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({int a, super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasNamed_notSuper2() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({int first, super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasNamed_super() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({super.first, super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasNamed_super2() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B({super.second, super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasPositional_notSuper() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B(int a, {super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_hasPositional_super() async {
+    addTestSource('''
+class A {
+  A({int first, double second});
+}
+
+class B extends A {
+  B(super.first, {super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalNamed_noOther() async {
+    addTestSource('''
+class A {
+  A(bool first, {int second, double third});
+}
+
+class B extends A {
+  B({super.^});
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+        (suggestion) => suggestion
+          ..completion.isEqualTo('third')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalPositional_hasPositional_notSuper() async {
+    addTestSource('''
+class A {
+  A([int first, double second]);
+}
+
+class B extends A {
+  B([int one, super.^]);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalPositional_hasPositional_super() async {
+    addTestSource('''
+class A {
+  A([int first, double second, bool third]);
+}
+
+class B extends A {
+  B([super.one, super.^]);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalPositional_hasPositional_super2() async {
+    addTestSource('''
+class A {
+  A([int first, double second, bool third]);
+}
+
+class B extends A {
+  B([super.second, super.^]);
+}
+''');
+
+    // It does not matter what is the name of the positional parameter.
+    // Here `super.second` consumes `int first`.
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_optionalPositional_noOther() async {
+    addTestSource('''
+class A {
+  A([int first, double second]);
+}
+
+class B extends A {
+  B(super.^);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_implicit_requiredPositional_hasPositional_notSuper() async {
+    addTestSource('''
+class A {
+  A(int first, double second);
+}
+
+class B extends A {
+  B(int one, super.^);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+
+  Future<void> test_implicit_requiredPositional_hasPositional_super() async {
+    addTestSource('''
+class A {
+  A(int first, double second, bool third);
+}
+
+class B extends A {
+  B(super.one, super.^);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_requiredPositional_hasPositional_super2() async {
+    addTestSource('''
+class A {
+  A(int first, double second, bool third);
+}
+
+class B extends A {
+  B(super.second, super.^);
+}
+''');
+
+    // It does not matter what is the name of the positional parameter.
+    // Here `super.second` consumes `int first`.
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('second')
+          ..isParameter
+          ..returnType.isEqualTo('double'),
+      ]);
+  }
+
+  Future<void> test_implicit_requiredPositional_noOther() async {
+    addTestSource('''
+class A {
+  A(int first, double second);
+  A.named(int third)
+}
+
+class B extends A {
+  B(super.^);
+}
+''');
+
+    var response = await computeSuggestions2();
+    check(response)
+      ..hasEmptyReplacement()
+      ..suggestions.matchesInAnyOrder([
+        (suggestion) => suggestion
+          ..completion.isEqualTo('first')
+          ..isParameter
+          ..returnType.isEqualTo('int'),
+      ]);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 4ed7cd0..384422b 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -21,6 +21,7 @@
 import 'override_contributor_test.dart' as override_contributor_test;
 import 'relevance/test_all.dart' as relevance_tests;
 import 'static_member_contributor_test.dart' as static_contributor_test;
+import 'super_formal_contributor_test.dart' as super_formal_contributor;
 import 'type_member_contributor_test.dart' as type_member_contributor_test;
 import 'uri_contributor_test.dart' as uri_contributor_test;
 import 'variable_name_contributor_test.dart' as variable_name_contributor_test;
@@ -44,6 +45,7 @@
     override_contributor_test.main();
     relevance_tests.main();
     static_contributor_test.main();
+    super_formal_contributor.main();
     type_member_contributor_test.main();
     uri_contributor_test.main();
     variable_name_contributor_test.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
index ce129cc..42c321b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
@@ -11,11 +11,25 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AddSuperConstructorInvocationTest);
+    defineReflectiveTests(AddSuperConstructorInvocationTest_language215);
   });
 }
 
 @reflectiveTest
-class AddSuperConstructorInvocationTest extends FixProcessorTest {
+class AddSuperConstructorInvocationTest extends FixProcessorTest
+    with AddSuperConstructorInvocationTestCases {}
+
+@reflectiveTest
+class AddSuperConstructorInvocationTest_language215 extends FixProcessorTest
+    with AddSuperConstructorInvocationTestCases {
+  @override
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfig(languageVersion: '2.15');
+  }
+}
+
+mixin AddSuperConstructorInvocationTestCases on FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION;
 
@@ -71,7 +85,26 @@
     await assertNoFix();
   }
 
-  Future<void> test_requiredAndNamed() async {
+  Future<void> test_typeArgument() async {
+    await resolveTestCode('''
+class A<T> {
+  A(T p);
+}
+class B extends A<int> {
+  B();
+}
+''');
+    await assertHasFix('''
+class A<T> {
+  A(T p);
+}
+class B extends A<int> {
+  B() : super(0);
+}
+''');
+  }
+
+  Future<void> test_unnamed_requiredAndNamed() async {
     await resolveTestCode('''
 class A {
   A(bool p1, int p2, double p3, String p4, {p5});
@@ -90,21 +123,24 @@
 ''');
   }
 
-  Future<void> test_typeArgument() async {
+  @FailingTest(
+    reason: 'Generates positional arguments instead of named',
+  )
+  Future<void> test_unnamed_requiredNamed() async {
     await resolveTestCode('''
-class A<T> {
-  A(T p);
+class A {
+  A({required int p1});
 }
-class B extends A<int> {
+class B extends A {
   B();
 }
 ''');
     await assertHasFix('''
-class A<T> {
-  A(T p);
+class A {
+  A({required int p1});
 }
-class B extends A<int> {
-  B() : super(0);
+class B extends A {
+  B() : super(p1: 0);
 }
 ''');
   }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index eabe7ee..d666d5c 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1745,6 +1745,32 @@
   String? get defaultValueCode {
     return constantInitializer?.toSource();
   }
+
+  @override
+  bool get hasDefaultValue {
+    if (super.hasDefaultValue) {
+      return true;
+    }
+    return computeConstantValue() != null;
+  }
+
+  @override
+  DartObject? computeConstantValue() {
+    if (constantInitializer != null) {
+      return super.computeConstantValue();
+    }
+
+    var superDefault = superConstructorParameter?.computeConstantValue();
+    var superDefaultType = superDefault?.type;
+    var libraryElement = library;
+    if (superDefaultType != null &&
+        libraryElement != null &&
+        libraryElement.typeSystem.isSubtypeOf(superDefaultType, type)) {
+      return superDefault;
+    }
+
+    return null;
+  }
 }
 
 /// The synthetic element representing the declaration of the type `dynamic`.
@@ -5485,12 +5511,9 @@
           return superParameters
               .firstWhereOrNull((e) => e.isNamed && e.name == name);
         } else {
+          var index = indexIn(enclosingElement);
           var positionalSuperParameters =
               superParameters.where((e) => e.isPositional).toList();
-          var index = enclosingElement.parameters
-              .whereType<SuperFormalParameterElementImpl>()
-              .toList()
-              .indexOf(this);
           if (index >= 0 && index < positionalSuperParameters.length) {
             return positionalSuperParameters[index];
           }
@@ -5503,6 +5526,14 @@
   @override
   T? accept<T>(ElementVisitor<T> visitor) =>
       visitor.visitSuperFormalParameterElement(this);
+
+  /// Return the index of this super-formal parameter among other super-formals.
+  int indexIn(ConstructorElementImpl enclosingElement) {
+    return enclosingElement.parameters
+        .whereType<SuperFormalParameterElementImpl>()
+        .toList()
+        .indexOf(this);
+  }
 }
 
 /// A concrete implementation of a [TopLevelVariableElement].
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 8138fda..c6522fb 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -348,13 +348,13 @@
           name: name,
           nameOffset: nameOffset,
           parameterKind: node.kind,
-        );
+        )..constantInitializer = node.defaultValue;
       } else {
         element = DefaultParameterElementImpl(
           name: name,
           nameOffset: nameOffset,
           parameterKind: node.kind,
-        );
+        )..constantInitializer = node.defaultValue;
       }
       _elementHolder.addParameter(element);
 
@@ -383,7 +383,6 @@
           defaultValue.accept(this);
         });
       });
-      element.defaultValueCode = defaultValue.toSource();
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 78bd179..2582044 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4939,23 +4939,25 @@
               parameterName ?? parameter,
             );
           }
-        } else if (defaultValuesAreExpected && parameter.defaultValue == null) {
+        } else if (defaultValuesAreExpected) {
           var parameterElement = parameter.declaredElement!;
-          var type = parameterElement.type;
-          if (typeSystem.isPotentiallyNonNullable(type)) {
-            var parameterName = _parameterName(parameter);
-            if (parameterElement.hasRequired) {
-              errorReporter.reportErrorForNode(
-                CompileTimeErrorCode
-                    .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
-                parameterName ?? parameter,
-              );
-            } else {
-              errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
-                parameterName ?? parameter,
-                [parameterName?.name ?? '?'],
-              );
+          if (!parameterElement.hasDefaultValue) {
+            var type = parameterElement.type;
+            if (typeSystem.isPotentiallyNonNullable(type)) {
+              var parameterName = _parameterName(parameter);
+              if (parameterElement.hasRequired) {
+                errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode
+                      .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
+                  parameterName ?? parameter,
+                );
+              } else {
+                errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
+                  parameterName ?? parameter,
+                  [parameterName?.name ?? '?'],
+                );
+              }
             }
           }
         }
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index 0656a4b..4dc5158 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -17,6 +17,34 @@
 
 @reflectiveTest
 class MissingDefaultValueForParameterTest extends PubPackageResolutionTest {
+  test_closure_nonNullable_named_optional_default() async {
+    await assertNoErrorsInCode('''
+var f = ({int a = 0}) {};
+''');
+  }
+
+  test_closure_nonNullable_named_optional_noDefault() async {
+    await assertErrorsInCode('''
+var f = ({int a}) {};
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 14, 1),
+    ]);
+  }
+
+  test_closure_nonNullable_positional_optional_default() async {
+    await assertNoErrorsInCode('''
+var f = ([int a = 0]) {};
+''');
+  }
+
+  test_closure_nonNullable_positional_optional_noDefault() async {
+    await assertErrorsInCode('''
+var f = ([int a]) {};
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 14, 1),
+    ]);
+  }
+
   test_constructor_externalFactory_nonNullable_named_optional_noDefault() async {
     await assertNoErrorsInCode('''
 class C {
@@ -82,6 +110,54 @@
     ]);
   }
 
+  test_constructor_generative_nonNullable_named_optional_super_hasDefault_explicit() async {
+    await assertNoErrorsInCode('''
+class A {
+  A({required int a});
+}
+class B extends A{
+  B({super.a = 0});
+}
+''');
+  }
+
+  test_constructor_generative_nonNullable_named_optional_super_hasDefault_fromSuper() async {
+    await assertNoErrorsInCode('''
+class A {
+  A({int a = 0});
+}
+class B extends A{
+  B({super.a});
+}
+''');
+  }
+
+  test_constructor_generative_nonNullable_named_optional_super_noDefault() async {
+    await assertErrorsInCode('''
+class A {
+  A({int? a});
+}
+class B extends A{
+  B({int super.a});
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 61, 1),
+    ]);
+  }
+
+  test_constructor_generative_nonNullable_named_optional_super_noDefault_fromSuper() async {
+    await assertErrorsInCode('''
+class A {
+  A({num a = 1.2});
+}
+class B extends A{
+  B({int super.a});
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 66, 1),
+    ]);
+  }
+
   test_constructor_generative_nonNullable_positional_optional_noDefault() async {
     await assertErrorsInCode('''
 class C {
@@ -92,6 +168,54 @@
     ]);
   }
 
+  test_constructor_generative_nonNullable_positional_optional_super_hasDefault_explicit() async {
+    await assertNoErrorsInCode('''
+class A {
+  A(int a);
+}
+class B extends A{
+  B([super.a = 0]);
+}
+''');
+  }
+
+  test_constructor_generative_nonNullable_positional_optional_super_hasDefault_fromSuper() async {
+    await assertNoErrorsInCode('''
+class A {
+  A([int a = 0]);
+}
+class B extends A{
+  B([super.a]);
+}
+''');
+  }
+
+  test_constructor_generative_nonNullable_positional_optional_super_noDefault() async {
+    await assertErrorsInCode('''
+class A {
+  A([int? a]);
+}
+class B extends A{
+  B([int super.a]);
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 61, 1),
+    ]);
+  }
+
+  test_constructor_generative_nonNullable_positional_optional_super_noDefault_fromSuper() async {
+    await assertErrorsInCode('''
+class A {
+  A([num a = 1.2]);
+}
+class B extends A{
+  B([int super.a]);
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 66, 1),
+    ]);
+  }
+
   test_constructor_generative_nullable_named_optional_noDefault() async {
     await assertNoErrorsInCode('''
 class C {
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
index 96f4683..1209c3f 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
@@ -54,6 +54,10 @@
   /// The relevance used when suggesting a named argument corresponding to a
   /// named parameter that is required.
   static const int requiredNamedArgument = 950;
+
+  /// The relevance used when suggesting a super-constructor parameter as
+  /// a super formal parameter.
+  static const int superFormalParameter = 1000;
 }
 
 /// A name scope for constants that are related to the relevance of completion
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index 1f3acb1..d4d536f 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -89,56 +89,50 @@
   return f().then(asyncSuccess);
 }
 
-bool _pass(dynamic object) => true;
-
-/// Calls [f] and verifies that it throws a `T`.
+/// Verifies that the asyncronous [result] throws a [T].
 ///
-/// The optional [check] function can provide additional validation that the
-/// correct object is being thrown. For example, to check the content of the
-/// thrown object you could write this:
+/// Fails if [result] completes with a value, or it completes with
+/// an error which is not a [T].
 ///
-///     asyncExpectThrows<MyException>(myThrowingFunction,
-///          (e) => e.myMessage.contains("WARNING"));
-///
-/// If `f` fails an expectation (i.e., throws an [ExpectException]), that
-/// exception is not caught by [asyncExpectThrows]. The test is still considered
-/// failing.
-void asyncExpectThrows<T>(Future<void> f(),
-    [bool check(T error) = _pass, String reason = ""]) {
-  var type = "";
-  if (T != dynamic && T != Object) type = "<$T>";
+/// Returns the accepted thrown object.
+/// For example, to check the content of the thrown object,
+/// you could write this:
+/// ```
+/// var e = await asyncExpectThrows<MyException>(asyncExpression)
+/// Expect.isTrue(e.myMessage.contains("WARNING"));
+/// ```
+/// If `result` completes with an [ExpectException] error from another
+/// failed test expectation, that error cannot be caught and accepted.
+Future<T> asyncExpectThrows<T extends Object>(Future<void> result,
+    [String reason = ""]) {
   // Handle null being passed in from legacy code while also avoiding producing
   // an unnecessary null check warning here.
   if ((reason as dynamic) == null) reason = "";
+
+  var type = "";
+  if (T != dynamic && T != Object) type = "<$T>";
   var header = "asyncExpectThrows$type(${reason}):";
 
+  if ((result as dynamic) == null) {
+    Expect.testError("$header result Future must not be null.");
+  }
   // TODO(rnystrom): It might useful to validate that T is not bound to
   // ExpectException since that won't work.
 
-  if (f is! Function()) {
-    // Only throws from executing the function body should count as throwing.
-    // The failure to even call `f` should throw outside the try/catch.
-    Expect.testError("$header Function not callable with zero arguments.");
-  }
-
-  var result = f();
-  if (result is! Future) {
-    Expect.testError("$header Function did not return a Future.");
-  }
-
   asyncStart();
-  result.then<Null>((_) {
+  return result.then<T>((_) {
     throw ExpectException("$header Did not throw.");
-  }).catchError((error, stack) {
+  }, onError: (error, stack) {
     // A test failure doesn't count as throwing.
     if (error is ExpectException) throw error;
 
-    if (error is! T || (check != null && !check(error))) {
+    if (error is! T) {
       // Throws something unexpected.
       throw ExpectException(
           "$header Unexpected '${Error.safeToString(error)}'\n$stack");
     }
 
     asyncEnd();
+    return error;
   });
 }
diff --git a/pkg/async_helper/lib/async_minitest.dart b/pkg/async_helper/lib/async_minitest.dart
index fa5d319..5b58930 100644
--- a/pkg/async_helper/lib/async_minitest.dart
+++ b/pkg/async_helper/lib/async_minitest.dart
@@ -215,14 +215,14 @@
   Expect.isNull(o);
 }
 
-void _checkThrow<T>(dynamic v, void onError(error)) {
+void _checkThrow<T extends Object>(dynamic v, void onError(error)) {
   if (v is Future) {
     asyncStart();
     v.then((_) {
       Expect.fail("Did not throw");
     }, onError: (e, s) {
       if (e is! T) throw e;
-      if (onError != null) onError(e);
+      onError(e);
       asyncEnd();
     });
     return;
diff --git a/pkg/compiler/test/inference/data/call_site.dart b/pkg/compiler/test/inference/data/call_site.dart
index 6cc8406..16f18e0 100644
--- a/pkg/compiler/test/inference/data/call_site.dart
+++ b/pkg/compiler/test/inference/data/call_site.dart
@@ -112,7 +112,7 @@
 /*member: A8.:[exact=A8]*/
 class A8 {
   /*member: A8.x8:[empty]*/
-  x8(/*Union([exact=JSString], [subclass=JsLinkedHashMap])*/ p) =>
+  x8(/*Union([exact=JSString], [exact=JsLinkedHashMap])*/ p) =>
       /*invoke: [exact=A8]*/ x8("x");
 }
 
@@ -126,7 +126,7 @@
   /*member: A9.x9:[empty]*/ x9(
           /*[exact=JSUInt31]*/ p1,
           /*Union([exact=JSString], [exact=JSUInt31])*/ p2,
-          /*Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ p3) =>
+          /*Union([exact=JSUInt31], [exact=JsLinkedHashMap])*/ p3) =>
       /*invoke: [exact=A9]*/ x9(p1, "x", {});
 }
 
diff --git a/pkg/compiler/test/inference/data/closure2.dart b/pkg/compiler/test/inference/data/closure2.dart
index 793c24c..a3c5e37 100644
--- a/pkg/compiler/test/inference/data/closure2.dart
+++ b/pkg/compiler/test/inference/data/closure2.dart
@@ -14,7 +14,7 @@
   return a;
 }
 
-/*member: returnDyn1:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn1:Union([exact=JSUInt31], [exact=JsLinkedHashMap])*/
 returnDyn1() {
   dynamic a = 42;
   // ignore: unused_local_variable
@@ -34,7 +34,7 @@
   return a;
 }
 
-/*member: returnDyn2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn2:Union([exact=JSUInt31], [exact=JsLinkedHashMap])*/
 returnDyn2() {
   dynamic a = 42;
   // ignore: unused_local_variable
@@ -60,10 +60,10 @@
   return a;
 }
 
-/*member: returnDyn3:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn3:Union([exact=JSUInt31], [exact=JsLinkedHashMap])*/
 returnDyn3() {
   dynamic a = 42;
-  if (a /*invoke: Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ == 53) {
+  if (a /*invoke: Union([exact=JSUInt31], [exact=JsLinkedHashMap])*/ == 53) {
     // ignore: unused_local_variable
     var f = /*[null]*/ () {
       a = {};
diff --git a/pkg/compiler/test/inference/data/closure_tracer.dart b/pkg/compiler/test/inference/data/closure_tracer.dart
index e689520..6353470 100644
--- a/pkg/compiler/test/inference/data/closure_tracer.dart
+++ b/pkg/compiler/test/inference/data/closure_tracer.dart
@@ -59,11 +59,11 @@
   dynamic b = <dynamic, dynamic>{'foo': 1};
 
   b
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
       ['bar'] = a;
 
   b
-          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
+          /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
           ['bar']
 
       /*Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)*/
diff --git a/pkg/compiler/test/inference/data/dictionary_types.dart b/pkg/compiler/test/inference/data/dictionary_types.dart
index 61c0072..e8a191a 100644
--- a/pkg/compiler/test/inference/data/dictionary_types.dart
+++ b/pkg/compiler/test/inference/data/dictionary_types.dart
@@ -13,7 +13,7 @@
   test5();
 }
 
-/*member: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dictionaryA1:Map([exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 dynamic dictionaryA1 = {
   'string': "aString",
   'int': 42,
@@ -21,7 +21,7 @@
   'list': []
 };
 
-/*member: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+/*member: dictionaryB1:Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
 dynamic dictionaryB1 = {
   'string': "aString",
   'int': 42,
@@ -29,7 +29,7 @@
   'list': []
 };
 
-/*member: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
+/*member: otherDict1:Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
 dynamic otherDict1 = {'stringTwo': "anotherString", 'intTwo': 84};
 
 /*member: int1:[exact=JSUInt31]*/
@@ -47,26 +47,26 @@
 /*member: test1:[null]*/
 test1() {
   dictionaryA1
-      . /*invoke: Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+      . /*invoke: Map([exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
       addAll(otherDict1);
   dictionaryB1
-      . /*invoke: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+      . /*invoke: Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
       addAll({'stringTwo': "anotherString", 'intTwo': 84});
   int1 = dictionaryB1
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
       ['int'];
   anotherInt1 = otherDict1
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
       ['intTwo'];
   dynamic1 =
-      dictionaryA1 /*Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/ [
+      dictionaryA1 /*Map([exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/ [
           'int'];
   nullOrInt1 = dictionaryB1
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
       ['intTwo'];
 }
 
-/*member: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryA2:Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionaryA2 = {
   'string': "aString",
   'int': 42,
@@ -74,7 +74,7 @@
   'list': []
 };
 
-/*member: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryB2:Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionaryB2 = {'string': "aString", 'intTwo': 42, 'list': []};
 
 /*member: nullOrInt2:[null|exact=JSUInt31]*/
@@ -89,22 +89,22 @@
 /*member: test2:[null]*/
 test2() {
   var union = dictionaryA2
-          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+          /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
           ['foo']
       ? dictionaryA2
       : dictionaryB2;
   nullOrInt2 = union
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
       ['intTwo'];
   aString2 = union
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
       ['string'];
   doubleOrNull2 = union
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSNumNotInt], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
       ['double'];
 }
 
-/*member: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionary3:Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionary3 = {
   'string': "aString",
   'int': 42,
@@ -125,18 +125,18 @@
 
 /*member: intOrNull3:[null|exact=JSUInt31]*/
 dynamic intOrNull3 = dictionary3
-    /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+    /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
     [keyI3];
 
 /*member: justNull3:[null]*/
 dynamic justNull3 = dictionary3
-    /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+    /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
     [keyN3];
 
 /*member: test3:[null]*/
 test3() {
   knownDouble3 = dictionary3
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt], [exact=JSString], [exact=JSUInt31]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSNumNotInt], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
       [keyD3];
   // ignore: unused_local_variable
   var x = [intOrNull3, justNull3];
@@ -147,8 +147,8 @@
   A4();
 /*member: A4.foo4:[exact=JSUInt31]*/
   foo4(
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
-    return value /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ [
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
+    return value /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ [
         'anInt'];
   }
 }
@@ -159,7 +159,7 @@
 
 /*member: B4.foo4:[exact=JSUInt31]*/
   foo4(
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSString], [exact=JSUInt31]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
     return 0;
   }
 }
@@ -180,7 +180,7 @@
       2);
 }
 
-/*member: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dict5:Map([null|exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 dynamic dict5 = makeMap5([1, 2]);
 
 /*member: notInt5:[null|subclass=Object]*/
@@ -189,7 +189,7 @@
 /*member: alsoNotInt5:[null|subclass=Object]*/
 dynamic alsoNotInt5 = 0;
 
-/*member: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: makeMap5:Map([exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 makeMap5(
     /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/ values) {
   return {
@@ -205,14 +205,14 @@
 /*member: test5:[null]*/
 test5() {
   dict5
-      /*update: Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+      /*update: Map([null|exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
       ['goo'] = 42;
   var closure =
-      /*Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+      /*Map([null|exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
       () => dict5;
   notInt5 = closure()['boo'];
   alsoNotInt5 = dict5
-      /*Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+      /*Map([null|exact=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
       ['goo'];
   print("$notInt5 and $alsoNotInt5.");
 }
diff --git a/pkg/compiler/test/inference/data/index.dart b/pkg/compiler/test/inference/data/index.dart
index 4a00271..c05e292 100644
--- a/pkg/compiler/test/inference/data/index.dart
+++ b/pkg/compiler/test/inference/data/index.dart
@@ -60,7 +60,7 @@
 mapLookupSingle() {
   var map = {0: 1};
   return map
-      /*Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [0];
 }
 
@@ -72,7 +72,7 @@
 mapLookupMultiple() {
   var map = {0: 1, 2: 3, 4: 5};
   return map
-      /*Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [2];
 }
 
@@ -84,7 +84,7 @@
 mapLookupMissing() {
   var map = {0: 1};
   return map
-      /*Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [2];
 }
 
@@ -96,7 +96,7 @@
 mapLookupMixedKeys() {
   var map = {0: 1, '': 2};
   return map
-      /*Map([subclass=JsLinkedHashMap], key: Union([exact=JSString], [exact=JSUInt31]), value: [null|exact=JSUInt31])*/
+      /*Map([exact=JsLinkedHashMap], key: Union([exact=JSString], [exact=JSUInt31]), value: [null|exact=JSUInt31])*/
       [''];
 }
 
@@ -108,7 +108,7 @@
 mapLookupMixedValues() {
   var map = {0: 1, 2: ''};
   return map
-      /*Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: Union(null, [exact=JSString], [exact=JSUInt31]))*/
+      /*Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: Union(null, [exact=JSString], [exact=JSUInt31]))*/
       [2];
 }
 
@@ -120,7 +120,7 @@
 dictionaryLookupSingle() {
   var map = {'foo': 'bar'};
   return map
-      /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([exact=JSString], value: "bar")})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([exact=JSString], value: "bar")})*/
       ['foo'];
 }
 
@@ -132,7 +132,7 @@
 dictionaryLookupMultiple() {
   var map = {'foo': 'bar', 'baz': 'boz'};
   return map
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([exact=JSString], value: "boz")})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([exact=JSString], value: "boz")})*/
       ['baz'];
 }
 
@@ -144,7 +144,7 @@
 dictionaryLookupMissing() {
   var map = {'foo': 'bar', 'baz': 'boz'};
   return map
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([exact=JSString], value: "boz")})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([exact=JSString], value: "boz")})*/
       ['unknown'];
 }
 
@@ -156,7 +156,7 @@
 intDictionaryLookupSingle() {
   var map = {'foo': 0};
   return map
-      /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSUInt31], map: {foo: [exact=JSUInt31]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSUInt31], map: {foo: [exact=JSUInt31]})*/
       ['foo'];
 }
 
diff --git a/pkg/compiler/test/inference/data/index_call.dart b/pkg/compiler/test/inference/data/index_call.dart
index 4454632..d563df2 100644
--- a/pkg/compiler/test/inference/data/index_call.dart
+++ b/pkg/compiler/test/inference/data/index_call.dart
@@ -63,9 +63,9 @@
   var a = {
     'a': {'b': 0}
   };
-  return a /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Dictionary([null|subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]}), map: {a: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]})})*/
+  return a /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Dictionary([null|exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]}), map: {a: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]})})*/
               ['a']
-          /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]})*/
+          /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|exact=JSUInt31], map: {b: [exact=JSUInt31]})*/
           ['b']
       . /*invoke: [exact=JSUInt31]*/
       abs();
@@ -77,9 +77,9 @@
   var a = {
     'a': {'b': closure}
   };
-  return a /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Dictionary([null|subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]}), map: {a: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]})})*/
+  return a /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Dictionary([null|exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]}), map: {a: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]})})*/
           ['a']
-      /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "b"), value: [null|subclass=Closure], map: {b: [subclass=Closure]})*/
       ['b'](d: 0);
 }
 
@@ -89,7 +89,7 @@
   var a = {
     'a': [closure]
   };
-  return a /*Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1), map: {a: Container([exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
+  return a /*Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "a"), value: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1), map: {a: Container([exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
           ['a']
       /*Container([exact=JSExtendableArray], element: [subclass=Closure], length: 1)*/
       [0](d: 0);
diff --git a/pkg/compiler/test/inference/data/index_set.dart b/pkg/compiler/test/inference/data/index_set.dart
index 883962c..c383f3f 100644
--- a/pkg/compiler/test/inference/data/index_set.dart
+++ b/pkg/compiler/test/inference/data/index_set.dart
@@ -60,7 +60,7 @@
 mapUpdateEmpty() {
   var map = {};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [0] = 42;
 }
 
@@ -72,7 +72,7 @@
 mapUpdateSingle() {
   var map = {0: 1};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [0] = 42;
 }
 
@@ -84,7 +84,7 @@
 mapUpdateMultiple() {
   var map = {0: 1, 2: 3, 4: 5};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [2] = 42;
 }
 
@@ -96,7 +96,7 @@
 mapUpdateMissing() {
   var map = {0: 1};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSUInt31])*/
       [2] = 42;
 }
 
@@ -108,7 +108,7 @@
 mapUpdateMixedKeys() {
   dynamic map = {'': 2};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: Union([exact=JSString], [exact=JSUInt31]), value: [null|exact=JSUInt31])*/
+      /*update: Map([exact=JsLinkedHashMap], key: Union([exact=JSString], [exact=JSUInt31]), value: [null|exact=JSUInt31])*/
       [0] = 42;
 }
 
@@ -120,7 +120,7 @@
 mapUpdateMixedValues() {
   dynamic map = {2: ''};
   return map
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: Union(null, [exact=JSString], [exact=JSUInt31]))*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSUInt31], value: Union(null, [exact=JSString], [exact=JSUInt31]))*/
       [2] = 42;
 }
 
@@ -132,7 +132,7 @@
 dictionaryUpdateEmpty() {
   var map = {};
   return map
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([null|exact=JSString], value: "bar")})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([null|exact=JSString], value: "bar")})*/
       ['foo'] = 'bar';
 }
 
@@ -144,7 +144,7 @@
 dictionaryUpdateSingle() {
   var map = {'foo': 'bar'};
   return map
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSString], map: {foo: [exact=JSString]})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSString], map: {foo: [exact=JSString]})*/
       ['foo'] = 'boz';
 }
 
@@ -156,7 +156,7 @@
 dictionaryReUpdateSingle() {
   var map = {'foo': 'bar'};
   return map
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([exact=JSString], value: "bar")})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: Value([null|exact=JSString], value: "bar"), map: {foo: Value([exact=JSString], value: "bar")})*/
       ['foo'] = 'bar';
 }
 
@@ -168,7 +168,7 @@
 dictionaryUpdateMultiple() {
   var map = {'foo': 'bar'};
   return map
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([null|exact=JSString], value: "boz")})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSString], map: {foo: Value([exact=JSString], value: "bar"), baz: Value([null|exact=JSString], value: "boz")})*/
       ['baz'] = 'boz';
 }
 
@@ -180,7 +180,7 @@
 intDictionaryUpdateSingle() {
   var map = {};
   return map
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSUInt31], map: {foo: [null|exact=JSUInt31]})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: Value([exact=JSString], value: "foo"), value: [null|exact=JSUInt31], map: {foo: [null|exact=JSUInt31]})*/
       ['foo'] = 0;
 }
 
diff --git a/pkg/compiler/test/inference/data/map_tracer_keys.dart b/pkg/compiler/test/inference/data/map_tracer_keys.dart
index beedfbf..1e70a9e 100644
--- a/pkg/compiler/test/inference/data/map_tracer_keys.dart
+++ b/pkg/compiler/test/inference/data/map_tracer_keys.dart
@@ -29,16 +29,16 @@
 test1() {
   var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
       ['d'] = 5.5;
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
       keys) {
     aDouble1 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
+        /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [null|exact=JSNumNotInt]})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
@@ -60,16 +60,16 @@
 test2() {
   dynamic theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
-      /*update: Map([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
+      /*update: Map([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
       [aList2] = 5.5;
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Map([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
+      /*Map([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
       keys) {
     aDouble2 = theMap
-        /*Map([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
+        /*Map([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt])*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
@@ -91,16 +91,16 @@
 test3() {
   dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
+      /*update: Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       ['d'] = aList3;
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       keys) {
     aDouble3 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
+        /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
@@ -125,10 +125,10 @@
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [exact=JSNumNotInt]})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [exact=JSNumNotInt]})*/
       keys) {
     aDouble4 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [exact=JSNumNotInt]})*/
+        /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSNumNotInt], map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: [exact=JSNumNotInt]})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
@@ -153,10 +153,10 @@
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSNumNotInt])*/
+      /*Map([exact=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSNumNotInt])*/
       keys) {
     aDouble5 = theMap
-        /*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSNumNotInt])*/
+        /*Map([exact=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSNumNotInt])*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
@@ -180,10 +180,10 @@
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
+      /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       keys) {
     aDouble6 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
+        /*Dictionary([exact=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSNumNotInt]), map: {a: [exact=JSNumNotInt], b: [exact=JSNumNotInt], c: [exact=JSNumNotInt], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
diff --git a/pkg/compiler/test/inference/data/no_such_method4.dart b/pkg/compiler/test/inference/data/no_such_method4.dart
index 0538869..2cd61c1 100644
--- a/pkg/compiler/test/inference/data/no_such_method4.dart
+++ b/pkg/compiler/test/inference/data/no_such_method4.dart
@@ -13,13 +13,13 @@
 
 /*member: B.:[exact=B]*/
 class B extends A {
-  /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+  /*member: B.foo:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
       {};
 }
 
 /*member: C.:[exact=C]*/
 class C extends B {
-  /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+  /*member: C.foo:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
       {};
 }
 
@@ -34,22 +34,22 @@
   return e. /*invoke: [exact=A]*/ foo();
 }
 
-/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test2() => a. /*invoke: [null|subclass=B]*/ foo();
 
-/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test3() => new B(). /*invoke: [exact=B]*/ foo();
 
-/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test4() => new C(). /*invoke: [exact=C]*/ foo();
 
-/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test5() {
   dynamic e = (a ? new A() : new B());
   return e. /*invoke: [subclass=A]*/ foo();
 }
 
-/*member: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test6:Dictionary([exact=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
 
 /*member: main:[null]*/
diff --git a/pkg/compiler/test/rti/data/map_literal.dart b/pkg/compiler/test/rti/data/map_literal.dart
index 1d91a1b..988f06e 100644
--- a/pkg/compiler/test/rti/data/map_literal.dart
+++ b/pkg/compiler/test/rti/data/map_literal.dart
@@ -11,7 +11,7 @@
 /*spec.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
 /*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
-/*spec.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap,JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*spec.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap,JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K],needsArgs*/
 
 /*prod.class: global#double:*/
 /*spec.class: global#double:implicit=[double]*/
diff --git a/pkg/compiler/test/rti/data/map_to_set.dart b/pkg/compiler/test/rti/data/map_to_set.dart
index 79f0f2a..4c870c3 100644
--- a/pkg/compiler/test/rti/data/map_to_set.dart
+++ b/pkg/compiler/test/rti/data/map_to_set.dart
@@ -11,7 +11,7 @@
 /*spec.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
 /*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*spec.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap,JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*spec.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap,JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K],needsArgs*/
 
 /*prod.class: global#double:*/
 /*spec.class: global#double:implicit=[double]*/
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 7aaeafd..5b3abdc 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -97,7 +97,13 @@
   void _registerJsonRpcMethods() {
     _clientPeer.registerMethod('streamListen', (parameters) async {
       final streamId = parameters['streamId'].asString;
-      await dds.streamManager.streamListen(this, streamId);
+      final includePrivates =
+          parameters['_includePrivateMembers'].asBoolOr(false);
+      await dds.streamManager.streamListen(
+        this,
+        streamId,
+        includePrivates: includePrivates,
+      );
       return RPCResponses.success;
     });
 
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 523cadf..48957f1 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -1899,8 +1899,6 @@
 
   final int? vmServicePort;
 
-  final bool? enableAsserts;
-
   /// Which console to run the program in.
   ///
   /// If "terminal" or "externalTerminal" will cause the program to be run by
@@ -1939,7 +1937,6 @@
     this.toolArgs,
     this.vmAdditionalArgs,
     this.console,
-    this.enableAsserts,
     this.customTool,
     this.customToolReplacesArgs,
     Object? restart,
@@ -1973,7 +1970,6 @@
         vmAdditionalArgs = (obj['vmAdditionalArgs'] as List?)?.cast<String>(),
         vmServicePort = obj['vmServicePort'] as int?,
         console = obj['console'] as String?,
-        enableAsserts = obj['enableAsserts'] as bool?,
         customTool = obj['customTool'] as String?,
         customToolReplacesArgs = obj['customToolReplacesArgs'] as int?,
         super.fromMap(obj);
@@ -1988,7 +1984,6 @@
         if (vmAdditionalArgs != null) 'vmAdditionalArgs': vmAdditionalArgs,
         if (vmServicePort != null) 'vmServicePort': vmServicePort,
         if (console != null) 'console': console,
-        if (enableAsserts != null) 'enableAsserts': enableAsserts,
         if (customTool != null) 'customTool': customTool,
         if (customToolReplacesArgs != null)
           'customToolReplacesArgs': customToolReplacesArgs,
diff --git a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
index 46e28e3..1ec25dd 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
@@ -98,9 +98,6 @@
         '-DSILENT_OBSERVATORY=true',
         '--write-service-info=${Uri.file(vmServiceInfoFile.path)}'
       ],
-      // Default to asserts on, this seems like the most useful behaviour for
-      // editor-spawned debug sessions.
-      if (args.enableAsserts ?? true) '--enable-asserts',
     ];
 
     // Handle customTool and deletion of any arguments for it.
@@ -150,11 +147,6 @@
         env: args.env,
       );
     }
-
-    // Delay responding until the debugger is connected.
-    if (debug) {
-      await debuggerInitialized;
-    }
   }
 
   /// Called by [attachRequest] to request that we actually connect to the app
diff --git a/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart b/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
index 0f67af4..716fcfe 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
@@ -93,11 +93,8 @@
         '-DSILENT_OBSERVATORY=true',
         '--write-service-info=${Uri.file(vmServiceInfoFile.path)}'
       ],
-      // Default to asserts on, this seems like the most useful behaviour for
-      // editor-spawned debug sessions.
-      if (args.enableAsserts ?? true) '--enable-asserts',
       // TODO(dantup): This should be changed from "dart run test:test" to
-      // "dart test" once the started-paused flags are working correctly.
+      // "dart test" once the start-paused flags are working correctly.
       // Currently they start paused but do not write the vm-service-info file
       // to give us the VM-service URI.
       // https://github.com/dart-lang/sdk/issues/44200#issuecomment-726869539
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index ee0bc49..be5b3f4 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -170,16 +170,19 @@
   /// `streamListen` request for `stream` to the VM service.
   Future<void> streamListen(
     DartDevelopmentServiceClient? client,
-    String stream,
-  ) async {
+    String stream, {
+    bool? includePrivates,
+  }) async {
     await _streamSubscriptionMutex.runGuarded(
       () async {
         assert(stream.isNotEmpty);
+        bool streamNewlySubscribed = false;
         if (!streamListeners.containsKey(stream)) {
           // Initialize the list of clients for the new stream before we do
           // anything else to ensure multiple clients registering for the same
           // stream in quick succession doesn't result in multiple streamListen
           // requests being sent to the VM service.
+          streamNewlySubscribed = true;
           streamListeners[stream] = <DartDevelopmentServiceClient>[];
           if ((stream == kDebugStream && client == null) ||
               stream != kDebugStream) {
@@ -188,12 +191,18 @@
             final result =
                 await dds.vmServiceClient.sendRequest('streamListen', {
               'streamId': stream,
+              if (includePrivates != null)
+                '_includePrivateMembers': includePrivates,
             });
             assert(result['type'] == 'Success');
           }
         }
         if (streamListeners[stream]!.contains(client)) {
           throw kStreamAlreadySubscribedException;
+        } else if (!streamNewlySubscribed && includePrivates != null) {
+          await dds.vmServiceClient.sendRequest(
+              '_setStreamIncludePrivateMembers',
+              {'streamId': stream, 'includePrivateMembers': includePrivates});
         }
         if (client != null) {
           streamListeners[stream]!.add(client);
diff --git a/pkg/dds/test/dap/dart_cli_test.dart b/pkg/dds/test/dap/dart_cli_test.dart
index d07dc37..57f2297 100644
--- a/pkg/dds/test/dap/dart_cli_test.dart
+++ b/pkg/dds/test/dap/dart_cli_test.dart
@@ -79,7 +79,6 @@
           program: 'foo.dart',
           customTool: '/custom/dart',
           noDebug: true,
-          enableAsserts: true, // to check args are still passed through
         );
 
         await adapter.configurationDoneRequest(request, null, () {});
@@ -87,8 +86,8 @@
         await responseCompleter.future;
 
         expect(adapter.executable, equals('/custom/dart'));
-        // args should be in-tact
-        expect(adapter.processArgs, contains('--enable-asserts'));
+        // a standard built-in arg should be present.
+        expect(adapter.processArgs, contains('--disable-dart-dev'));
       });
 
       test('with all args replaced', () async {
@@ -100,7 +99,6 @@
           customTool: '/custom/dart',
           customToolReplacesArgs: 9999, // replaces all built-in args
           noDebug: true,
-          enableAsserts: true, // should not be in args
           toolArgs: ['tool_args'], // should still be in args
         );
 
@@ -111,7 +109,7 @@
         expect(adapter.executable, equals('/custom/dart'));
         // normal built-in args are replaced by customToolReplacesArgs, but
         // user-provided toolArgs are not.
-        expect(adapter.processArgs, isNot(contains('--enable-asserts')));
+        expect(adapter.processArgs, isNot(contains('--disable-dart-dev')));
         expect(adapter.processArgs, contains('tool_args'));
       });
     });
diff --git a/pkg/dds/test/dap/integration/debug_services.dart b/pkg/dds/test/dap/integration/debug_services_test.dart
similarity index 100%
rename from pkg/dds/test/dap/integration/debug_services.dart
rename to pkg/dds/test/dap/integration/debug_services_test.dart
diff --git a/pkg/dds/tool/dap/README.md b/pkg/dds/tool/dap/README.md
index 26bbeb3..ec49ac5 100644
--- a/pkg/dds/tool/dap/README.md
+++ b/pkg/dds/tool/dap/README.md
@@ -39,7 +39,6 @@
 - `List<String>? toolArgs` - arguments passed after the tool that will run `program` (after `dart` for CLI scripts and after `dart run test:test` for test scripts)
 - `List<String>? vmAdditionalArgs` - arguments passed directly to the Dart VM (after `dart` for both CLI scripts and test scripts)
 - `String? console` - if set to `"terminal"` or `"externalTerminal"` will be run using the `runInTerminal` reverse-request; otherwise the debug adapter spawns the Dart process
-- `bool? enableAsserts` - whether to enable asserts (if not supplied, defaults to enabled)
 - `String? customTool` - an optional tool to run instead of `dart` - the custom tool must be completely compatible with the tool/command it is replacing
 - `int? customToolReplacesArgs` - the number of arguments to delete from the beginning of the argument list when invoking `customTool` - e.g. setting `customTool` to `dart_test` and
   `customToolReplacesArgs` to `2` for a test run would invoke `dart_test foo_test.dart` instead of `dart run test:test foo_test.dart` (if larger than the number of computed arguments all arguments will be removed, if not supplied will default to `0`)
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 1b1a534..e7413dd17 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -243,9 +243,13 @@
         buffer.write('_');
       } else {
         int first = equivalence[0];
-        buffer..write('#')..write(first);
+        buffer
+          ..write('#')
+          ..write(first);
         if (first == i) {
-          buffer..write('=')..write(objects[i]);
+          buffer
+            ..write('=')
+            ..write(objects[i]);
         }
       }
     }
@@ -259,7 +263,10 @@
     if (first.isNotEmpty && first.length == objects.length) return;
     var buffer = new StringBuffer("Expect.allIdentical([");
     _writeEquivalences(objects, equivalences, buffer);
-    buffer..write("]")..write(msg)..write(")");
+    buffer
+      ..write("]")
+      ..write(msg)
+      ..write(")");
     _fail(buffer.toString());
   }
 
@@ -290,7 +297,10 @@
     if (!hasEquivalence) return;
     var buffer = new StringBuffer("Expect.allDistinct([");
     _writeEquivalences(objects, equivalences, buffer);
-    buffer..write("]")..write(msg)..write(")");
+    buffer
+      ..write("]")
+      ..write(msg)
+      ..write(")");
     _fail(buffer.toString());
   }
 
@@ -387,7 +397,7 @@
     String defaultMessage =
         'Expect.stringEquals(expected: <$expected>", <$actual>$msg) fails';
 
-    if ((expected == null) || (actual == null)) {
+    if ((expected as dynamic) == null || (actual as dynamic) == null) {
       _fail('$defaultMessage');
     }
 
@@ -583,45 +593,52 @@
     }
   }
 
-  static bool _defaultCheck([dynamic e]) => true;
+  static bool _defaultCheck([dynamic _]) => true;
 
   /**
-   * Calls the function [f] and verifies that it throws a `T`.
-   * The optional [check] function can provide additional validation
-   * that the correct object is being thrown.  For example, to check
-   * the content of the thrown boject you could write this:
+   * Verifies that [computation] throws a [T].
    *
-   *     Expect.throws<MyException>(myThrowingFunction,
-   *          (e) => e.myMessage.contains("WARNING"));
+   * Calls the [computation] function and fails if that call doesn't throw,
+   * throws something which is not a [T], or throws a [T] which does not
+   * satisfy the optional [check] function.
    *
-   * The type variable can be omitted and the type checked in [check]
-   * instead. This was traditionally done before Dart had generic methods.
+   * Returns the accepted thrown [T] object, if one is caught.
+   * This value can be checked further, instead of checking it in the [check]
+   * function. For example, to check the content of the thrown object,
+   * you could write this:
+   * ```
+   * var e = Expect.throws<MyException>(myThrowingFunction);
+   * Expect.isTrue(e.myMessage.contains("WARNING"));
+   * ```
+   * The type variable can be omitted, in which case it defaults to [Object],
+   * and the (sub-)type of the object can be checked in [check] instead.
+   * This was traditionally done before Dart had generic methods.
    *
-   * If `f` fails an expectation (i.e., throws an [ExpectException]), that
-   * exception is not caught by [Expect.throws]. The test is still considered
-   * failing.
+   * If `computation` fails another test expectation
+   * (i.e., throws an [ExpectException]),
+   * that exception cannot be caught and accepted by [Expect.throws].
+   * The test is still considered failing.
    */
-  static void throws<T>(void f(),
-      [bool check(T error) = _defaultCheck, String reason = ""]) {
+  static T throws<T extends Object>(void Function() computation,
+      [bool Function(T error)? check, String? reason]) {
     // TODO(vsm): Make check and reason nullable or change call sites.
     // Existing tests pass null to set a reason and/or pass them through
     // via helpers.
     // TODO(rnystrom): Using the strange form below instead of "??=" to avoid
     // warnings of unnecessary null checks when analyzed as NNBD code.
-    if ((check as dynamic) == null) check = _defaultCheck;
-    if ((reason as dynamic) == null) reason = "";
+    reason ??= "";
     String msg = reason.isEmpty ? "" : "($reason)";
-    if (f is! Function()) {
+    if ((computation as dynamic) == null) {
       // Only throws from executing the function body should count as throwing.
       // The failure to even call `f` should throw outside the try/catch.
-      _fail("Expect.throws$msg: Function f not callable with zero arguments");
+      testError("Function must not be null");
     }
     try {
-      f();
+      computation();
     } catch (e, s) {
       // A test failure doesn't count as throwing.
       if (e is ExpectException) rethrow;
-      if (e is T && check(e as dynamic)) return;
+      if (e is T && (check ?? _defaultCheck)(e)) return e;
       // Throws something unexpected.
       String type = "";
       if (T != dynamic && T != Object) {
@@ -633,47 +650,41 @@
     _fail('Expect.throws$msg fails: Did not throw');
   }
 
-  static void throwsArgumentError(void f(), [String reason = "ArgumentError"]) {
-    Expect.throws(f, (error) => error is ArgumentError, reason);
-  }
+  static ArgumentError throwsArgumentError(void f(),
+          [String reason = "ArgumentError"]) =>
+      Expect.throws<ArgumentError>(f, _defaultCheck, reason);
 
-  static void throwsAssertionError(void f(),
-      [String reason = "AssertionError"]) {
-    Expect.throws(f, (error) => error is AssertionError, reason);
-  }
+  static AssertionError throwsAssertionError(void f(),
+          [String reason = "AssertionError"]) =>
+      Expect.throws<AssertionError>(f, _defaultCheck, reason);
 
-  static void throwsFormatException(void f(),
-      [String reason = "FormatException"]) {
-    Expect.throws(f, (error) => error is FormatException, reason);
-  }
+  static FormatException throwsFormatException(void f(),
+          [String reason = "FormatException"]) =>
+      Expect.throws<FormatException>(f, _defaultCheck, reason);
 
-  static void throwsNoSuchMethodError(void f(),
-      [String reason = "NoSuchMethodError"]) {
-    Expect.throws(f, (error) => error is NoSuchMethodError, reason);
-  }
+  static NoSuchMethodError throwsNoSuchMethodError(void f(),
+          [String reason = "NoSuchMethodError"]) =>
+      Expect.throws<NoSuchMethodError>(f, _defaultCheck, reason);
 
-  static void throwsReachabilityError(void f(),
-      [String reason = "ReachabilityError"]) {
-    Expect.throws(
-        f, (error) => error.toString().startsWith('ReachabilityError'), reason);
-  }
+  static Error throwsReachabilityError(void f(),
+          [String reason = "ReachabilityError"]) =>
+      Expect.throws<Error>(f,
+          (error) => error.toString().startsWith('ReachabilityError'), reason);
 
-  static void throwsRangeError(void f(), [String reason = "RangeError"]) {
-    Expect.throws(f, (error) => error is RangeError, reason);
-  }
+  static RangeError throwsRangeError(void f(),
+          [String reason = "RangeError"]) =>
+      Expect.throws<RangeError>(f, _defaultCheck, reason);
 
-  static void throwsStateError(void f(), [String reason = "StateError"]) {
-    Expect.throws(f, (error) => error is StateError, reason);
-  }
+  static StateError throwsStateError(void f(),
+          [String reason = "StateError"]) =>
+      Expect.throws<StateError>(f, _defaultCheck, reason);
 
-  static void throwsTypeError(void f(), [String reason = "TypeError"]) {
-    Expect.throws(f, (error) => error is TypeError, reason);
-  }
+  static TypeError throwsTypeError(void f(), [String reason = "TypeError"]) =>
+      Expect.throws<TypeError>(f, _defaultCheck, reason);
 
-  static void throwsUnsupportedError(void f(),
-      [String reason = "UnsupportedError"]) {
-    Expect.throws(f, (error) => error is UnsupportedError, reason);
-  }
+  static UnsupportedError throwsUnsupportedError(void f(),
+          [String reason = "UnsupportedError"]) =>
+      Expect.throws<UnsupportedError>(f, _defaultCheck, reason);
 
   /// Reports that there is an error in the test itself and not the code under
   /// test.
@@ -748,20 +759,20 @@
     _getTestName = getName;
   }
 
-  // TODO(rnystrom): Type this `String Function()?` once this library doesn't
-  // need to be NNBD-agnostic.
-  static dynamic _getTestName;
+  static String Function() _getTestName = _kEmptyString;
 
   final String message;
   final String name;
 
-  ExpectException(this.message)
-      : name = (_getTestName == null) ? "" : _getTestName();
+  ExpectException(this.message) : name = _getTestName();
 
   String toString() {
     if (name != "") return 'In test "$name" $message';
     return message;
   }
+
+  /// Initial value for _getTestName.
+  static String _kEmptyString() => "";
 }
 
 /// Is true iff type assertions are enabled.
@@ -769,7 +780,7 @@
 final bool typeAssertionsEnabled = (() {
   try {
     dynamic i = 42;
-    String s = i;
+    String s = i; // ignore: unused_local_variable
   } on TypeError {
     return true;
   }
diff --git a/pkg/expect/test/nnbd_mode_test.dart b/pkg/expect/test/nnbd_mode_test.dart
index 35dd345..1bacdec 100644
--- a/pkg/expect/test/nnbd_mode_test.dart
+++ b/pkg/expect/test/nnbd_mode_test.dart
@@ -6,7 +6,7 @@
 
 final bool strong = () {
   try {
-    int i = null as dynamic;
+    int i = null as dynamic; // ignore: unused_local_variable
     return false;
   } catch (e) {
     return true;
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 97ef414..d9f5fdf 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -1060,6 +1060,7 @@
 xxxxxxxxxxxx
 xyz
 y's
+yaml2json
 year
 yxxx
 yy
diff --git a/pkg/front_end/tool/smoke_test_quick.dart b/pkg/front_end/tool/smoke_test_quick.dart
index 12b77c3..2b7a200 100644
--- a/pkg/front_end/tool/smoke_test_quick.dart
+++ b/pkg/front_end/tool/smoke_test_quick.dart
@@ -29,6 +29,9 @@
   futures.add(run(
       "pkg/front_end/test/generated_files_up_to_date_git_test.dart", [],
       filter: false));
+  futures.add(run("tools/yaml2json.dart",
+      ["sdk/lib/libraries.yaml", "sdk/lib/libraries.json", '--check'],
+      filter: false));
   await Future.wait(futures);
   print("\n-----------------------\n");
   print("Done with exitcode $exitCode in ${stopwatch.elapsedMilliseconds} ms");
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
index 4203e7a..ba91b27 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -56,7 +56,7 @@
   new self::A::•();
   new self::B::•();
   self::C<core::num> c = new self::D::•();
-  exp::Expect::throws<dynamic>(() → void {
+  exp::Expect::throws<core::Object>(() → void {
     [@vm.call-site-attributes.metadata=receiverType:#lib::C<dart.core::num>] [@vm.direct-call.metadata=#lib::D.bar] c.{self::C::bar} = 3.14;
   });
   self::E e = new self::F::•();
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 1f0744a..423381b 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -128,10 +128,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 1) {
+DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 2) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
-  bool result = Service::ListenStream(stream_id.ToCString());
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, include_privates,
+                               arguments->NativeArgAt(1));
+  bool result =
+      Service::ListenStream(stream_id.ToCString(), include_privates.value());
   return Bool::Get(result).ptr();
 #else
   return Object::null();
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 236343c..5c62c48 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -149,7 +149,11 @@
       return new Future.error(exception);
     }
     String serial = (_requestSerial++).toString();
-    var request = new _WebSocketRequest(method, params);
+    var request = new _WebSocketRequest(method, <String, dynamic>{
+      ...params,
+      // Include internal response data.
+      '_includePrivateMembers': true,
+    });
     if ((_webSocket != null) && _webSocket!.isOpen) {
       // Already connected, send request immediately.
       _sendRequest(serial, request);
diff --git a/runtime/observatory_2/lib/service_common.dart b/runtime/observatory_2/lib/service_common.dart
index b61f4a0..d6eba9b 100644
--- a/runtime/observatory_2/lib/service_common.dart
+++ b/runtime/observatory_2/lib/service_common.dart
@@ -149,7 +149,11 @@
       return new Future.error(exception);
     }
     String serial = (_requestSerial++).toString();
-    var request = new _WebSocketRequest(method, params);
+    var request = new _WebSocketRequest(method, <String, dynamic>{
+      ...params,
+      // Include internal response data.
+      '_includePrivateMembers': true,
+    });
     if ((_webSocket != null) && _webSocket.isOpen) {
       // Already connected, send request immediately.
       _sendRequest(serial, request);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index ca3d03c..1742e8d 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -361,7 +361,7 @@
   V(VMService_OnStart, 0)                                                      \
   V(VMService_OnExit, 0)                                                       \
   V(VMService_OnServerAddressChange, 1)                                        \
-  V(VMService_ListenStream, 1)                                                 \
+  V(VMService_ListenStream, 2)                                                 \
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index bf9a9ad..15f48ef 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -740,6 +740,13 @@
 
 Type& TranslationHelper::GetDeclarationType(const Class& klass) {
   ASSERT(!klass.IsNull());
+  // Forward expression evaluation class to a real class when
+  // creating types.
+  if (GetExpressionEvaluationClass().ptr() == klass.ptr()) {
+    ASSERT(GetExpressionEvaluationRealClass().ptr() != klass.ptr());
+    return GetDeclarationType(GetExpressionEvaluationRealClass());
+  }
+  ASSERT(klass.id() != kIllegalCid);
   // Note that if cls is _Closure, the returned type will be _Closure,
   // and not the signature type.
   Type& type = Type::ZoneHandle(Z);
@@ -3556,6 +3563,14 @@
 
 const Type& TypeTranslator::ReceiverType(const Class& klass) {
   ASSERT(!klass.IsNull());
+  // Forward expression evaluation class to a real class when
+  // creating types.
+  if (translation_helper_.GetExpressionEvaluationClass().ptr() == klass.ptr()) {
+    ASSERT(translation_helper_.GetExpressionEvaluationRealClass().ptr() !=
+           klass.ptr());
+    return ReceiverType(translation_helper_.GetExpressionEvaluationRealClass());
+  }
+  ASSERT(klass.id() != kIllegalCid);
   // Note that if klass is _Closure, the returned type will be _Closure,
   // and not the signature type.
   Type& type = Type::ZoneHandle(Z);
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 35b2647..ea30fa5 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -209,14 +209,27 @@
     }
     return *expression_evaluation_function_;
   }
+  void SetExpressionEvaluationClass(const Class& cls) {
+    ASSERT(expression_evaluation_class_ == nullptr);
+    ASSERT(!cls.IsNull());
+    expression_evaluation_class_ = &Class::Handle(zone_, cls.ptr());
+  }
+  const Class& GetExpressionEvaluationClass() {
+    if (expression_evaluation_class_ == nullptr) {
+      return Class::null_class();
+    }
+    return *expression_evaluation_class_;
+  }
   void SetExpressionEvaluationRealClass(const Class& real_class) {
     ASSERT(expression_evaluation_real_class_ == nullptr);
     ASSERT(!real_class.IsNull());
     expression_evaluation_real_class_ = &Class::Handle(zone_, real_class.ptr());
   }
-  ClassPtr GetExpressionEvaluationRealClass() {
-    ASSERT(expression_evaluation_real_class_ != nullptr);
-    return expression_evaluation_real_class_->ptr();
+  const Class& GetExpressionEvaluationRealClass() {
+    if (expression_evaluation_real_class_ == nullptr) {
+      return Class::null_class();
+    }
+    return *expression_evaluation_real_class_;
   }
 
  private:
@@ -250,6 +263,14 @@
   Smi& name_index_handle_;
   GrowableObjectArray* potential_extension_libraries_ = nullptr;
   Function* expression_evaluation_function_ = nullptr;
+
+  // A temporary class needed to contain the function to which an eval
+  // expression is compiled. This is a fresh class so loading the kernel
+  // isn't a no-op. It should be unreachable after the eval function is loaded.
+  Class* expression_evaluation_class_ = nullptr;
+
+  // The original class that is the scope in which the eval expression is
+  // evaluated.
   Class* expression_evaluation_real_class_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(TranslationHelper);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index a4e6c1a..8b8468d 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -95,6 +95,8 @@
 Dart_Handle Api::false_handle_ = NULL;
 Dart_Handle Api::null_handle_ = NULL;
 Dart_Handle Api::empty_string_handle_ = NULL;
+Dart_Handle Api::no_callbacks_error_handle_ = NULL;
+Dart_Handle Api::unwind_in_progress_error_handle_ = NULL;
 
 const char* CanonicalFunction(const char* func) {
   if (strncmp(func, "dart::", 6) == 0) {
@@ -478,23 +480,6 @@
   return Api::NewHandle(T, error.ptr());
 }
 
-Dart_Handle Api::AcquiredError(IsolateGroup* isolate_group) {
-  ApiState* state = isolate_group->api_state();
-  ASSERT(state != NULL);
-  PersistentHandle* acquired_error_handle = state->AcquiredError();
-  return reinterpret_cast<Dart_Handle>(acquired_error_handle);
-}
-
-Dart_Handle Api::UnwindInProgressError() {
-  Thread* T = Thread::Current();
-  CHECK_API_SCOPE(T);
-  TransitionToVM transition(T);
-  HANDLESCOPE(T);
-  const String& message = String::Handle(
-      Z, String::New("No api calls are allowed while unwind is in progress"));
-  return Api::NewHandle(T, UnwindError::New(message));
-}
-
 bool Api::IsValid(Dart_Handle handle) {
   Isolate* isolate = Isolate::Current();
   Thread* thread = Thread::Current();
@@ -551,6 +536,14 @@
 
   ASSERT(empty_string_handle_ == NULL);
   empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().ptr());
+
+  ASSERT(no_callbacks_error_handle_ == NULL);
+  no_callbacks_error_handle_ =
+      InitNewReadOnlyApiHandle(Object::no_callbacks_error().ptr());
+
+  ASSERT(unwind_in_progress_error_handle_ == NULL);
+  unwind_in_progress_error_handle_ =
+      InitNewReadOnlyApiHandle(Object::unwind_in_progress_error().ptr());
 }
 
 void Api::Cleanup() {
@@ -558,6 +551,8 @@
   false_handle_ = NULL;
   null_handle_ = NULL;
   empty_string_handle_ = NULL;
+  no_callbacks_error_handle_ = NULL;
+  unwind_in_progress_error_handle_ = NULL;
 }
 
 bool Api::StringGetPeerHelper(NativeArguments* arguments,
@@ -1156,9 +1151,9 @@
   ApiState* state = isolate_group->api_state();
   ASSERT(state != NULL);
   ASSERT(state->IsActivePersistentHandle(object));
-  PersistentHandle* ref = PersistentHandle::Cast(object);
-  ASSERT(!state->IsProtectedHandle(ref));
-  if (!state->IsProtectedHandle(ref)) {
+  ASSERT(!Api::IsProtectedHandle(object));
+  if (!Api::IsProtectedHandle(object)) {
+    PersistentHandle* ref = PersistentHandle::Cast(object);
     state->FreePersistentHandle(ref);
   }
 }
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 47f9b7a..73f681f 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -181,12 +181,6 @@
   // Gets the handle used to designate successful return.
   static Dart_Handle Success() { return Api::True(); }
 
-  // Gets the handle which holds the pre-created acquired error object.
-  static Dart_Handle AcquiredError(IsolateGroup* isolate_group);
-
-  // Gets the handle for unwind-is-in-progress error.
-  static Dart_Handle UnwindInProgressError();
-
   // Returns true if the handle holds a Smi.
   static bool IsSmi(Dart_Handle handle) {
     // Important: we do not require current thread to be in VM state because
@@ -241,6 +235,22 @@
   // Gets a handle to EmptyString.
   static Dart_Handle EmptyString() { return empty_string_handle_; }
 
+  // Gets the handle which holds the pre-created acquired error object.
+  static Dart_Handle NoCallbacksError() { return no_callbacks_error_handle_; }
+
+  // Gets the handle for unwind-is-in-progress error.
+  static Dart_Handle UnwindInProgressError() {
+    return unwind_in_progress_error_handle_;
+  }
+
+  static bool IsProtectedHandle(Dart_Handle object) {
+    if (object == NULL) return false;
+    return (object == true_handle_) || (object == false_handle_) ||
+           (object == null_handle_) || (object == empty_string_handle_) ||
+           (object == no_callbacks_error_handle_) ||
+           (object == unwind_in_progress_error_handle_);
+  }
+
   // Retrieves the top ApiLocalScope.
   static ApiLocalScope* TopScope(Thread* thread);
 
@@ -314,6 +324,8 @@
   static Dart_Handle false_handle_;
   static Dart_Handle null_handle_;
   static Dart_Handle empty_string_handle_;
+  static Dart_Handle no_callbacks_error_handle_;
+  static Dart_Handle unwind_in_progress_error_handle_;
 
   friend class ApiNativeScope;
 };
@@ -326,8 +338,7 @@
 
 #define CHECK_CALLBACK_STATE(thread)                                           \
   if (thread->no_callback_scope_depth() != 0) {                                \
-    return reinterpret_cast<Dart_Handle>(                                      \
-        Api::AcquiredError(thread->isolate_group()));                          \
+    return reinterpret_cast<Dart_Handle>(Api::NoCallbacksError());             \
   }                                                                            \
   if (thread->is_unwind_in_progress()) {                                       \
     return reinterpret_cast<Dart_Handle>(Api::UnwindInProgressError());        \
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 02cbfa3..c9851a6 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -2602,9 +2602,7 @@
   // Now try allocating a string with outstanding Acquires and it should
   // return an error.
   result = NewString("We expect an error here");
-  EXPECT_ERROR(result,
-               "Internal Dart data pointers have been acquired, "
-               "please release them using Dart_TypedDataReleaseData.");
+  EXPECT_ERROR(result, "Callbacks into the Dart VM are currently prohibited");
 
   // Now modify the values in the directly accessible array and then check
   // it we see the changes back in dart.
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index e23252e..f3f9775 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -702,31 +702,7 @@
 // group basis and destroyed when the isolate group is shutdown.
 class ApiState {
  public:
-  ApiState()
-      : persistent_handles_(),
-        weak_persistent_handles_(),
-        null_(NULL),
-        true_(NULL),
-        false_(NULL),
-        acquired_error_(NULL) {}
-  ~ApiState() {
-    if (null_ != NULL) {
-      persistent_handles_.FreeHandle(null_);
-      null_ = NULL;
-    }
-    if (true_ != NULL) {
-      persistent_handles_.FreeHandle(true_);
-      true_ = NULL;
-    }
-    if (false_ != NULL) {
-      persistent_handles_.FreeHandle(false_);
-      false_ = NULL;
-    }
-    if (acquired_error_ != NULL) {
-      persistent_handles_.FreeHandle(acquired_error_);
-      acquired_error_ = NULL;
-    }
-  }
+  ApiState() : persistent_handles_(), weak_persistent_handles_() {}
 
   void MergeOtherApiState(ApiState* api_state);
 
@@ -790,30 +766,11 @@
            !weak_persistent_handles_.IsFreeHandle(object);
   }
 
-  bool IsProtectedHandle(PersistentHandle* object) {
-    MutexLocker ml(&mutex_);
-    if (object == NULL) return false;
-    return object == null_ || object == true_ || object == false_;
-  }
-
   int CountPersistentHandles() {
     MutexLocker ml(&mutex_);
     return persistent_handles_.CountHandles();
   }
 
-  PersistentHandle* AcquiredError() {
-    // The ApiError pre-allocated in the "vm-isolate" since we will not be able
-    // to allocate it when the error actually occurs.
-    // When the error occurs there will be outstanding acquires to internal
-    // data pointers making it unsafe to allocate objects on the dart heap.
-    MutexLocker ml(&mutex_);
-    if (acquired_error_ == nullptr) {
-      acquired_error_ = persistent_handles_.AllocateHandle();
-      acquired_error_->set_ptr(ApiError::typed_data_acquire_error());
-    }
-    return acquired_error_;
-  }
-
   void RunWithLockedPersistentHandles(
       std::function<void(PersistentHandles&)> fun) {
     MutexLocker ml(&mutex_);
@@ -835,12 +792,6 @@
   FinalizablePersistentHandles weak_persistent_handles_;
   WeakTable acquired_table_;
 
-  // Persistent handles to important objects.
-  PersistentHandle* null_;
-  PersistentHandle* true_;
-  PersistentHandle* false_;
-  PersistentHandle* acquired_error_;
-
   DISALLOW_COPY_AND_ASSIGN(ApiState);
 };
 
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index dfac508..5194918 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -37,7 +37,9 @@
       param_values_(NULL),
       num_params_(0),
       offset_(0),
-      count_(-1) {
+      count_(-1),
+      include_private_members_(true),
+      ignore_object_depth_(0) {
   ObjectIdRing* ring = NULL;
   Isolate* isolate = Isolate::Current();
   if (isolate != NULL) {
@@ -90,6 +92,10 @@
                  "request %s\n",
                  Dart::UptimeMillis(), main_port, isolate_name, method_);
   }
+  const char* kIncludePrivateMembersKey = "_includePrivateMembers";
+  if (HasParam(kIncludePrivateMembersKey)) {
+    include_private_members_ = ParamIs(kIncludePrivateMembersKey, "true");
+  }
   buffer()->Printf("{\"jsonrpc\":\"2.0\", \"result\":");
 }
 
@@ -368,49 +374,61 @@
   PrintProperty("id", id_zone_->GetServiceId(o));
 }
 
+#define PRIVATE_NAME_CHECK()                                                   \
+  if (!IsAllowableKey(name) || ignore_object_depth_ > 0) return
+
 void JSONStream::PrintProperty(const char* name, const ServiceEvent* event) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(event);
 }
 
 void JSONStream::PrintProperty(const char* name, Breakpoint* bpt) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(bpt);
 }
 
 void JSONStream::PrintProperty(const char* name, TokenPosition tp) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(tp);
 }
 
 void JSONStream::PrintProperty(const char* name, Metric* metric) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(metric);
 }
 
 void JSONStream::PrintProperty(const char* name, MessageQueue* queue) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(queue);
 }
 
 void JSONStream::PrintProperty(const char* name, Isolate* isolate) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(isolate);
 }
 
 void JSONStream::PrintProperty(const char* name,
                                const TimelineEvent* timeline_event) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(timeline_event);
 }
 
 void JSONStream::PrintProperty(const char* name,
                                const TimelineEventBlock* timeline_event_block) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(timeline_event_block);
 }
 
 void JSONStream::PrintfProperty(const char* name, const char* format, ...) {
+  PRIVATE_NAME_CHECK();
   va_list args;
   va_start(args, format);
   writer_.VPrintfProperty(name, format, args);
@@ -462,11 +480,13 @@
 }
 
 void JSONStream::PrintProperty(const char* name, const Object& o, bool ref) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(o, ref);
 }
 
 void JSONStream::PrintPropertyVM(const char* name, bool ref) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValueVM(ref);
 }
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index a00f266..5b37379 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -9,6 +9,7 @@
 #include "platform/allocation.h"
 #include "platform/text_buffer.h"
 #include "vm/json_writer.h"
+#include "vm/os.h"
 #include "vm/service.h"
 #include "vm/token_position.h"
 
@@ -102,6 +103,18 @@
 
   void set_reply_port(Dart_Port port);
 
+  bool include_private_members() const { return include_private_members_; }
+  void set_include_private_members(bool include_private_members) {
+    include_private_members_ = include_private_members;
+  }
+
+  bool IsAllowableKey(const char* key) {
+    if (include_private_members_) {
+      return true;
+    }
+    return *key != '_';
+  }
+
   void SetParams(const char** param_keys,
                  const char** param_values,
                  intptr_t num_params);
@@ -167,15 +180,41 @@
   void PostNullReply(Dart_Port port);
 
   void OpenObject(const char* property_name = NULL) {
+    if (ignore_object_depth_ > 0 ||
+        (property_name != nullptr && !IsAllowableKey(property_name))) {
+      ignore_object_depth_++;
+      return;
+    }
     writer_.OpenObject(property_name);
   }
-  void CloseObject() { writer_.CloseObject(); }
-  void UncloseObject() { writer_.UncloseObject(); }
+  void CloseObject() {
+    if (ignore_object_depth_ > 0) {
+      ignore_object_depth_--;
+      return;
+    }
+    writer_.CloseObject();
+  }
+  void UncloseObject() {
+    // This should be updated to handle unclosing a private object if we need
+    // to handle that case, which we don't currently.
+    writer_.UncloseObject();
+  }
 
   void OpenArray(const char* property_name = NULL) {
+    if (ignore_object_depth_ > 0 ||
+        (property_name != nullptr && !IsAllowableKey(property_name))) {
+      ignore_object_depth_++;
+      return;
+    }
     writer_.OpenArray(property_name);
   }
-  void CloseArray() { writer_.CloseArray(); }
+  void CloseArray() {
+    if (ignore_object_depth_ > 0) {
+      ignore_object_depth_--;
+      return;
+    }
+    writer_.CloseArray();
+  }
 
   void PrintValueNull() { writer_.PrintValueNull(); }
   void PrintValueBool(bool b) { writer_.PrintValueBool(b); }
@@ -211,46 +250,67 @@
 
   void PrintServiceId(const Object& o);
 
+#define PRIVATE_NAME_CHECK()                                                   \
+  if (!IsAllowableKey(name) || ignore_object_depth_ > 0) {                     \
+    return;                                                                    \
+  }
+
   void PrintPropertyBool(const char* name, bool b) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyBool(name, b);
   }
   void PrintProperty(const char* name, intptr_t i) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, i);
   }
   void PrintProperty64(const char* name, int64_t i) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, i);
   }
   void PrintPropertyTimeMillis(const char* name, int64_t millis) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, millis);
   }
   void PrintPropertyTimeMicros(const char* name, int64_t micros) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, micros);
   }
   void PrintProperty(const char* name, double d) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, d);
   }
   void PrintPropertyBase64(const char* name,
                            const uint8_t* bytes,
                            intptr_t length) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyBase64(name, bytes, length);
   }
   void PrintProperty(const char* name, const char* s) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, s);
   }
   bool PrintPropertyStr(const char* name,
                         const String& s,
                         intptr_t offset,
                         intptr_t count) {
+    if (!IsAllowableKey(name)) {
+      return false;
+    }
     return writer_.PrintPropertyStr(name, s, offset, count);
   }
   void PrintPropertyNoEscape(const char* name, const char* s) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyNoEscape(name, s);
   }
   void PrintfProperty(const char* name, const char* format, ...)
       PRINTF_ATTRIBUTE(3, 4);
   void VPrintfProperty(const char* name, const char* format, va_list args) {
+    PRIVATE_NAME_CHECK();
     writer_.VPrintfProperty(name, format, args);
   }
+
+#undef PRIVATE_NAME_CHECK
+
   void PrintProperty(const char* name, const Object& o, bool ref = true);
 
   void PrintProperty(const char* name, const ServiceEvent* event);
@@ -285,7 +345,8 @@
   intptr_t offset_;
   intptr_t count_;
   int64_t setup_time_micros_;
-
+  bool include_private_members_;
+  intptr_t ignore_object_depth_;
   friend class JSONObject;
   friend class JSONArray;
   friend class TimelineEvent;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 39689f6..0507227 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -706,6 +706,7 @@
 
   // Load the "evaluate:source" expression evaluation library.
   ASSERT(expression_evaluation_library_.IsNull());
+  ASSERT(H.GetExpressionEvaluationClass().IsNull());
   ASSERT(H.GetExpressionEvaluationFunction().IsNull());
   H.SetExpressionEvaluationRealClass(real_class);
   const Object& result = Object::Handle(Z, LoadProgram(true));
@@ -1449,6 +1450,9 @@
   // they are not reachable anymore and we never look them up by name.
   const bool register_class =
       library.ptr() != expression_evaluation_library_.ptr();
+  if (!register_class) {
+    H.SetExpressionEvaluationClass(*out_class);
+  }
 
   if (loading_native_wrappers_library_ || !register_class) {
     FinishClassLoading(*out_class, library, toplevel_class, class_offset,
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 3259317..cb4dcdf 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1158,10 +1158,14 @@
 
   String& error_str = String::Handle();
   error_str = String::New(
-      "Internal Dart data pointers have been acquired, please release them "
-      "using Dart_TypedDataReleaseData.",
+      "Callbacks into the Dart VM are currently prohibited. Either there are "
+      "outstanding pointers from Dart_TypedDataAcquireData that have not been "
+      "released with Dart_TypedDataReleaseData, or a finalizer is running.",
       Heap::kOld);
-  *typed_data_acquire_error_ = ApiError::New(error_str, Heap::kOld);
+  *no_callbacks_error_ = ApiError::New(error_str, Heap::kOld);
+  error_str = String::New(
+      "No api calls are allowed while unwind is in progress", Heap::kOld);
+  *unwind_in_progress_error_ = UnwindError::New(error_str, Heap::kOld);
   error_str = String::New("SnapshotWriter Error", Heap::kOld);
   *snapshot_writer_error_ =
       LanguageError::New(error_str, Report::kError, Heap::kOld);
@@ -1238,8 +1242,10 @@
   ASSERT(bool_false_->IsBool());
   ASSERT(smi_illegal_cid_->IsSmi());
   ASSERT(smi_zero_->IsSmi());
-  ASSERT(!typed_data_acquire_error_->IsSmi());
-  ASSERT(typed_data_acquire_error_->IsApiError());
+  ASSERT(!no_callbacks_error_->IsSmi());
+  ASSERT(no_callbacks_error_->IsApiError());
+  ASSERT(!unwind_in_progress_error_->IsSmi());
+  ASSERT(unwind_in_progress_error_->IsUnwindError());
   ASSERT(!snapshot_writer_error_->IsSmi());
   ASSERT(snapshot_writer_error_->IsLanguageError());
   ASSERT(!branch_offset_error_->IsSmi());
@@ -21294,10 +21300,8 @@
   ASSERT(Utils::IsUint(sizeof(untag()->type_class_id_) * kBitsPerByte, id));
   // We should never need a Type object for a top-level class.
   ASSERT(!ClassTable::IsTopLevelCid(id));
-  // We must allow Types with kIllegalCid type class ids, because the class
-  // used for evaluating expressions inside a instance method call context
-  // from the debugger is not registered (and thus has kIllegalCid as an id).
-  ASSERT(id == kIllegalCid || !IsInternalOnlyClassId(id));
+  ASSERT(id != kIllegalCid);
+  ASSERT(!IsInternalOnlyClassId(id));
   StoreNonPointer(&untag()->type_class_id_, id);
 }
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index c402aab..ab78804 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -453,7 +453,8 @@
   V(Bool, bool_false)                                                          \
   V(Smi, smi_illegal_cid)                                                      \
   V(Smi, smi_zero)                                                             \
-  V(ApiError, typed_data_acquire_error)                                        \
+  V(ApiError, no_callbacks_error)                                              \
+  V(UnwindError, unwind_in_progress_error)                                     \
   V(LanguageError, snapshot_writer_error)                                      \
   V(LanguageError, branch_offset_error)                                        \
   V(LanguageError, speculative_inlining_error)                                 \
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 50238aa..38e0d75 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -367,7 +367,8 @@
     &Service::timeline_stream, &Service::profiler_stream,
 };
 
-bool Service::ListenStream(const char* stream_id) {
+bool Service::ListenStream(const char* stream_id,
+                           bool include_private_members) {
   if (FLAG_trace_service) {
     OS::PrintErr("vm-service: starting stream '%s'\n", stream_id);
   }
@@ -375,6 +376,7 @@
   for (intptr_t i = 0; i < num_streams; i++) {
     if (strcmp(stream_id, streams_[i]->id()) == 0) {
       streams_[i]->set_enabled(true);
+      streams_[i]->set_include_private_members(include_private_members);
       return true;
     }
   }
@@ -1164,7 +1166,7 @@
 }
 
 void Service::HandleEvent(ServiceEvent* event, bool enter_safepoint) {
-  if (event->stream_info() != NULL && !event->stream_info()->enabled()) {
+  if (event->stream_info() != nullptr && !event->stream_info()->enabled()) {
     if (FLAG_warn_on_pause_with_no_debugger && event->IsPause()) {
       // If we are about to pause a running program which has no
       // debugger connected, tell the user about it.
@@ -1172,7 +1174,7 @@
     }
     // Ignore events when no one is listening to the event stream.
     return;
-  } else if (event->stream_info() != NULL &&
+  } else if (event->stream_info() != nullptr &&
              FLAG_warn_on_pause_with_no_debugger && event->IsPause()) {
     ReportPauseOnConsole(event);
   }
@@ -1180,8 +1182,12 @@
     return;
   }
   JSONStream js;
+  if (event->stream_info() != nullptr) {
+    js.set_include_private_members(
+        event->stream_info()->include_private_members());
+  }
   const char* stream_id = event->stream_id();
-  ASSERT(stream_id != NULL);
+  ASSERT(stream_id != nullptr);
   {
     JSONObject jsobj(&js);
     jsobj.AddProperty("jsonrpc", "2.0");
@@ -1495,6 +1501,31 @@
   }
 }
 
+static const MethodParameter* const
+    set_stream_include_private_members_params[] = {
+        NO_ISOLATE_PARAMETER,
+        new BoolParameter("includePrivateMembers", true),
+        nullptr,
+};
+
+static void SetStreamIncludePrivateMembers(Thread* thread, JSONStream* js) {
+  const char* stream_id = js->LookupParam("streamId");
+  if (stream_id == nullptr) {
+    PrintMissingParamError(js, "streamId");
+    return;
+  }
+  bool include_private_members =
+      BoolParameter::Parse(js->LookupParam("includePrivateMembers"), false);
+  intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]);
+  for (intptr_t i = 0; i < num_streams; i++) {
+    if (strcmp(stream_id, streams_[i]->id()) == 0) {
+      streams_[i]->set_include_private_members(include_private_members);
+      break;
+    }
+  }
+  PrintSuccess(js);
+}
+
 static void ActOnIsolateGroup(JSONStream* js,
                               std::function<void(IsolateGroup*)> visitor) {
   const String& prefix =
@@ -5626,6 +5657,8 @@
     set_library_debuggable_params },
   { "setName", SetName,
     set_name_params },
+  { "_setStreamIncludePrivateMembers", SetStreamIncludePrivateMembers,
+    set_stream_include_private_members_params },
   { "setTraceClassAllocation", SetTraceClassAllocation,
     set_trace_class_allocation_params },
   { "setVMName", SetVMName,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index f625b94..751c1e5 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -68,16 +68,23 @@
 
 class StreamInfo {
  public:
-  explicit StreamInfo(const char* id) : id_(id), enabled_(false) {}
+  explicit StreamInfo(const char* id)
+      : id_(id), enabled_(false), include_private_members_(false) {}
 
   const char* id() const { return id_; }
 
   void set_enabled(bool value) { enabled_ = value; }
   bool enabled() const { return enabled_; }
 
+  void set_include_private_members(bool value) {
+    include_private_members_ = value;
+  }
+  bool include_private_members() const { return include_private_members_; }
+
  private:
   const char* id_;
   bool enabled_;
+  bool include_private_members_;
 };
 
 class Service : public AllStatic {
@@ -168,7 +175,7 @@
   static StreamInfo timeline_stream;
   static StreamInfo profiler_stream;
 
-  static bool ListenStream(const char* stream_id);
+  static bool ListenStream(const char* stream_id, bool include_privates);
   static void CancelStream(const char* stream_id);
 
   static ObjectPtr RequestAssets();
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index b01ebb6..8db9d2a 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -17,8 +17,6 @@
 
 import 'dart:_internal' hide Symbol;
 
-const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");
-
 const int _mask30 = 0x3fffffff; // Low 30 bits.
 
 @patch
@@ -509,13 +507,13 @@
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
-          return new JsLinkedHashMap<K, V>.es6();
+          return new JsLinkedHashMap<K, V>();
         }
         hashCode = _defaultHashCode;
       } else {
         if (identical(identityHashCode, hashCode) &&
             identical(identical, equals)) {
-          return new _LinkedIdentityHashMap<K, V>.es6();
+          return new _LinkedIdentityHashMap<K, V>();
         }
         if (equals == null) {
           equals = _defaultEquals;
@@ -533,12 +531,12 @@
   }
 
   @patch
-  factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>.es6;
+  factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
 
   // Private factory constructor called by generated code for map literals.
   @pragma('dart2js:noInline')
   factory LinkedHashMap._literal(List keyValuePairs) {
-    return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>.es6());
+    return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>());
   }
 
   // Private factory constructor called by generated code for map literals.
@@ -546,7 +544,7 @@
   @pragma('dart2js:noInline')
   @pragma('dart2js:noSideEffects')
   factory LinkedHashMap._empty() {
-    return new JsLinkedHashMap<K, V>.es6();
+    return new JsLinkedHashMap<K, V>();
   }
 
   // Private factory static function called by generated code for map literals.
@@ -564,17 +562,6 @@
 }
 
 class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> {
-  static bool get _supportsEs6Maps {
-    return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true',
-        'typeof Map != "undefined"');
-  }
-
-  factory _LinkedIdentityHashMap.es6() {
-    return (_USE_ES6_MAPS && _LinkedIdentityHashMap._supportsEs6Maps)
-        ? new _Es6LinkedIdentityHashMap<K, V>()
-        : new _LinkedIdentityHashMap<K, V>();
-  }
-
   _LinkedIdentityHashMap();
 
   int internalComputeHashCode(var key) {
@@ -595,161 +582,6 @@
   }
 }
 
-class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V>
-    implements InternalMap {
-  final _map;
-  int _modifications = 0;
-
-  _Es6LinkedIdentityHashMap() : _map = JS('var', 'new Map()');
-
-  int get length => JS('int', '#.size', _map);
-  bool get isEmpty => length == 0;
-  bool get isNotEmpty => !isEmpty;
-
-  Iterable<K> get keys => new _Es6MapIterable<K>(this, true);
-
-  Iterable<V> get values => new _Es6MapIterable<V>(this, false);
-
-  bool containsKey(Object? key) {
-    return JS('bool', '#.has(#)', _map, key);
-  }
-
-  bool containsValue(Object? value) {
-    return values.any((each) => each == value);
-  }
-
-  void addAll(Map<K, V> other) {
-    other.forEach((K key, V value) {
-      this[key] = value;
-    });
-  }
-
-  V? operator [](Object? key) {
-    return JS('var', '#.get(#)', _map, key);
-  }
-
-  void operator []=(K key, V value) {
-    JS('var', '#.set(#, #)', _map, key, value);
-    _modified();
-  }
-
-  V putIfAbsent(K key, V ifAbsent()) {
-    if (containsKey(key)) return this[key] as V;
-    V value = ifAbsent();
-    this[key] = value;
-    return value;
-  }
-
-  V? remove(Object? key) {
-    V? value = this[key];
-    JS('bool', '#.delete(#)', _map, key);
-    _modified();
-    return value;
-  }
-
-  void clear() {
-    JS('void', '#.clear()', _map);
-    _modified();
-  }
-
-  void forEach(void action(K key, V value)) {
-    var jsEntries = JS('var', '#.entries()', _map);
-    int modifications = _modifications;
-    while (true) {
-      var next = JS('var', '#.next()', jsEntries);
-      bool done = JS('bool', '#.done', next);
-      if (done) break;
-      var entry = JS('var', '#.value', next);
-      var key = JS('var', '#[0]', entry);
-      var value = JS('var', '#[1]', entry);
-      action(key, value);
-      if (modifications != _modifications) {
-        throw new ConcurrentModificationError(this);
-      }
-    }
-  }
-
-  void _modified() {
-    // Value cycles after 2^30 modifications so that modification counts are
-    // always unboxed (Smi) values. Modification detection will be missed if you
-    // make exactly some multiple of 2^30 modifications between advances of an
-    // iterator.
-    _modifications = _mask30 & (_modifications + 1);
-  }
-}
-
-class _Es6MapIterable<E> extends EfficientLengthIterable<E> {
-  final _Es6LinkedIdentityHashMap _map;
-  final bool _isKeys;
-
-  _Es6MapIterable(this._map, this._isKeys);
-
-  int get length => _map.length;
-  bool get isEmpty => _map.isEmpty;
-
-  Iterator<E> get iterator =>
-      new _Es6MapIterator<E>(_map, _map._modifications, _isKeys);
-
-  bool contains(Object? element) => _map.containsKey(element);
-
-  void forEach(void f(E element)) {
-    var jsIterator;
-    if (_isKeys) {
-      jsIterator = JS('var', '#.keys()', _map._map);
-    } else {
-      jsIterator = JS('var', '#.values()', _map._map);
-    }
-    int modifications = _map._modifications;
-    while (true) {
-      var next = JS('var', '#.next()', jsIterator);
-      bool done = JS('bool', '#.done', next);
-      if (done) break;
-      var value = JS('var', '#.value', next);
-      f(value);
-      if (modifications != _map._modifications) {
-        throw new ConcurrentModificationError(_map);
-      }
-    }
-  }
-}
-
-class _Es6MapIterator<E> implements Iterator<E> {
-  final _Es6LinkedIdentityHashMap _map;
-  final int _modifications;
-  final bool _isKeys;
-  var _jsIterator;
-  var _next;
-  E? _current;
-  bool _done = false;
-
-  _Es6MapIterator(this._map, this._modifications, this._isKeys) {
-    if (_isKeys) {
-      _jsIterator = JS('var', '#.keys()', _map._map);
-    } else {
-      _jsIterator = JS('var', '#.values()', _map._map);
-    }
-  }
-
-  E get current => _current as E;
-
-  bool moveNext() {
-    if (_modifications != _map._modifications) {
-      throw new ConcurrentModificationError(_map);
-    }
-    if (_done) return false;
-    _next = JS('var', '#.next()', _jsIterator);
-    bool done = JS('bool', '#.done', _next);
-    if (done) {
-      _current = null;
-      _done = true;
-      return false;
-    } else {
-      _current = JS('var', '#.value', _next);
-      return true;
-    }
-  }
-}
-
 // TODO(floitsch): use ES6 maps when available.
 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
   final _Equality<K> _equals;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 6d4d129..9579a76 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -478,7 +478,7 @@
   factory Map.unmodifiable(Map other) = ConstantMap<K, V>.from;
 
   @patch
-  factory Map() = JsLinkedHashMap<K, V>.es6;
+  factory Map() = JsLinkedHashMap<K, V>;
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
index fdf9d23..bd8533a 100644
--- a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -7,8 +7,6 @@
 
 part of _js_helper;
 
-const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");
-
 class JsLinkedHashMap<K, V> extends MapBase<K, V>
     implements LinkedHashMap<K, V>, InternalMap {
   int _length = 0;
@@ -35,21 +33,8 @@
   // iterated over.
   int _modifications = 0;
 
-  static bool get _supportsEs6Maps {
-    return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true',
-        'typeof Map != "undefined"');
-  }
-
   JsLinkedHashMap();
 
-  /// If ES6 Maps are available returns a linked hash-map backed by an ES6 Map.
-  @pragma('dart2js:tryInline')
-  factory JsLinkedHashMap.es6() {
-    return (_USE_ES6_MAPS && JsLinkedHashMap._supportsEs6Maps)
-        ? new Es6LinkedHashMap<K, V>()
-        : new JsLinkedHashMap<K, V>();
-  }
-
   int get length => _length;
   bool get isEmpty => _length == 0;
   bool get isNotEmpty => !isEmpty;
@@ -342,38 +327,6 @@
   }
 }
 
-class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
-  @override
-  LinkedHashMapCell? _getTableCell(var table, var key) {
-    return JS('var', '#.get(#)', table, key);
-  }
-
-  @override
-  List<LinkedHashMapCell>? _getTableBucket(var table, var key) {
-    return JS('var', '#.get(#)', table, key);
-  }
-
-  @override
-  void _setTableEntry(var table, var key, var value) {
-    JS('void', '#.set(#, #)', table, key, value);
-  }
-
-  @override
-  void _deleteTableEntry(var table, var key) {
-    JS('void', '#.delete(#)', table, key);
-  }
-
-  @override
-  bool _containsTableEntry(var table, var key) {
-    return JS('bool', '#.has(#)', table, key);
-  }
-
-  @override
-  _newHashTable() {
-    return JS('var', 'new Map()');
-  }
-}
-
 class LinkedHashMapCell {
   final dynamic hashMapCellKey;
   dynamic hashMapCellValue;
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index cbda1c3..dabd9f4 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -234,7 +234,7 @@
   /// with a [Directory] for the renamed directory.
   ///
   /// If [newPath] identifies an existing directory, then the behavior is
-  /// platform-specific. On all platforms, the future completes with an
+  /// platform-specific. On all platforms, the future completes with a
   /// [FileSystemException] if the existing directory is not empty. On POSIX
   /// systems, if [newPath] identifies an existing empty directory then that
   /// directory is deleted before this directory is renamed.
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index c9a168a..b62cc71 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -182,9 +182,6 @@
       "web_gl": {
         "uri": "web_gl/dart2js/web_gl_dart2js.dart"
       },
-      "_dart2js_runtime_metrics": {
-        "uri": "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
-      },
       "_metadata": {
         "uri": "html/html_common/metadata.dart"
       }
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 5af3cfd..ae16c86 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -549,7 +549,9 @@
       return encodeRpcError(message, kStreamAlreadySubscribed);
     }
     if (!_isAnyClientSubscribed(streamId)) {
-      if (!serviceStreams.contains(streamId) && !_vmListenStream(streamId)) {
+      final includePrivates = message.params['_includePrivateMembers'] == true;
+      if (!serviceStreams.contains(streamId) &&
+          !_vmListenStream(streamId, includePrivates)) {
         return encodeRpcError(message, kInvalidParams,
             details: "streamListen: invalid 'streamId' parameter: ${streamId}");
       }
@@ -831,7 +833,7 @@
 
 /// Subscribe to a service stream.
 @pragma("vm:external-name", "VMService_ListenStream")
-external bool _vmListenStream(String streamId);
+external bool _vmListenStream(String streamId, bool include_privates);
 
 /// Cancel a subscription to a service stream.
 @pragma("vm:external-name", "VMService_CancelStream")
diff --git a/tests/language/control_flow_collections/await_for_dynamic_null_test.dart b/tests/language/control_flow_collections/await_for_dynamic_null_test.dart
index aad701f2..36286b9 100644
--- a/tests/language/control_flow_collections/await_for_dynamic_null_test.dart
+++ b/tests/language/control_flow_collections/await_for_dynamic_null_test.dart
@@ -9,11 +9,14 @@
   asyncTest(() async {
     // Null stream.
     dynamic nullStream = null;
-    asyncExpectThrows<Error>(
-        () async => <int>[await for (var i in nullStream) 1]);
-    asyncExpectThrows<Error>(
-        () async => <int, int>{await for (var i in nullStream) 1: 1});
-    asyncExpectThrows<Error>(
-        () async => <int>{await for (var i in nullStream) 1});
+    asyncExpectThrows<Error>(() async {
+      <int>[await for (var i in nullStream) 1];
+    }());
+    asyncExpectThrows<Error>(() async {
+      <int, int>{await for (var i in nullStream) 1: 1};
+    }());
+    asyncExpectThrows<Error>(() async {
+      <int>{await for (var i in nullStream) 1};
+    }());
   });
 }
diff --git a/tests/language/control_flow_collections/await_for_test.dart b/tests/language/control_flow_collections/await_for_test.dart
index ce84fe0..d98f9f2 100644
--- a/tests/language/control_flow_collections/await_for_test.dart
+++ b/tests/language/control_flow_collections/await_for_test.dart
@@ -30,17 +30,28 @@
   Expect.listEquals(list, <int>[await for (var i in stream(list)) i]);
 
   // Await for at beginning.
-  Expect.listEquals(list, <int>[await for (var i in stream([1, 2])) i, 3, 4]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, 2])) i,
+    3,
+    4
+  ]);
 
   // Await for in middle.
-  Expect.listEquals(list, <int>[1, await for (var i in stream([2, 3])) i, 4]);
+  Expect.listEquals(list, <int>[
+    1,
+    await for (var i in stream([2, 3])) i,
+    4
+  ]);
 
   // Await for at end.
-  Expect.listEquals(list, <int>[1, 2, await for (var i in stream([3, 4])) i]);
+  Expect.listEquals(list, <int>[
+    1,
+    2,
+    await for (var i in stream([3, 4])) i
+  ]);
 
   // Empty await for.
-  Expect.listEquals(list,
-      <int>[1, 2, await for (var i in stream([])) i, 3, 4]);
+  Expect.listEquals(list, <int>[1, 2, await for (var i in stream([])) i, 3, 4]);
 
   // Multiple await fors.
   Expect.listEquals(list, <int>[
@@ -50,26 +61,44 @@
   ]);
 
   // Spread inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]
+  ]);
 
   // If inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i
+  ]);
 
   // Else inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i else i
+  ]);
 
   // For inside await for.
   Expect.listEquals(list, <int>[
-    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+    await for (var i in stream([0, 2]))
+      for (var j = 1; j <= 2; j++) i + j
   ]);
 
   // Does not flatten nested collection literal.
-  Expect.listEquals([1], [await for (var i in stream([1])) [i]].first);
-  Expect.mapEquals({1: 1}, [await for (var i in stream([1])) {i: i}].first);
-  Expect.setEquals({1}, [await for (var i in stream([1])) {i}].first);
+  Expect.listEquals(
+      [1],
+      [
+        await for (var i in stream([1])) [i]
+      ].first);
+  Expect.mapEquals(
+      {1: 1},
+      [
+        await for (var i in stream([1])) {i: i}
+      ].first);
+  Expect.setEquals(
+      {1},
+      [
+        await for (var i in stream([1])) {i}
+      ].first);
 }
 
 Future<void> testMap() async {
@@ -77,26 +106,30 @@
   Expect.mapEquals(map, <int, int>{await for (var i in stream(list)) i: i});
 
   // Await for at beginning.
-  Expect.mapEquals(map,
-      <int, int>{await for (var i in stream([1, 2])) i: i, 3: 3, 4: 4});
-
-  // Await for in middle.
-  Expect.mapEquals(map,
-      <int, int>{1: 1, await for (var i in stream([2, 3])) i: i, 4: 4});
-
-  // Await for at end.
-  Expect.mapEquals(map,
-      <int, int>{1: 1, 2: 2, await for (var i in stream([3, 4])) i: i});
-
-  // Empty await for.
   Expect.mapEquals(map, <int, int>{
-    1: 1,
-    await for (var i in stream([])) i: i,
-    2: 2,
+    await for (var i in stream([1, 2])) i: i,
     3: 3,
     4: 4
   });
 
+  // Await for in middle.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    await for (var i in stream([2, 3])) i: i,
+    4: 4
+  });
+
+  // Await for at end.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    2: 2,
+    await for (var i in stream([3, 4])) i: i
+  });
+
+  // Empty await for.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, await for (var i in stream([])) i: i, 2: 2, 3: 3, 4: 4});
+
   // Multiple await fors.
   Expect.mapEquals(map, <int, int>{
     await for (var i in stream([1])) i: i,
@@ -106,18 +139,22 @@
 
   // Spread inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([0, 2]))
-      ...<int, int>{1 + i: 1 + i, 2 + i: 2 + i}
+    await for (var i in stream([0, 2])) ...<int, int>{
+      1 + i: 1 + i,
+      2 + i: 2 + i
+    }
   });
 
   // If inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i: i
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i: i
   });
 
   // Else inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i: -i else i: i
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i: -i else i: i
   });
 
   // For inside await for.
@@ -132,17 +169,28 @@
   Expect.setEquals(set, <int>{await for (var i in stream(list)) i});
 
   // Await for at beginning.
-  Expect.setEquals(set, <int>{await for (var i in stream([1, 2])) i, 3, 4});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, 2])) i,
+    3,
+    4
+  });
 
   // Await for in middle.
-  Expect.setEquals(set, <int>{1, await for (var i in stream([2, 3])) i, 4});
+  Expect.setEquals(set, <int>{
+    1,
+    await for (var i in stream([2, 3])) i,
+    4
+  });
 
   // Await for at end.
-  Expect.setEquals(set, <int>{1, 2, await for (var i in stream([3, 4])) i});
+  Expect.setEquals(set, <int>{
+    1,
+    2,
+    await for (var i in stream([3, 4])) i
+  });
 
   // Empty await for.
-  Expect.setEquals(set,
-      <int>{1, await for (var i in stream([])) i, 2, 3, 4});
+  Expect.setEquals(set, <int>{1, await for (var i in stream([])) i, 2, 3, 4});
 
   // Multiple await fors.
   Expect.setEquals(set, <int>{
@@ -152,26 +200,44 @@
   });
 
   // Spread inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]
+  });
 
   // If inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i
+  });
 
   // Else inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i else i
+  });
 
   // For inside await for.
   Expect.setEquals(set, <int>{
-    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+    await for (var i in stream([0, 2]))
+      for (var j = 1; j <= 2; j++) i + j
   });
 
   // Does not flatten nested collection literal.
-  Expect.listEquals([1], {await for (var i in stream([1])) [i]}.first);
-  Expect.mapEquals({1: 1}, {await for (var i in stream([1])) {i: i}}.first);
-  Expect.setEquals({1}, {await for (var i in stream([1])) {i}}.first);
+  Expect.listEquals(
+      [1],
+      {
+        await for (var i in stream([1])) [i]
+      }.first);
+  Expect.mapEquals(
+      {1: 1},
+      {
+        await for (var i in stream([1])) {i: i}
+      }.first);
+  Expect.setEquals(
+      {1},
+      {
+        await for (var i in stream([1])) {i}
+      }.first);
 }
 
 Future<void> testDuplicateKeys() async {
@@ -207,28 +273,46 @@
   Expect.equals("1:a,2:a", map.keys.join(","));
   Expect.equals("2,4", map.values.join(","));
 
-  var set = <Equality>{e1a, await for (var i in stream([0, 1, 2])) keys[i]};
+  var set = <Equality>{
+    e1a,
+    await for (var i in stream([0, 1, 2])) keys[i]
+  };
   Expect.equals("1:a,2:a", set.join(","));
 }
 
 Future<void> testRuntimeErrors() async {
   // Cast variable.
   dynamic nonStream = 3;
-  asyncExpectThrows<TypeError>(
-      () async => <int>[await for (int i in nonStream) 1]);
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (int i in nonStream) 1: 1});
-  asyncExpectThrows<TypeError>(
-      () async => <int>{await for (int i in nonStream) 1});
+  asyncExpectThrows<TypeError>(() async {
+    <int>[await for (int i in nonStream) 1];
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{await for (int i in nonStream) 1: 1};
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int>{await for (int i in nonStream) 1};
+  }());
 
   // Wrong element type.
   dynamic nonInt = "string";
-  asyncExpectThrows<TypeError>(
-      () async => <int>[await for (var i in stream([1])) nonInt]);
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (var i in stream([1])) nonInt: 1});
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (var i in stream([1])) 1: nonInt});
-  asyncExpectThrows<TypeError>(
-      () async => <int>{await for (var i in stream([1])) nonInt});
+  asyncExpectThrows<TypeError>(() async {
+    <int>[
+      await for (var i in stream([1])) nonInt
+    ];
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{
+      await for (var i in stream([1])) nonInt: 1
+    };
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{
+      await for (var i in stream([1])) 1: nonInt
+    };
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int>{
+      await for (var i in stream([1])) nonInt
+    };
+  }());
 }
diff --git a/tests/language_2/control_flow_collections/await_for_null_test.dart b/tests/language_2/control_flow_collections/await_for_null_test.dart
index 47529b2..482cbff 100644
--- a/tests/language_2/control_flow_collections/await_for_null_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_null_test.dart
@@ -11,11 +11,14 @@
   asyncTest(() async {
     // Null stream.
     Stream<int> nullStream = null;
-    asyncExpectThrows<Error>(
-        () async => <int>[await for (var i in nullStream) 1]);
-    asyncExpectThrows<Error>(
-        () async => <int, int>{await for (var i in nullStream) 1: 1});
-    asyncExpectThrows<Error>(
-        () async => <int>{await for (var i in nullStream) 1});
+    asyncExpectThrows<Error>(() async {
+      <int>[await for (var i in nullStream) 1];
+    }());
+    asyncExpectThrows<Error>(() async {
+      <int, int>{await for (var i in nullStream) 1: 1};
+    }());
+    asyncExpectThrows<Error>(() async {
+      <int>{await for (var i in nullStream) 1};
+    }());
   });
 }
diff --git a/tests/language_2/control_flow_collections/await_for_test.dart b/tests/language_2/control_flow_collections/await_for_test.dart
index 402820b..d661143 100644
--- a/tests/language_2/control_flow_collections/await_for_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_test.dart
@@ -32,17 +32,28 @@
   Expect.listEquals(list, <int>[await for (var i in stream(list)) i]);
 
   // Await for at beginning.
-  Expect.listEquals(list, <int>[await for (var i in stream([1, 2])) i, 3, 4]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, 2])) i,
+    3,
+    4
+  ]);
 
   // Await for in middle.
-  Expect.listEquals(list, <int>[1, await for (var i in stream([2, 3])) i, 4]);
+  Expect.listEquals(list, <int>[
+    1,
+    await for (var i in stream([2, 3])) i,
+    4
+  ]);
 
   // Await for at end.
-  Expect.listEquals(list, <int>[1, 2, await for (var i in stream([3, 4])) i]);
+  Expect.listEquals(list, <int>[
+    1,
+    2,
+    await for (var i in stream([3, 4])) i
+  ]);
 
   // Empty await for.
-  Expect.listEquals(list,
-      <int>[1, 2, await for (var i in stream([])) i, 3, 4]);
+  Expect.listEquals(list, <int>[1, 2, await for (var i in stream([])) i, 3, 4]);
 
   // Multiple await fors.
   Expect.listEquals(list, <int>[
@@ -52,38 +63,58 @@
   ]);
 
   // Spread inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]
+  ]);
 
   // If inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i
+  ]);
 
   // Else inside await for.
-  Expect.listEquals(list,
-      <int>[await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i]);
+  Expect.listEquals(list, <int>[
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i else i
+  ]);
 
   // For inside await for.
   Expect.listEquals(list, <int>[
-    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+    await for (var i in stream([0, 2]))
+      for (var j = 1; j <= 2; j++) i + j
   ]);
 
   // Does not flatten nested collection literal.
-  Expect.listEquals([1], [await for (var i in stream([1])) [i]].first);
-  Expect.mapEquals({1: 1}, [await for (var i in stream([1])) {i: i}].first);
-  Expect.setEquals({1}, [await for (var i in stream([1])) {i}].first);
+  Expect.listEquals(
+      [1],
+      [
+        await for (var i in stream([1])) [i]
+      ].first);
+  Expect.mapEquals(
+      {1: 1},
+      [
+        await for (var i in stream([1])) {i: i}
+      ].first);
+  Expect.setEquals(
+      {1},
+      [
+        await for (var i in stream([1])) {i}
+      ].first);
 
   // Downcast stream.
   Object obj = stream([1, 2, 3, 4]);
   Expect.listEquals(list, <int>[await for (var n in obj) n]);
 
   // Downcast variable.
-  Expect.listEquals(list,
-      <int>[await for (int n in numStream([1, 2, 3, 4])) n]);
+  Expect.listEquals(list, <int>[
+    await for (int n in numStream([1, 2, 3, 4])) n
+  ]);
 
   // Downcast element.
-  Expect.listEquals(list,
-      <int>[await for (num n in numStream([1, 2, 3, 4])) n]);
+  Expect.listEquals(list, <int>[
+    await for (num n in numStream([1, 2, 3, 4])) n
+  ]);
 }
 
 Future<void> testMap() async {
@@ -91,26 +122,30 @@
   Expect.mapEquals(map, <int, int>{await for (var i in stream(list)) i: i});
 
   // Await for at beginning.
-  Expect.mapEquals(map,
-      <int, int>{await for (var i in stream([1, 2])) i: i, 3: 3, 4: 4});
-
-  // Await for in middle.
-  Expect.mapEquals(map,
-      <int, int>{1: 1, await for (var i in stream([2, 3])) i: i, 4: 4});
-
-  // Await for at end.
-  Expect.mapEquals(map,
-      <int, int>{1: 1, 2: 2, await for (var i in stream([3, 4])) i: i});
-
-  // Empty await for.
   Expect.mapEquals(map, <int, int>{
-    1: 1,
-    await for (var i in stream([])) i: i,
-    2: 2,
+    await for (var i in stream([1, 2])) i: i,
     3: 3,
     4: 4
   });
 
+  // Await for in middle.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    await for (var i in stream([2, 3])) i: i,
+    4: 4
+  });
+
+  // Await for at end.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    2: 2,
+    await for (var i in stream([3, 4])) i: i
+  });
+
+  // Empty await for.
+  Expect.mapEquals(map,
+      <int, int>{1: 1, await for (var i in stream([])) i: i, 2: 2, 3: 3, 4: 4});
+
   // Multiple await fors.
   Expect.mapEquals(map, <int, int>{
     await for (var i in stream([1])) i: i,
@@ -120,18 +155,22 @@
 
   // Spread inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([0, 2]))
-      ...<int, int>{1 + i: 1 + i, 2 + i: 2 + i}
+    await for (var i in stream([0, 2])) ...<int, int>{
+      1 + i: 1 + i,
+      2 + i: 2 + i
+    }
   });
 
   // If inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i: i
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i: i
   });
 
   // Else inside await for.
   Expect.mapEquals(map, <int, int>{
-    await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i: -i else i: i
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i: -i else i: i
   });
 
   // For inside await for.
@@ -145,12 +184,14 @@
   Expect.mapEquals(map, <int, int>{await for (var n in obj) n: n});
 
   // Downcast variable.
-  Expect.mapEquals(map,
-      <int, int>{await for (int n in numStream([1, 2, 3, 4])) n: n});
+  Expect.mapEquals(map, <int, int>{
+    await for (int n in numStream([1, 2, 3, 4])) n: n
+  });
 
   // Downcast element.
-  Expect.mapEquals(map,
-      <int, int>{await for (num n in numStream([1, 2, 3, 4])) n: n});
+  Expect.mapEquals(map, <int, int>{
+    await for (num n in numStream([1, 2, 3, 4])) n: n
+  });
 }
 
 Future<void> testSet() async {
@@ -158,17 +199,28 @@
   Expect.setEquals(set, <int>{await for (var i in stream(list)) i});
 
   // Await for at beginning.
-  Expect.setEquals(set, <int>{await for (var i in stream([1, 2])) i, 3, 4});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, 2])) i,
+    3,
+    4
+  });
 
   // Await for in middle.
-  Expect.setEquals(set, <int>{1, await for (var i in stream([2, 3])) i, 4});
+  Expect.setEquals(set, <int>{
+    1,
+    await for (var i in stream([2, 3])) i,
+    4
+  });
 
   // Await for at end.
-  Expect.setEquals(set, <int>{1, 2, await for (var i in stream([3, 4])) i});
+  Expect.setEquals(set, <int>{
+    1,
+    2,
+    await for (var i in stream([3, 4])) i
+  });
 
   // Empty await for.
-  Expect.setEquals(set,
-      <int>{1, await for (var i in stream([])) i, 2, 3, 4});
+  Expect.setEquals(set, <int>{1, await for (var i in stream([])) i, 2, 3, 4});
 
   // Multiple await fors.
   Expect.setEquals(set, <int>{
@@ -178,36 +230,58 @@
   });
 
   // Spread inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([0, 2])) ...<int>[1 + i, 2 + i]
+  });
 
   // If inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([1, 9, 2, 3, 9, 4])) if (i != 9) i});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, 9, 2, 3, 9, 4]))
+      if (i != 9) i
+  });
 
   // Else inside await for.
-  Expect.setEquals(set,
-      <int>{await for (var i in stream([1, -2, 3, -4])) if (i < 0) -i else i});
+  Expect.setEquals(set, <int>{
+    await for (var i in stream([1, -2, 3, -4]))
+      if (i < 0) -i else i
+  });
 
   // For inside await for.
   Expect.setEquals(set, <int>{
-    await for (var i in stream([0, 2])) for (var j = 1; j <= 2; j++) i + j
+    await for (var i in stream([0, 2]))
+      for (var j = 1; j <= 2; j++) i + j
   });
 
   // Does not flatten nested collection literal.
-  Expect.listEquals([1], {await for (var i in stream([1])) [i]}.first);
-  Expect.mapEquals({1: 1}, {await for (var i in stream([1])) {i: i}}.first);
-  Expect.setEquals({1}, {await for (var i in stream([1])) {i}}.first);
+  Expect.listEquals(
+      [1],
+      {
+        await for (var i in stream([1])) [i]
+      }.first);
+  Expect.mapEquals(
+      {1: 1},
+      {
+        await for (var i in stream([1])) {i: i}
+      }.first);
+  Expect.setEquals(
+      {1},
+      {
+        await for (var i in stream([1])) {i}
+      }.first);
 
   // Downcast stream.
   Object obj = stream([1, 2, 3, 4]);
   Expect.setEquals(set, <int>{await for (var n in obj) n});
 
   // Downcast variable.
-  Expect.setEquals(set, <int>{await for (int n in numStream([1, 2, 3, 4])) n});
+  Expect.setEquals(set, <int>{
+    await for (int n in numStream([1, 2, 3, 4])) n
+  });
 
   // Downcast element.
-  Expect.setEquals(set, <int>{await for (num n in numStream([1, 2, 3, 4])) n});
+  Expect.setEquals(set, <int>{
+    await for (num n in numStream([1, 2, 3, 4])) n
+  });
 }
 
 Future<void> testDuplicateKeys() async {
@@ -243,28 +317,46 @@
   Expect.equals("1:a,2:a", map.keys.join(","));
   Expect.equals("2,4", map.values.join(","));
 
-  var set = <Equality>{e1a, await for (var i in stream([0, 1, 2])) keys[i]};
+  var set = <Equality>{
+    e1a,
+    await for (var i in stream([0, 1, 2])) keys[i]
+  };
   Expect.equals("1:a,2:a", set.join(","));
 }
 
 Future<void> testRuntimeErrors() async {
   // Cast variable.
   dynamic nonStream = 3;
-  asyncExpectThrows<TypeError>(
-      () async => <int>[await for (int i in nonStream) 1]);
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (int i in nonStream) 1: 1});
-  asyncExpectThrows<TypeError>(
-      () async => <int>{await for (int i in nonStream) 1});
+  asyncExpectThrows<TypeError>(() async {
+    <int>[await for (int i in nonStream) 1];
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{await for (int i in nonStream) 1: 1};
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int>{await for (int i in nonStream) 1};
+  }());
 
   // Wrong element type.
   dynamic nonInt = "string";
-  asyncExpectThrows<TypeError>(
-      () async => <int>[await for (var i in stream([1])) nonInt]);
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (var i in stream([1])) nonInt: 1});
-  asyncExpectThrows<TypeError>(
-      () async => <int, int>{await for (var i in stream([1])) 1: nonInt});
-  asyncExpectThrows<TypeError>(
-      () async => <int>{await for (var i in stream([1])) nonInt});
+  asyncExpectThrows<TypeError>(() async {
+    <int>[
+      await for (var i in stream([1])) nonInt
+    ];
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{
+      await for (var i in stream([1])) nonInt: 1
+    };
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int, int>{
+      await for (var i in stream([1])) 1: nonInt
+    };
+  }());
+  asyncExpectThrows<TypeError>(() async {
+    <int>{
+      await for (var i in stream([1])) nonInt
+    };
+  }());
 }
diff --git a/tests/lib/js/js_util/async_test.dart b/tests/lib/js/js_util/async_test.dart
index 9172fe7..7e3316b 100644
--- a/tests/lib/js/js_util/async_test.dart
+++ b/tests/lib/js/js_util/async_test.dart
@@ -42,8 +42,9 @@
   }
 
   Future<void> testRejectedPromise() async {
-    asyncExpectThrows<String>(() => js_util.promiseToFuture(rejectedPromise),
-        (String error) => error == 'rejected');
+    final String error = await asyncExpectThrows<String>(
+        js_util.promiseToFuture(rejectedPromise));
+    expect(error, equals('rejected'));
   }
 
   Future<void> testReturnResolvedPromise() async {
diff --git a/tests/lib_2/js/js_util/async_test.dart b/tests/lib_2/js/js_util/async_test.dart
index 6a49358..a913157 100644
--- a/tests/lib_2/js/js_util/async_test.dart
+++ b/tests/lib_2/js/js_util/async_test.dart
@@ -44,8 +44,9 @@
   }
 
   Future<void> testRejectedPromise() async {
-    asyncExpectThrows<String>(() => js_util.promiseToFuture(rejectedPromise),
-        (String error) => error == 'rejected');
+    final String error = await asyncExpectThrows<String>(
+        js_util.promiseToFuture(rejectedPromise));
+    expect(error, equals('rejected'));
   }
 
   Future<void> testReturnResolvedPromise() async {
diff --git a/tests/standalone/io/http_parser_header_add_test.dart b/tests/standalone/io/http_parser_header_add_test.dart
index 4421733..4fdf602 100644
--- a/tests/standalone/io/http_parser_header_add_test.dart
+++ b/tests/standalone/io/http_parser_header_add_test.dart
@@ -17,19 +17,15 @@
     request.response.close();
   });
 
-  final completer = Completer<void>();
   // The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
   final client = HttpClient()..userAgent = 'Bob’s browser';
-  asyncExpectThrows<FormatException>(() async {
-    try {
-      await client.open("CONNECT", "127.0.0.1", server.port, "/");
-    } finally {
-      client.close(force: true);
-      server.close();
-      completer.complete();
-    }
-  });
-  await completer.future;
+  try {
+    await asyncExpectThrows<FormatException>(
+        client.open("CONNECT", "127.0.0.1", server.port, "/"));
+  } finally {
+    client.close(force: true);
+    server.close();
+  }
 }
 
 main() {
diff --git a/tests/standalone/io/io_override_test.dart b/tests/standalone/io/io_override_test.dart
index fdd49ba..4fe9c66 100644
--- a/tests/standalone/io/io_override_test.dart
+++ b/tests/standalone/io/io_override_test.dart
@@ -161,17 +161,17 @@
 }
 
 Future<Socket> socketConnect(dynamic host, int port,
-    {dynamic sourceAddress, int sourcePort = 0, Duration? timeout}) {
+    {dynamic sourceAddress, int sourcePort = 0, Duration? timeout}) async {
   throw "";
 }
 
 Future<ConnectionTask<Socket>> socketStartConnect(dynamic host, int port,
-    {dynamic sourceAddress, int sourcePort = 0}) {
+    {dynamic sourceAddress, int sourcePort = 0}) async {
   throw "";
 }
 
 Future<ServerSocket> serverSocketBind(dynamic address, int port,
-    {int backlog: 0, bool v6Only: false, bool shared: false}) {
+    {int backlog: 0, bool v6Only: false, bool shared: false}) async {
   throw "";
 }
 
@@ -217,9 +217,9 @@
       Expect.identical(
           _mockFileSystemEvent, new Directory("directory").watch());
       Expect.isTrue(new Link("link") is LinkMock);
-      asyncExpectThrows(() async => await Socket.connect(null, 0));
-      asyncExpectThrows(() async => await Socket.startConnect(null, 0));
-      asyncExpectThrows(() async => await ServerSocket.bind(null, 0));
+      asyncExpectThrows(Socket.connect(null, 0));
+      asyncExpectThrows(Socket.startConnect(null, 0));
+      asyncExpectThrows(ServerSocket.bind(null, 0));
       Expect.isTrue(stdin is StdinMock);
       Expect.identical(stdout, stdoutMock);
       Expect.identical(stderr, stderrMock);
diff --git a/tests/standalone_2/io/http_parser_header_add_test.dart b/tests/standalone_2/io/http_parser_header_add_test.dart
index 7c86ff2..e597ea3 100644
--- a/tests/standalone_2/io/http_parser_header_add_test.dart
+++ b/tests/standalone_2/io/http_parser_header_add_test.dart
@@ -19,19 +19,15 @@
     request.response.close();
   });
 
-  final completer = Completer<void>();
   // The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
   final client = HttpClient()..userAgent = 'Bob’s browser';
-  asyncExpectThrows<FormatException>(() async {
-    try {
-      await client.open("CONNECT", "127.0.0.1", server.port, "/");
-    } finally {
-      client.close(force: true);
-      server.close();
-      completer.complete();
-    }
-  });
-  await completer.future;
+  try {
+    await asyncExpectThrows<FormatException>(
+        client.open("CONNECT", "127.0.0.1", server.port, "/"));
+  } finally {
+    client.close(force: true);
+    server.close();
+  }
 }
 
 main() {
diff --git a/tools/VERSION b/tools/VERSION
index 9518591..856c72a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 157
+PRERELEASE 158
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/yaml2json.dart b/tools/yaml2json.dart
index e8b6a07..abf313d 100644
--- a/tools/yaml2json.dart
+++ b/tools/yaml2json.dart
@@ -12,8 +12,13 @@
 
 main(List<String> arguments) {
   var port = new RawReceivePort();
+  bool check = false;
+  if (arguments.contains('--check')) {
+    arguments = arguments.toList()..remove('--check');
+    check = true;
+  }
   if (arguments.length != 2) {
-    stderr.writeln("Usage: yaml2json.dart input.yaml output.json");
+    stderr.writeln("Usage: yaml2json.dart input.yaml output.json [--check]");
     exit(1);
   }
   Uri input = Uri.base.resolve(arguments[0]);
@@ -27,6 +32,23 @@
     result[key] = yaml[key];
   }
   File file = new File.fromUri(output);
-  file.writeAsStringSync(const JsonEncoder.withIndent("  ").convert(result));
+  String text = const JsonEncoder.withIndent("  ").convert(result);
+  if (check) {
+    bool needsUpdate = true;
+    if (file.existsSync()) {
+      String existingText = file.readAsStringSync();
+      needsUpdate = text != existingText;
+    }
+    if (needsUpdate) {
+      stderr.write('''
+The file ${arguments[1]} is not up to date. Regenerate using
+
+  dart tools/yaml2json.dart ${arguments[0]} ${arguments[1]}
+''');
+      exit(1);
+    }
+  } else {
+    file.writeAsStringSync(text);
+  }
   port.close();
 }