Version 2.15.0-296.0.dev

Merge commit 'f7af5c5256ee6f3a167f380722b96e8af4360b46' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a37ecd..eed2f0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## 2.16.0
+
+### Tools
+
+#### Dart command line
+
+- **Breaking Change** [#46100][]: The standalone `dartanalyzer` tool has been
+  marked deprecated as previously announced.
+  Its replacement is the `dart analyze` command.
+  Should you find any issues, or missing features, in the replacement
+  command, kindly file [an issue]][].
+
+[an issue]: https://github.com/dart-lang/sdk/issues/new
+
 ## 2.15.0
 
 ### Language
@@ -323,9 +337,12 @@
 
 #### `dart:js_util`
 
-- The `js_util` methods `getProperty`, `setProperty`, `callMethod`,
-  `callConstructor`, and `newObject` now support a generic type argument
-  to specify the return type.
+- The `js_util` methods `setProperty`, `callMethod`, and `callConstructor` have
+  been optimized to remove checks on arguments when the checks can be elided.
+  Also, those methods, along with `getProperty` and `newObject`, now support a
+  generic type argument to specify a return type. These two changes make simple
+  `js_util` usage, like reading and writing primitive properties or calling
+  methods with simple arguments, have zero overhead.
 
 #### `dart:web_sql`
 
@@ -486,6 +503,14 @@
   `dart pub get/upgrade/downgrade/add/remove` that will result in the `example/`
   folder dependencies to be updated after operating in the current directory.
 
+### Other libraries
+
+#### `package:js`
+
+- Extensions on JS interop or native `dart:html` classes can now declare
+  members as `external`. These members are equivalent to regular extension
+  members that use `js_util` to expose the underlying JavaScript.
+
 ## 2.14.4 - 2021-10-14
 
 This is a patch release that fixes:
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 0b96e08..08de605 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -9429,7 +9429,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSuperInitializerNotLast = const MessageCode(
     "SuperInitializerNotLast",
-    analyzerCodes: <String>["INVALID_SUPER_INVOCATION"],
+    analyzerCodes: <String>["SUPER_INVOCATION_NOT_LAST"],
     problemMessage: r"""Can't have initializers after 'super'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
index c4469ea..c56e634 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
@@ -15,7 +15,9 @@
   /// Assists with the same relevance are sorted alphabetically.
   static final Comparator<Assist> SORT_BY_RELEVANCE = (Assist a, Assist b) {
     if (a.kind.priority != b.kind.priority) {
-      return a.kind.priority - b.kind.priority;
+      // A higher priority indicates a higher relevance
+      // and should be sorted before a lower priority.
+      return b.kind.priority - a.kind.priority;
     }
     return a.change.message.compareTo(b.change.message);
   };
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 9f7152c..ecc14cc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -36,10 +36,11 @@
   // CodeAction class).
   final codeActionPriorities = Expando<int>();
 
-  /// A comparator that can be used to sort [CodeActions]s using priorties
-  /// in [codeActionPriorities]. The highest number priority will be sorted
-  /// before lower number priorityies. Items with the same relevance are sorted
-  /// alphabetically by their title.
+  /// A comparator that can be used to sort [CodeActions]s using priorities
+  /// in [codeActionPriorities].
+  ///
+  /// The highest number priority will be sorted before lower number priorities.
+  /// Items with the same priority are sorted alphabetically by their title.
   late final Comparator<CodeAction> _codeActionComparator =
       (CodeAction a, CodeAction b) {
     // We should never be sorting actions without priorities.
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 47624e2..c7233ba 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -73,7 +73,7 @@
   );
   static const CONVERT_INTO_ASYNC_BODY = AssistKind(
     'dart.assist.convert.bodyToAsync',
-    29,
+    31,
     'Convert to async function body',
   );
   static const CONVERT_INTO_BLOCK_BODY = AssistKind(
@@ -222,77 +222,77 @@
   // Flutter wrap specific assists
   static const FLUTTER_WRAP_GENERIC = AssistKind(
     'dart.assist.flutter.wrap.generic',
-    31,
+    29,
     'Wrap with widget...',
   );
 
   static const FLUTTER_WRAP_BUILDER = AssistKind(
     'dart.assist.flutter.wrap.builder',
-    32,
+    28,
     'Wrap with Builder',
   );
   static const FLUTTER_WRAP_CENTER = AssistKind(
     'dart.assist.flutter.wrap.center',
-    32,
+    28,
     'Wrap with Center',
   );
   static const FLUTTER_WRAP_COLUMN = AssistKind(
     'dart.assist.flutter.wrap.column',
-    32,
+    28,
     'Wrap with Column',
   );
   static const FLUTTER_WRAP_CONTAINER = AssistKind(
     'dart.assist.flutter.wrap.container',
-    32,
+    28,
     'Wrap with Container',
   );
   static const FLUTTER_WRAP_PADDING = AssistKind(
     'dart.assist.flutter.wrap.padding',
-    32,
+    28,
     'Wrap with Padding',
   );
   static const FLUTTER_WRAP_ROW = AssistKind(
     'dart.assist.flutter.wrap.row',
-    32,
+    28,
     'Wrap with Row',
   );
   static const FLUTTER_WRAP_SIZED_BOX = AssistKind(
     'dart.assist.flutter.wrap.sizedBox',
-    32,
+    28,
     'Wrap with SizedBox',
   );
   static const FLUTTER_WRAP_STREAM_BUILDER = AssistKind(
     'dart.assist.flutter.wrap.streamBuilder',
-    32,
+    28,
     'Wrap with StreamBuilder',
   );
 
   // Flutter re-order assists
   static const FLUTTER_SWAP_WITH_CHILD = AssistKind(
     'dart.assist.flutter.swap.withChild',
-    33,
+    27,
     'Swap with child',
   );
   static const FLUTTER_SWAP_WITH_PARENT = AssistKind(
     'dart.assist.flutter.swap.withParent',
-    33,
+    27,
     'Swap with parent',
   );
   static const FLUTTER_MOVE_DOWN = AssistKind(
     'dart.assist.flutter.move.down',
-    34,
+    26,
     'Move widget down',
   );
   static const FLUTTER_MOVE_UP = AssistKind(
     'dart.assist.flutter.move.up',
-    34,
+    26,
     'Move widget up',
   );
 
   // Flutter remove assist
   static const FLUTTER_REMOVE_WIDGET = AssistKind(
     'dart.assist.flutter.removeWidget',
-    35,
+    25,
     'Remove this widget',
   );
 
@@ -334,7 +334,7 @@
   static const REMOVE_TYPE_ANNOTATION = AssistKind(
     // todo (pq): unify w/ fix
     'dart.assist.remove.typeAnnotation',
-    29,
+    31,
     'Remove type annotation',
   );
   static const REPLACE_CONDITIONAL_WITH_IF_ELSE = AssistKind(
@@ -374,47 +374,47 @@
   );
   static const SURROUND_WITH_BLOCK = AssistKind(
     'dart.assist.surround.block',
-    22,
+    38,
     'Surround with block',
   );
   static const SURROUND_WITH_DO_WHILE = AssistKind(
     'dart.assist.surround.doWhile',
-    27,
+    33,
     "Surround with 'do-while'",
   );
   static const SURROUND_WITH_FOR = AssistKind(
     'dart.assist.surround.forEach',
-    26,
+    34,
     "Surround with 'for'",
   );
   static const SURROUND_WITH_FOR_IN = AssistKind(
     'dart.assist.surround.forIn',
-    25,
+    35,
     "Surround with 'for-in'",
   );
   static const SURROUND_WITH_IF = AssistKind(
     'dart.assist.surround.if',
-    23,
+    37,
     "Surround with 'if'",
   );
   static const SURROUND_WITH_SET_STATE = AssistKind(
     'dart.assist.surround.setState',
-    27,
+    33,
     "Surround with 'setState'",
   );
   static const SURROUND_WITH_TRY_CATCH = AssistKind(
     'dart.assist.surround.tryCatch',
-    28,
+    32,
     "Surround with 'try-catch'",
   );
   static const SURROUND_WITH_TRY_FINALLY = AssistKind(
     'dart.assist.surround.tryFinally',
-    29,
+    31,
     "Surround with 'try-finally'",
   );
   static const SURROUND_WITH_WHILE = AssistKind(
     'dart.assist.surround.while',
-    24,
+    36,
     "Surround with 'while'",
   );
   static const USE_CURLY_BRACES = AssistKind(
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index f695939..7782757 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -22,12 +22,14 @@
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'domain_completion_util.dart';
 import 'mocks.dart';
 import 'src/plugin/plugin_manager_test.dart';
+import 'utils/change_check.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -43,30 +45,31 @@
   Future<void> test_alreadyImported() async {
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 import 'dart:math';
 void f() {
   Rand^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    validator
-      ..hasCompletion('Random')
-      ..hasChange().assertNoFileEdits();
+    check(details)
+      ..completion.isEqualTo('Random')
+      ..change.edits.isEmpty;
   }
 
   Future<void> test_import_dart() async {
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   R^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    validator
-      ..hasCompletion('Random')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Random')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'dart:math';
 
 void f() {
@@ -94,16 +97,17 @@
 
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:aaa/a.dart');
-    validator
-      ..hasCompletion('Test')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Test')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'package:aaa/a.dart';
 
 void f() {
@@ -119,16 +123,17 @@
 
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:test/a.dart');
-    validator
-      ..hasCompletion('Test')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Test')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'package:test/a.dart';
 
 void f() {
@@ -160,7 +165,7 @@
     expect(response.error?.code, RequestErrorCode.INVALID_FILE_PATH_FORMAT);
   }
 
-  Future<GetSuggestionDetails2Validator> _getCodeDetails({
+  Future<CompletionGetSuggestionDetails2Result> _getCodeDetails({
     required String path,
     required String content,
     required String completion,
@@ -184,7 +189,7 @@
     );
   }
 
-  Future<GetSuggestionDetails2Validator> _getDetails({
+  Future<CompletionGetSuggestionDetails2Result> _getDetails({
     required String path,
     required int completionOffset,
     required String completion,
@@ -198,11 +203,10 @@
     ).toRequest('0');
 
     var response = await _handleSuccessfulRequest(request);
-    var result = CompletionGetSuggestionDetails2Result.fromResponse(response);
-    return GetSuggestionDetails2Validator(result);
+    return CompletionGetSuggestionDetails2Result.fromResponse(response);
   }
 
-  Future<GetSuggestionDetails2Validator> _getTestCodeDetails(
+  Future<CompletionGetSuggestionDetails2Result> _getTestCodeDetails(
     String content, {
     required String completion,
     required String libraryUri,
@@ -2548,20 +2552,6 @@
   }
 }
 
-class GetSuggestionDetails2Validator {
-  final CompletionGetSuggestionDetails2Result result;
-
-  GetSuggestionDetails2Validator(this.result);
-
-  SourceChangeValidator hasChange() {
-    return SourceChangeValidator(result.change);
-  }
-
-  void hasCompletion(Object completion) {
-    expect(result.completion, completion);
-  }
-}
-
 class PubPackageAnalysisServerTest with ResourceProviderMixin {
   late final MockServerChannel serverChannel;
   late final AnalysisServer server;
@@ -2739,32 +2729,6 @@
   }
 }
 
-class SourceChangeValidator {
-  final SourceChange change;
-
-  SourceChangeValidator(this.change);
-
-  void assertNoFileEdits() {
-    expect(change.edits, isEmpty);
-  }
-
-  SourceFileEditValidator hasFileEdit(String path) {
-    var edit = change.edits.singleWhere((e) => e.file == path);
-    return SourceFileEditValidator(edit);
-  }
-}
-
-class SourceFileEditValidator {
-  final SourceFileEdit edit;
-
-  SourceFileEditValidator(this.edit);
-
-  void whenApplied(String applyTo, Object expected) {
-    var actual = SourceEdit.applySequence(applyTo, edit.edits);
-    expect(actual, expected);
-  }
-}
-
 class SuggestionsValidator {
   final List<CompletionSuggestion> suggestions;
   final List<String>? libraryUrisToImport;
@@ -2853,3 +2817,21 @@
     return withKind(CompletionSuggestionKind.IDENTIFIER);
   }
 }
+
+extension on CheckTarget<CompletionGetSuggestionDetails2Result> {
+  @useResult
+  CheckTarget<String> get completion {
+    return nest(
+      value.completion,
+      (selected) => 'has completion ${valueStr(selected)}',
+    );
+  }
+
+  @useResult
+  CheckTarget<SourceChange> get change {
+    return nest(
+      value.change,
+      (selected) => 'has change ${valueStr(selected)}',
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index 2797109..d814a75 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -393,6 +393,39 @@
     }
   }
 
+  Future<void> test_sort() async {
+    const content = '''
+    import 'package:flutter/widgets.dart';
+
+    build() => Contai^ner(child: Container());
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+      workspaceCapabilities:
+          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+    );
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        position: positionFromMarker(content));
+    final names = codeActions.map(
+      (e) => e.map((command) => command.title, (action) => action.title),
+    );
+
+    expect(
+      names,
+      containsAllInOrder([
+        // Check the ordering for two well-known assists that should always be
+        // sorted this way.
+        // https://github.com/Dart-Code/Dart-Code/issues/3646
+        'Wrap with widget...',
+        'Remove this widget',
+      ]),
+    );
+  }
+
   List<TextDocumentEdit> _extractTextDocumentEdits(
           Either2<
                   List<TextDocumentEdit>,
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 972198c..c60efba 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -57,7 +57,7 @@
       offset: completionOffset,
     );
 
-    var directives = request.target.unit.directives;
+    var directives = resolvedUnit.unit.directives;
 
     var imports = request.libraryElement.imports;
     expect(imports, hasLength(directives.length + 1));
diff --git a/pkg/analysis_server/test/utils/change_check.dart b/pkg/analysis_server/test/utils/change_check.dart
new file mode 100644
index 0000000..3cd3e2b
--- /dev/null
+++ b/pkg/analysis_server/test/utils/change_check.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
+
+extension SourceChangeExtension on CheckTarget<SourceChange> {
+  @useResult
+  CheckTarget<List<SourceFileEdit>> get edits {
+    return nest(value.edits, (value) => 'has edits ${valueStr(value)}');
+  }
+
+  CheckTarget<SourceFileEdit> hasFileEdit(String path) {
+    return nest(
+      value.edits.singleWhere((e) => e.file == path),
+      (selected) => 'has edit ${valueStr(selected)}',
+    );
+  }
+}
+
+extension SourceFileEditExtension on CheckTarget<SourceFileEdit> {
+  @useResult
+  CheckTarget<String> appliedTo(String applyTo) {
+    var actual = SourceEdit.applySequence(applyTo, value.edits);
+    return nest(
+      actual,
+      (selected) => 'produces ${valueStr(selected)}',
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 6e3a83b..950eb5b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -256,7 +256,6 @@
   CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
   CompileTimeErrorCode.INVALID_OVERRIDE,
   CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
-  CompileTimeErrorCode.INVALID_SUPER_INVOCATION,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
@@ -407,6 +406,7 @@
   CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
   CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+  CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
   CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
   CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
   CompileTimeErrorCode.TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS,
diff --git a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
index 108cc22..6d06e03 100644
--- a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
+++ b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
@@ -62,6 +62,17 @@
       } else {
         _errorReporter.reportErrorForNode(errorCode, expression, arguments);
       }
+    } else if (!_resolver.definingLibrary.isNonNullableByDefault) {
+      if (expression is InstanceCreationExpression) {
+        // In pre-null safety code, an implicit cast from a supertype is allowed
+        // unless the expression is an explicit instance creation expression,
+        // with the idea that the cast would likely fail at runtime.
+        var constructor = expression.constructorName.staticElement;
+        if (constructor == null || !constructor.isFactory) {
+          _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+          return;
+        }
+      }
     }
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index c9e3ac0..2dd25ca 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -7381,51 +7381,6 @@
   );
 
   /**
-   * No parameters.
-   */
-  // #### Description
-  //
-  // The analyzer produces this diagnostic when the initializer list of a
-  // constructor contains an invocation of a constructor in the superclass, but
-  // the invocation isn't the last item in the initializer list.
-  //
-  // #### Example
-  //
-  // The following code produces this diagnostic because the invocation of the
-  // superclass' constructor isn't the last item in the initializer list:
-  //
-  // ```dart
-  // class A {
-  //   A(int x);
-  // }
-  //
-  // class B extends A {
-  //   B(int x) : [!super!](x), assert(x >= 0);
-  // }
-  // ```
-  //
-  // #### Common fixes
-  //
-  // Move the invocation of the superclass' constructor to the end of the
-  // initializer list:
-  //
-  // ```dart
-  // class A {
-  //   A(int x);
-  // }
-  //
-  // class B extends A {
-  //   B(int x) : assert(x >= 0), super(x);
-  // }
-  // ```
-  static const CompileTimeErrorCode INVALID_SUPER_INVOCATION =
-      CompileTimeErrorCode(
-    'INVALID_SUPER_INVOCATION',
-    "The superclass call must be last in an initializer list: '{0}'.",
-    hasPublishedDocs: true,
-  );
-
-  /**
    * Parameters:
    * 0: the name of the type parameter
    */
@@ -12892,6 +12847,52 @@
   );
 
   /**
+   * Parameters:
+   * 0: the superinitializer
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the initializer list of a
+  // constructor contains an invocation of a constructor in the superclass, but
+  // the invocation isn't the last item in the initializer list.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the invocation of the
+  // superclass' constructor isn't the last item in the initializer list:
+  //
+  // ```dart
+  // class A {
+  //   A(int x);
+  // }
+  //
+  // class B extends A {
+  //   B(int x) : [!super!](x), assert(x >= 0);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Move the invocation of the superclass' constructor to the end of the
+  // initializer list:
+  //
+  // ```dart
+  // class A {
+  //   A(int x);
+  // }
+  //
+  // class B extends A {
+  //   B(int x) : assert(x >= 0), super(x);
+  // }
+  // ```
+  static const CompileTimeErrorCode SUPER_INVOCATION_NOT_LAST =
+      CompileTimeErrorCode(
+    'SUPER_INVOCATION_NOT_LAST',
+    "The superconstructor call must be last in an initializer list: '{0}'.",
+    hasPublishedDocs: true,
+  );
+
+  /**
    * No parameters.
    */
   // #### Description
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 0159195..6ce8f76 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -191,10 +191,6 @@
         _reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message,
             offset, length);
         return;
-      case "INVALID_SUPER_INVOCATION":
-        errorReporter?.reportErrorForOffset(
-            CompileTimeErrorCode.INVALID_SUPER_INVOCATION, offset, length);
-        return;
       case "MISSING_DIGIT":
         errorReporter?.reportErrorForOffset(
             ScannerErrorCode.MISSING_DIGIT, offset, length);
@@ -265,6 +261,10 @@
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.RETURN_IN_GENERATOR, offset, length);
         return;
+      case "SUPER_INVOCATION_NOT_LAST":
+        errorReporter?.reportErrorForOffset(
+            CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, offset, length);
+        return;
       case "SUPER_IN_REDIRECTING_CONSTRUCTOR":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e140ee8..85bde05 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -517,7 +517,7 @@
       }
       _constructorFieldsVerifier.verify(node);
       _checkForRedirectingConstructorErrorCodes(node);
-      _checkForMultipleSuperInitializers(node);
+      _checkForConflictingInitializerErrorCodes(node);
       _checkForRecursiveConstructorRedirect(node, element);
       if (!_checkForRecursiveFactoryRedirect(node, element)) {
         _checkForAllRedirectConstructorErrorCodes(node);
@@ -1848,6 +1848,99 @@
     }
   }
 
+  /// Check that the given constructor [declaration] has a valid combination of
+  /// redirecting constructor invocation(s), super constructor invocation(s),
+  /// field initializers, and assert initializers.
+  void _checkForConflictingInitializerErrorCodes(
+      ConstructorDeclaration declaration) {
+    // Count and check each redirecting initializer.
+    var redirectingInitializerCount = 0;
+    var superInitializerCount = 0;
+    late SuperConstructorInvocation superInitializer;
+    for (ConstructorInitializer initializer in declaration.initializers) {
+      if (initializer is RedirectingConstructorInvocation) {
+        if (redirectingInitializerCount > 0) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
+              initializer);
+        }
+        if (declaration.factoryKeyword == null) {
+          RedirectingConstructorInvocation invocation = initializer;
+          var redirectingElement = invocation.staticElement;
+          if (redirectingElement == null) {
+            String enclosingNamedType = _enclosingClass!.displayName;
+            String constructorStrName = enclosingNamedType;
+            if (invocation.constructorName != null) {
+              constructorStrName += ".${invocation.constructorName!.name}";
+            }
+            errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
+                invocation,
+                [constructorStrName, enclosingNamedType]);
+          } else {
+            if (redirectingElement.isFactory) {
+              errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode
+                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+                  initializer);
+            }
+          }
+        }
+        // [declaration] is a redirecting constructor via a redirecting
+        // initializer.
+        _checkForRedirectToNonConstConstructor(
+          declaration.declaredElement!,
+          initializer.staticElement,
+          initializer.constructorName ?? initializer.thisKeyword,
+        );
+        redirectingInitializerCount++;
+      } else if (initializer is SuperConstructorInvocation) {
+        if (superInitializerCount == 1) {
+          // Only report the second (first illegal) superinitializer.
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
+        }
+        superInitializer = initializer;
+        superInitializerCount++;
+      }
+    }
+    // Check for initializers which are illegal when alongside a redirecting
+    // initializer.
+    if (redirectingInitializerCount > 0) {
+      for (ConstructorInitializer initializer in declaration.initializers) {
+        if (initializer is SuperConstructorInvocation) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+        if (initializer is ConstructorFieldInitializer) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+        if (initializer is AssertInitializer) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+      }
+    }
+    if (redirectingInitializerCount == 0 &&
+        superInitializerCount == 1 &&
+        superInitializer != declaration.initializers.last) {
+      var superNamedType = _enclosingClass!.supertype!.element.displayName;
+      var constructorStrName = superNamedType;
+      var constructorName = superInitializer.constructorName;
+      if (constructorName != null) {
+        constructorStrName += '.${constructorName.name}';
+      }
+      errorReporter.reportErrorForToken(
+          CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
+          superInitializer.superKeyword,
+          [constructorStrName]);
+    }
+  }
+
   /// Verify that if the given [constructor] declaration is 'const' then there
   /// are no invocations of non-'const' super constructors, and that there are
   /// no instance variables mixed in.
@@ -3270,22 +3363,6 @@
     }
   }
 
-  /// Verify that the given [constructor] has at most one 'super' initializer.
-  ///
-  /// See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
-  void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
-    bool hasSuperInitializer = false;
-    for (ConstructorInitializer initializer in constructor.initializers) {
-      if (initializer is SuperConstructorInvocation) {
-        if (hasSuperInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
-        }
-        hasSuperInitializer = true;
-      }
-    }
-  }
-
   /// Checks to ensure that the given native function [body] is in SDK code.
   ///
   /// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
@@ -3728,112 +3805,44 @@
     return true;
   }
 
-  /// Check that the given constructor [declaration] has a valid combination of
-  /// redirected constructor invocation(s), super constructor invocations and
-  /// field initializers.
-  ///
-  /// See [CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS],
-  /// [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and
-  /// [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR].
+  /// Check that the given constructor [declaration] has a valid redirected
+  /// constructor.
   void _checkForRedirectingConstructorErrorCodes(
       ConstructorDeclaration declaration) {
-    // Check for default values in the parameters
+    // Check for default values in the parameters.
     var redirectedConstructor = declaration.redirectedConstructor;
-    if (redirectedConstructor != null) {
-      for (FormalParameter parameter in declaration.parameters.parameters) {
-        if (parameter is DefaultFormalParameter &&
-            parameter.defaultValue != null) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode
-                  .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
-              parameter.identifier!);
-        }
-      }
-      var redirectedElement = redirectedConstructor.staticElement;
-      _checkForRedirectToNonConstConstructor(
-        declaration.declaredElement!,
-        redirectedElement,
-        redirectedConstructor,
-      );
-      var redirectedClass = redirectedElement?.enclosingElement;
-      if (redirectedClass is ClassElement &&
-          redirectedClass.isAbstract &&
-          redirectedElement != null &&
-          !redirectedElement.isFactory) {
-        String enclosingNamedType = _enclosingClass!.displayName;
-        String constructorStrName = enclosingNamedType;
-        if (declaration.name != null) {
-          constructorStrName += ".${declaration.name!.name}";
-        }
+    if (redirectedConstructor == null) {
+      return;
+    }
+    for (FormalParameter parameter in declaration.parameters.parameters) {
+      if (parameter is DefaultFormalParameter &&
+          parameter.defaultValue != null) {
         errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
-            redirectedConstructor,
-            [constructorStrName, redirectedClass.name]);
+            CompileTimeErrorCode
+                .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+            parameter.identifier!);
       }
     }
-    // check if there are redirected invocations
-    int numRedirections = 0;
-    for (ConstructorInitializer initializer in declaration.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
-        if (numRedirections > 0) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
-              initializer);
-        }
-        if (declaration.factoryKeyword == null) {
-          RedirectingConstructorInvocation invocation = initializer;
-          var redirectingElement = invocation.staticElement;
-          if (redirectingElement == null) {
-            String enclosingNamedType = _enclosingClass!.displayName;
-            String constructorStrName = enclosingNamedType;
-            if (invocation.constructorName != null) {
-              constructorStrName += ".${invocation.constructorName!.name}";
-            }
-            errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
-                invocation,
-                [constructorStrName, enclosingNamedType]);
-          } else {
-            if (redirectingElement.isFactory) {
-              errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode
-                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
-                  initializer);
-            }
-          }
-        }
-        // [declaration] is a redirecting constructor via a redirecting
-        // initializer.
-        _checkForRedirectToNonConstConstructor(
-          declaration.declaredElement!,
-          initializer.staticElement,
-          initializer.constructorName ?? initializer.thisKeyword,
-        );
-        numRedirections++;
+    var redirectedElement = redirectedConstructor.staticElement;
+    _checkForRedirectToNonConstConstructor(
+      declaration.declaredElement!,
+      redirectedElement,
+      redirectedConstructor,
+    );
+    var redirectedClass = redirectedElement?.enclosingElement;
+    if (redirectedClass is ClassElement &&
+        redirectedClass.isAbstract &&
+        redirectedElement != null &&
+        !redirectedElement.isFactory) {
+      String enclosingNamedType = _enclosingClass!.displayName;
+      String constructorStrName = enclosingNamedType;
+      if (declaration.name != null) {
+        constructorStrName += ".${declaration.name!.name}";
       }
-    }
-    // check for other initializers
-    if (numRedirections > 0) {
-      for (ConstructorInitializer initializer in declaration.initializers) {
-        if (initializer is SuperConstructorInvocation) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-        if (initializer is ConstructorFieldInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-        if (initializer is AssertInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-      }
+      errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
+          redirectedConstructor,
+          [constructorStrName, redirectedClass.name]);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3d179d7..ef1119a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -82,21 +82,14 @@
   }
 
   void checkAssignment(Expression expr, DartType to) {
-    checkForCast(expr, from: expr.typeOrThrow, to: to);
+    _checkImplicitCast(expr, from: expr.typeOrThrow, to: to);
   }
 
-  /// Analyzer checks boolean conversions, but we need to check too, because
-  /// it uses the default assignability rules that allow `dynamic` and `Object`
-  /// to be assigned to bool with no message.
-  void checkBoolean(Expression expr) =>
-      checkAssignment(expr, typeProvider.boolType);
-
   void checkCollectionElement(
       CollectionElement? element, DartType expectedType) {
     if (element is ForElement) {
       checkCollectionElement(element.body, expectedType);
     } else if (element is IfElement) {
-      checkBoolean(element.condition);
       checkCollectionElement(element.thenElement, expectedType);
       checkCollectionElement(element.elseElement, expectedType);
     } else if (element is Expression) {
@@ -120,24 +113,11 @@
     }
   }
 
-  void checkForCast(
-    Expression expr, {
-    required DartType from,
-    required DartType to,
-  }) {
-    if (expr is ParenthesizedExpression) {
-      checkForCast(expr.expression, from: from, to: to);
-    } else {
-      _checkImplicitCast(expr, from: from, to: to);
-    }
-  }
-
   void checkMapElement(CollectionElement? element, DartType expectedKeyType,
       DartType expectedValueType) {
     if (element is ForElement) {
       checkMapElement(element.body, expectedKeyType, expectedValueType);
     } else if (element is IfElement) {
-      checkBoolean(element.condition);
       checkMapElement(element.thenElement, expectedKeyType, expectedValueType);
       checkMapElement(element.elseElement, expectedKeyType, expectedValueType);
     } else if (element is MapLiteralEntry) {
@@ -178,17 +158,12 @@
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
-    var right = node.rightHandSide;
     Token operator = node.operator;
     TokenType operatorType = operator.type;
     if (operatorType == TokenType.EQ ||
         operatorType == TokenType.QUESTION_QUESTION_EQ) {
-      checkForCast(right, from: right.typeOrThrow, to: node.writeType!);
-    } else if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
-        operatorType == TokenType.BAR_BAR_EQ) {
-      checkBoolean(left);
-      checkBoolean(right);
+      var right = node.rightHandSide;
+      _checkImplicitCast(right, from: right.typeOrThrow, to: node.writeType!);
     } else {
       _checkCompoundAssignment(node);
     }
@@ -196,28 +171,6 @@
   }
 
   @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var op = node.operator;
-    if (!op.isUserDefinableOperator) {
-      switch (op.type) {
-        case TokenType.AMPERSAND_AMPERSAND:
-        case TokenType.BAR_BAR:
-          checkBoolean(node.leftOperand);
-          checkBoolean(node.rightOperand);
-          break;
-        case TokenType.BANG_EQ:
-        case TokenType.BANG_EQ_EQ:
-        case TokenType.EQ_EQ_EQ:
-        case TokenType.QUESTION_QUESTION:
-          break;
-        default:
-          assert(false);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
   void visitComment(Comment node) {
     // skip, no need to do typechecking inside comments (they may contain
     // comment references which would require resolution).
@@ -231,31 +184,9 @@
 
   @override
   void visitConditionalExpression(ConditionalExpression node) {
-    checkBoolean(node.condition);
     node.visitChildren(this);
   }
 
-  /// Check constructor declaration to ensure correct super call placement.
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    node.visitChildren(this);
-
-    final init = node.initializers;
-    for (int i = 0, last = init.length - 1; i < last; i++) {
-      final initializer = init[i];
-      if (initializer is SuperConstructorInvocation) {
-        // TODO(srawlins): Don't report this when
-        //  [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR] or
-        //  [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS] is reported for
-        //  this constructor.
-        var source = (node.root as CompilationUnit).declaredElement!.source;
-        var token = initializer.superKeyword;
-        reporter.onError(AnalysisError(source, token.offset, token.length,
-            CompileTimeErrorCode.INVALID_SUPER_INVOCATION, [initializer]));
-      }
-    }
-  }
-
   @override
   void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     var field = node.fieldName;
@@ -281,12 +212,6 @@
   }
 
   @override
-  void visitDoStatement(DoStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
     _checkReturnOrYield(node.expression, node);
     node.visitChildren(this);
@@ -305,36 +230,12 @@
   }
 
   @override
-  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    var condition = node.condition;
-    if (condition != null) {
-      checkBoolean(condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForPartsWithExpression(ForPartsWithExpression node) {
-    var condition = node.condition;
-    if (condition != null) {
-      checkBoolean(condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     _checkFunctionApplication(node);
     node.visitChildren(this);
   }
 
   @override
-  void visitIfStatement(IfStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitIndexExpression(IndexExpression node) {
     var element = node.writeOrReadElement;
     if (element is MethodElement) {
@@ -403,11 +304,7 @@
 
   @override
   void visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type == TokenType.BANG) {
-      checkBoolean(node.operand);
-    } else {
-      _checkUnary(node, node.operand, node.operator, node.staticElement);
-    }
+    _checkUnary(node, node.operand, node.operator, node.staticElement);
     node.visitChildren(this);
   }
 
@@ -523,7 +420,7 @@
       for (VariableDeclaration variable in node.variables) {
         var initializer = variable.initializer;
         if (initializer != null) {
-          checkForCast(initializer,
+          _checkImplicitCast(initializer,
               from: initializer.typeOrThrow, to: type.typeOrThrow);
         }
       }
@@ -533,12 +430,6 @@
   }
 
   @override
-  void visitWhileStatement(WhileStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitYieldStatement(YieldStatement node) {
     _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
     node.visitChildren(this);
@@ -591,11 +482,10 @@
     }
   }
 
-  /// Given an expression [expr] of type [fromType], returns true if an implicit
-  /// downcast is required, false if it is not, or null if the types are
-  /// unrelated.
-  bool? _checkFunctionTypeCasts(
-      Expression expr, FunctionType to, DartType fromType) {
+  /// Returns true if an implicit downcast is required to assign an expression
+  /// of type [fromType] to type [to], false if it is not, or null if the
+  /// types are unrelated.
+  bool? _checkFunctionTypeCasts(FunctionType to, DartType fromType) {
     bool callTearoff = false;
     FunctionType? from;
     if (fromType is FunctionType) {
@@ -640,6 +530,7 @@
       return;
     }
 
+    expr = expr.unParenthesized;
     if (_needsImplicitCast(expr, to: to, from: from) == true) {
       _recordImplicitCast(expr, to,
           from: from,
@@ -796,7 +687,7 @@
     if (from.isVoid) return null;
 
     if (to is FunctionType) {
-      var needsCast = _checkFunctionTypeCasts(expr, to, from);
+      var needsCast = _checkFunctionTypeCasts(to, from);
       if (needsCast != null) return needsCast;
     }
 
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 80aab8d..b1868a7 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -6524,46 +6524,6 @@
 
       class C {}
       ```
-  INVALID_SUPER_INVOCATION:
-    problemMessage: "The superclass call must be last in an initializer list: '{0}'."
-    hasPublishedDocs: true
-    comment: No parameters.
-    documentation: |-
-      #### Description
-
-      The analyzer produces this diagnostic when the initializer list of a
-      constructor contains an invocation of a constructor in the superclass, but
-      the invocation isn't the last item in the initializer list.
-
-      #### Example
-
-      The following code produces this diagnostic because the invocation of the
-      superclass' constructor isn't the last item in the initializer list:
-
-      ```dart
-      class A {
-        A(int x);
-      }
-
-      class B extends A {
-        B(int x) : [!super!](x), assert(x >= 0);
-      }
-      ```
-
-      #### Common fixes
-
-      Move the invocation of the superclass' constructor to the end of the
-      initializer list:
-
-      ```dart
-      class A {
-        A(int x);
-      }
-
-      class B extends A {
-        B(int x) : assert(x >= 0), super(x);
-      }
-      ```
   INVALID_TYPE_ARGUMENT_IN_CONST_LIST:
     sharedName: INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL
     problemMessage: "Constant list literals can't include a type parameter as a type argument, such as '{0}'."
@@ -11329,6 +11289,49 @@
       7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
       is a compile-time error if a generative constructor of class Object
       includes a superinitializer.
+  SUPER_INVOCATION_NOT_LAST:
+    previousName: INVALID_SUPER_INVOCATION
+    problemMessage: "The superconstructor call must be last in an initializer list: '{0}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the superinitializer
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when the initializer list of a
+      constructor contains an invocation of a constructor in the superclass, but
+      the invocation isn't the last item in the initializer list.
+
+      #### Example
+
+      The following code produces this diagnostic because the invocation of the
+      superclass' constructor isn't the last item in the initializer list:
+
+      ```dart
+      class A {
+        A(int x);
+      }
+
+      class B extends A {
+        B(int x) : [!super!](x), assert(x >= 0);
+      }
+      ```
+
+      #### Common fixes
+
+      Move the invocation of the superclass' constructor to the end of the
+      initializer list:
+
+      ```dart
+      class A {
+        A(int x);
+      }
+
+      class B extends A {
+        B(int x) : assert(x >= 0), super(x);
+      }
+      ```
   SUPER_IN_EXTENSION:
     problemMessage: "The 'super' keyword can't be used in an extension because an extension doesn't have a superclass."
     hasPublishedDocs: true
diff --git a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
index 8147f29..ef8d48e 100644
--- a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
@@ -15,14 +15,22 @@
 
 @reflectiveTest
 class MultipleSuperInitializersTest extends PubPackageResolutionTest {
+  test_oneSuperInitializer() async {
+    await assertNoErrorsInCode('''
+class A {}
+class B extends A {
+  B() : super() {}
+}
+''');
+  }
+
   test_twoSuperInitializers() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode('''
 class A {}
 class B extends A {
   B() : super(), super() {}
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 39, 5),
       error(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, 48, 7),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
index 0e9e5de..d96e7f3 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
@@ -26,6 +26,21 @@
     ]);
   }
 
+  test_conditional_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() { return [1, 2, 3] ? 2 : 1; }
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+    ]);
+  }
+
+  test_conditional_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() { return o ? 2 : 1; }
+''');
+  }
+
   test_do() async {
     await assertErrorsInCode(r'''
 f() {
@@ -36,6 +51,26 @@
     ]);
   }
 
+  test_do_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+Object o;
+f() {
+  do {} while ([1, 2, 3]);
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 31, 9),
+    ]);
+  }
+
+  test_do_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() {
+  do {} while (o);
+}
+''');
+  }
+
   test_for() async {
     // https://github.com/dart-lang/sdk/issues/24713
     await assertErrorsInCode(r'''
@@ -71,6 +106,25 @@
     ]);
   }
 
+  test_for_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  for (;[1, 2, 3];) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 14, 9),
+    ]);
+  }
+
+  test_for_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() {
+  for (;o;) {}
+}
+''');
+  }
+
   test_forElement() async {
     await assertErrorsInCode('''
 var v = [for (; 0;) 1];
@@ -89,6 +143,24 @@
     ]);
   }
 
+  test_if_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  if ([1, 2, 3]) return 2; else return 1;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 12, 9),
+    ]);
+  }
+
+  test_if_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  if (o) return 2; else return 1;
+}
+''');
+  }
+
   test_ifElement() async {
     await assertErrorsInCode('''
 var v = [if (3) 1];
@@ -97,6 +169,21 @@
     ]);
   }
 
+  test_ifElement_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+var v = [if ([1, 2, 3]) 'x'];
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+    ]);
+  }
+
+  test_ifElement_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+var v = [if (o) 'x'];
+''');
+  }
+
   test_while() async {
     await assertErrorsInCode(r'''
 f() {
@@ -106,6 +193,24 @@
       error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 1),
     ]);
   }
+
+  test_while_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  while ([1, 2, 3]) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 9),
+    ]);
+  }
+
+  test_while_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  while (o) {}
+}
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
index 2d2c516..6fb1e92 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
@@ -26,6 +26,24 @@
       error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 2),
     ]);
   }
+
+  test_nonBool_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  ![1, 2, 3];
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 9),
+    ]);
+  }
+
+  test_nonBool_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  !o;
+}
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
index f3d16b1..ea06d2a 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
@@ -27,6 +27,34 @@
     ]);
   }
 
+  test_and_left_implicitCast_fromInstanceCreationExpression() async {
+    await assertErrorsInCode('''
+main() {
+  new Object() && true;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 11, 12),
+    ]);
+  }
+
+  test_and_left_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+bool f(List<int> left, bool right) {
+  return left && right;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 46, 4),
+    ]);
+  }
+
+  test_and_left_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+bool f(Object left, bool right) {
+  return left && right;
+}
+''');
+  }
+
   test_and_right() async {
     await assertErrorsInCode(r'''
 bool f(bool left, String right) {
diff --git a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
index 9fafaa1..c58d414 100644
--- a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
@@ -33,7 +33,6 @@
   A.name() {}
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 18, 5),
       error(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, 18, 7),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
similarity index 66%
rename from pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
rename to pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
index 078fecf..6924087 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
@@ -9,19 +9,19 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InvalidSuperInvocationTest);
+    defineReflectiveTests(SuperInvocationNotLastTest);
   });
 }
 
 @reflectiveTest
-class InvalidSuperInvocationTest extends PubPackageResolutionTest {
+class SuperInvocationNotLastTest extends PubPackageResolutionTest {
   test_superBeforeAssert() async {
     await assertErrorsInCode(r'''
 class A {
   A(int? x) : super(), assert(x != null);
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 24, 5),
+      error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 24, 5),
     ]);
   }
 
@@ -32,7 +32,16 @@
   A() : super(), x = 1;
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 33, 5),
+      error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 33, 5),
     ]);
   }
+
+  test_superIsLast() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int x;
+  A() : x = 1, super();
+}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3d245fa..5b02fd3 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -344,7 +344,6 @@
     as invalid_required_positional_param;
 import 'invalid_sealed_annotation_test.dart' as invalid_sealed_annotation;
 import 'invalid_super_in_initializer_test.dart' as invalid_super_in_initializer;
-import 'invalid_super_invocation_test.dart' as invalid_super_invocation;
 import 'invalid_type_argument_in_const_list_test.dart'
     as invalid_type_argument_in_const_list;
 import 'invalid_type_argument_in_const_map_test.dart'
@@ -625,6 +624,7 @@
 import 'super_in_redirecting_constructor_test.dart'
     as super_in_redirecting_constructor;
 import 'super_initializer_in_object_test.dart' as super_initializer_in_object;
+import 'super_invocation_not_last_test.dart' as super_invocation_not_last;
 import 'switch_case_completes_normally_test.dart'
     as switch_case_completes_normally;
 import 'switch_expression_not_assignable_test.dart'
@@ -947,7 +947,6 @@
     invalid_required_positional_param.main();
     invalid_sealed_annotation.main();
     invalid_super_in_initializer.main();
-    invalid_super_invocation.main();
     invalid_type_argument_in_const_list.main();
     invalid_type_argument_in_const_map.main();
     invalid_type_argument_in_const_set.main();
@@ -1131,6 +1130,7 @@
     super_in_invalid_context.main();
     super_in_redirecting_constructor.main();
     super_initializer_in_object.main();
+    super_invocation_not_last.main();
     switch_case_completes_normally.main();
     switch_expression_not_assignable.main();
     tearoff_of_generative_constructor_of_abstract_class.main();
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index ce366390..5a33bcb 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3031,33 +3031,6 @@
     ]);
   }
 
-  test_superCallPlacement() async {
-    await assertErrorsInCode('''
-class Base {
-  var x;
-  Base() : x = 1;
-}
-
-class Derived extends Base {
-  var y, z;
-  Derived() : y = 1, super(), z = 2;
-}
-
-class Valid extends Base {
-  var y, z;
-  Valid(): y = 1, z = 2, super();
-}
-
-class AlsoValid extends Base {
-  AlsoValid() : super();
-}
-
-main() => new Derived();
-''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 105, 5),
-    ]);
-  }
-
   test_superclassOverrideOfGrandInterface_interfaceOfAbstractSuperclass() async {
     await assertErrorsInCode('''
 class A {}
@@ -3416,62 +3389,6 @@
     ]);
   }
 
-  test_unaryOperators() async {
-    await assertErrorsInCode('''
-class A {
-  A operator ~() => null;
-  A operator +(int x) => null;
-  A operator -(int x) => null;
-  A operator -() => null;
-}
-class B extends A {}
-class C extends B {}
-
-foo() => new A();
-
-test() {
-  A a = new A();
-  B b = new B();
-  var c = foo();
-  dynamic d;
-
-  ~a;
-  (~d);
-
-  !a;
-  !d;
-
-  -a;
-  (-d);
-
-  ++a;
-  --a;
-  (++d);
-  (--d);
-
-  a++;
-  a--;
-  (d++);
-  (d--);
-
-  ++b;
-  --b;
-  b++;
-  b--;
-
-  takesC(C c) => null;
-  takesC(++b);
-  takesC(--b);
-  takesC(b++);
-  takesC(b--);
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 201, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 237, 1),
-      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 280, 1),
-    ]);
-  }
-
   test_unboundTypeName() async {
     await assertErrorsInCode('''
 void main() {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 94648b5..ba40e44 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -7152,46 +7152,6 @@
 }
 {% endprettify %}
 
-### invalid_super_invocation
-
-_The superclass call must be last in an initializer list: '{0}'._
-
-#### Description
-
-The analyzer produces this diagnostic when the initializer list of a
-constructor contains an invocation of a constructor in the superclass, but
-the invocation isn't the last item in the initializer list.
-
-#### Example
-
-The following code produces this diagnostic because the invocation of the
-superclass' constructor isn't the last item in the initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
-  A(int x);
-}
-
-class B extends A {
-  B(int x) : [!super!](x), assert(x >= 0);
-}
-{% endprettify %}
-
-#### Common fixes
-
-Move the invocation of the superclass' constructor to the end of the
-initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
-  A(int x);
-}
-
-class B extends A {
-  B(int x) : assert(x >= 0), super(x);
-}
-{% endprettify %}
-
 ### invalid_type_argument_in_const_literal
 
 _Constant list literals can't include a type parameter as a type argument, such
@@ -12846,6 +12806,48 @@
 class C extends Object {}
 {% endprettify %}
 
+### super_invocation_not_last
+
+<a id="invalid_super_invocation" aria-hidden="true"></a>_(Previously known as `invalid_super_invocation`)_
+
+_The superconstructor call must be last in an initializer list: '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the initializer list of a
+constructor contains an invocation of a constructor in the superclass, but
+the invocation isn't the last item in the initializer list.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of the
+superclass' constructor isn't the last item in the initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+  A(int x);
+}
+
+class B extends A {
+  B(int x) : [!super!](x), assert(x >= 0);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Move the invocation of the superclass' constructor to the end of the
+initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+  A(int x);
+}
+
+class B extends A {
+  B(int x) : assert(x >= 0), super(x);
+}
+{% endprettify %}
+
 ### super_in_extension
 
 _The 'super' keyword can't be used in an extension because an extension doesn't
@@ -14435,7 +14437,7 @@
 
 ### undefined_super_member
 
-<a id="undefined_super_method" aria-hidden="true"></a>_(Previously known as `UNDEFINED_SUPER_METHOD`)_
+<a id="undefined_super_method" aria-hidden="true"></a>_(Previously known as `undefined_super_method`)_
 
 _The getter '{0}' isn't defined in a superclass of '{1}'._
 
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index f7d094b..9f58663 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -71,9 +71,9 @@
     sink.writeln('### ${name.toLowerCase()}');
     for (var previousName in previousNames) {
       sink.writeln();
-      sink.writeln(
-          '<a id="${previousName.toLowerCase()}" aria-hidden="true"></a>'
-          '_(Previously known as `$previousName`)_');
+      var previousInLowerCase = previousName.toLowerCase();
+      sink.writeln('<a id="$previousInLowerCase" aria-hidden="true"></a>'
+          '_(Previously known as `$previousInLowerCase`)_');
     }
     for (String message in messages) {
       sink.writeln();
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 2fe6603..bb03fc8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -69,9 +69,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionTarget {
-  /// The compilation unit in which the completion is occurring.
-  final CompilationUnit unit;
-
   /// The offset within the source at which the completion is being requested.
   final int offset;
 
@@ -122,14 +119,8 @@
   ParameterElement? _parameterElement;
 
   /// Compute the appropriate [CompletionTarget] for the given [offset] within
-  /// the [compilationUnit].
-  ///
-  /// Optionally, start the search from within [entryPoint] instead of using
-  /// the [compilationUnit], which is useful for analyzing ASTs that have no
-  /// [compilationUnit] such as dart expressions within angular templates.
-  factory CompletionTarget.forOffset(
-      CompilationUnit compilationUnit, int offset,
-      {AstNode? entryPoint}) {
+  /// the [entryPoint].
+  factory CompletionTarget.forOffset(AstNode entryPoint, int offset) {
     // The precise algorithm is as follows. We perform a depth-first search of
     // all edges in the parse tree (both those that point to AST nodes and
     // those that point to tokens), visiting parents before children. The
@@ -144,7 +135,6 @@
     // prune the search to the point where no recursion is necessary; at each
     // step in the process we know exactly which child node we need to proceed
     // to.
-    entryPoint ??= compilationUnit;
     var containingNode = entryPoint;
     outerLoop:
     while (true) {
@@ -167,11 +157,10 @@
             var commentToken = _getContainingCommentToken(entity, offset);
             if (commentToken != null) {
               return CompletionTarget._(
-                  compilationUnit, offset, containingNode, commentToken, true);
+                  offset, containingNode, commentToken, true);
             }
             // Target found.
-            return CompletionTarget._(
-                compilationUnit, offset, containingNode, entity, false);
+            return CompletionTarget._(offset, containingNode, entity, false);
           } else {
             // Since entity is a token, we don't need to look inside it; just
             // proceed to the next entity.
@@ -198,14 +187,13 @@
                   _getContainingDocComment(containingNode, commentToken);
               if (docComment != null) {
                 return CompletionTarget._(
-                    compilationUnit, offset, docComment, commentToken, false);
+                    offset, docComment, commentToken, false);
               } else {
-                return CompletionTarget._(compilationUnit, offset,
-                    compilationUnit, commentToken, true);
+                return CompletionTarget._(
+                    offset, entryPoint, commentToken, true);
               }
             }
-            return CompletionTarget._(
-                compilationUnit, offset, containingNode, entity, false);
+            return CompletionTarget._(offset, containingNode, entity, false);
           }
 
           // Otherwise, the completion target is somewhere inside the entity,
@@ -228,23 +216,23 @@
       assert(identical(containingNode, entryPoint));
 
       // Check for comments on the EOF token (trailing comments in a file).
-      var commentToken =
-          _getContainingCommentToken(compilationUnit.endToken, offset);
-      if (commentToken != null) {
-        return CompletionTarget._(
-            compilationUnit, offset, compilationUnit, commentToken, true);
+      if (entryPoint is CompilationUnit) {
+        var commentToken =
+            _getContainingCommentToken(entryPoint.endToken, offset);
+        if (commentToken != null) {
+          return CompletionTarget._(offset, entryPoint, commentToken, true);
+        }
       }
 
       // Since no completion target was found, we set the completion target
       // entity to null and use the entryPoint as the parent.
-      return CompletionTarget._(
-          compilationUnit, offset, entryPoint, null, false);
+      return CompletionTarget._(offset, entryPoint, null, false);
     }
   }
 
   /// Create a [CompletionTarget] holding the given [containingNode] and
   /// [entity].
-  CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+  CompletionTarget._(this.offset, AstNode containingNode,
       SyntacticEntity? entity, this.isCommentText)
       : containingNode = containingNode,
         entity = entity,
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index dea31e3..2110c49 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -20,22 +19,12 @@
 /// suggestions should be made based upon the type of node in which the
 /// suggestions were requested.
 class OpType {
-  /// The [TypeSystem] used during resolution of the current unit.
-  TypeSystem? _typeSystem;
-
   /// Indicates whether constructor suggestions should be included.
   bool includeConstructorSuggestions = false;
 
   /// Indicates whether type names should be suggested.
   bool includeTypeNameSuggestions = false;
 
-  /// If [includeTypeNameSuggestions] is set to true, then this function may
-  /// be set to a non-default function to filter out potential suggestions
-  /// (null) based on their static [DartType], or change the relative relevance
-  /// by returning a higher or lower relevance.
-  SuggestionsFilter typeNameSuggestionsFilter =
-      (DartType _, int relevance) => relevance;
-
   /// Indicates whether setters along with methods and functions that
   /// have a [void] return type should be suggested.
   bool includeVoidReturnSuggestions = false;
@@ -76,10 +65,6 @@
   /// An representation of the location at which completion was requested.
   String? completionLocation;
 
-  /// The type that is required by the context in which the completion was
-  /// activated, or `null` if there is no such type, or it cannot be determined.
-  DartType? _requiredType;
-
   /// Determine the suggestions that should be made based upon the given
   /// [CompletionTarget] and [offset].
   factory OpType.forCompletion(CompletionTarget target, int offset) {
@@ -90,8 +75,6 @@
       return optype;
     }
 
-    optype._typeSystem = target.unit.declaredElement?.library.typeSystem;
-
     var targetNode = target.containingNode;
     targetNode.accept(_OpTypeAstVisitor(optype, target.entity, offset));
 
@@ -111,16 +94,9 @@
 
     // If a value should be suggested, suggest also constructors.
     if (optype.includeReturnValueSuggestions) {
-      // Careful: in angular plugin, `target.unit` may be null!
-      var unitElement = target.unit.declaredElement;
-      if (unitElement != null) {
-        optype.includeConstructorSuggestions = true;
-      }
+      optype.includeConstructorSuggestions = true;
     }
 
-    // Compute the type required by the context and set filters.
-    optype._computeRequiredTypeAndFilters(target);
-
     return optype;
   }
 
@@ -142,59 +118,6 @@
       !includeReturnValueSuggestions &&
       !includeVoidReturnSuggestions;
 
-  /// Try to determine the required context type, and configure filters.
-  void _computeRequiredTypeAndFilters(CompletionTarget target) {
-    var entity = target.entity;
-    AstNode? node = target.containingNode;
-
-    if (node is InstanceCreationExpression &&
-        node.keyword != null &&
-        node.constructorName == entity) {
-      entity = node;
-      node = node.parent;
-    }
-
-    if (node is AssignmentExpression &&
-        node.operator.type == TokenType.EQ &&
-        node.rightHandSide == entity) {
-      _requiredType = node.leftHandSide.staticType;
-    } else if (node is BinaryExpression &&
-        node.operator.type == TokenType.EQ_EQ &&
-        node.rightOperand == entity) {
-      _requiredType = node.leftOperand.staticType;
-    } else if (node is NamedExpression && node.expression == entity) {
-      _requiredType = node.staticParameterElement?.type;
-    } else if (node is SwitchCase && node.expression == entity) {
-      var parent = node.parent;
-      if (parent is SwitchStatement) {
-        _requiredType = parent.expression.staticType;
-      }
-    } else if (node is VariableDeclaration && node.initializer == entity) {
-      _requiredType = node.declaredElement?.type;
-    } else if (entity is Expression && entity.staticParameterElement != null) {
-      _requiredType = entity.staticParameterElement?.type;
-    }
-
-    var requiredType = _requiredType;
-    if (requiredType == null) {
-      return;
-    }
-    if (requiredType.isDynamic || requiredType.isDartCoreObject) {
-      _requiredType = null;
-      return;
-    }
-  }
-
-  /// Return `true` if the [leftType] is a subtype of the [rightType].
-  bool _isSubtypeOf(DartType leftType, DartType rightType) {
-    var typeSystem = _typeSystem;
-    if (typeSystem == null) {
-      return false;
-    }
-
-    return typeSystem.isSubtypeOf(leftType, rightType);
-  }
-
   /// Return the statement before [entity]
   /// where [entity] can be a statement or the `}` closing the given block.
   static Statement? getPreviousStatement(Block node, Object? entity) {
@@ -334,17 +257,6 @@
     if (identical(entity, node.type)) {
       optype.completionLocation = 'AsExpression_type';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
-        var staticType = node.expression.staticType;
-        if (staticType != null &&
-            (staticType.isDynamic ||
-                (optype._isSubtypeOf(dartType, staticType) &&
-                    dartType != staticType))) {
-          return relevance;
-        } else {
-          return null;
-        }
-      };
     }
   }
 
@@ -652,7 +564,6 @@
     if (identical(entity, node.superclass2)) {
       optype.completionLocation = 'ExtendsClause_superclass';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = _nonMixinClasses;
     }
   }
 
@@ -947,17 +858,6 @@
     if (identical(entity, node.type)) {
       optype.completionLocation = 'IsExpression_type';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
-        var staticType = node.expression.staticType;
-        if (staticType != null &&
-            (staticType.isDynamic ||
-                (optype._isSubtypeOf(dartType, staticType) &&
-                    dartType != staticType))) {
-          return relevance;
-        } else {
-          return null;
-        }
-      };
     }
   }
 
@@ -1473,18 +1373,6 @@
     return false;
   }
 
-  /// A filter used to disable everything except classes (such as functions and
-  /// mixins).
-  int? _nonMixinClasses(DartType type, int relevance) {
-    if (type is InterfaceType) {
-      if (type.element.isMixin) {
-        return null;
-      }
-      return relevance;
-    }
-    return null;
-  }
-
   static bool _isParameterOfGenericFunctionType(FormalParameter node) {
     var parameterList = node.parent;
     if (parameterList is DefaultFormalParameter) {
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 3e6290b..58791ae 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -69,7 +69,8 @@
   /// for example to allow key-binding specific fixes (or groups of).
   final String id;
 
-  /// The priority of this kind of assist for the kind of error being addressed.
+  /// The priority of this kind of assist for the kind of error being addressed
+  /// where a higher integer value indicates a higher priority and relevance.
   final int priority;
 
   /// A human-readable description of the changes that will be applied by this
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index cf0a57b..77cc825 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -59,8 +59,8 @@
     CompletionTarget? target,
     OpType? optype,
   }) async {
-    target ??= CompletionTarget.forOffset(request.result.unit, request.offset,
-        entryPoint: entryPoint);
+    entryPoint ??= request.result.unit;
+    target ??= CompletionTarget.forOffset(entryPoint, request.offset);
     optype ??= OpType.forCompletion(target, request.offset);
     if (!optype.includeIdentifiers) {
       return;
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index a27010c..d88f47a 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -29,7 +29,7 @@
     var containingLibrary = request.result.libraryElement;
 
     // Recompute the target since resolution may have changed it
-    var expression = _computeDotTarget(request, null);
+    var expression = _computeDotTarget(request.result.unit, request.offset);
     if (expression == null || expression.isSynthetic) {
       return;
     }
@@ -42,7 +42,7 @@
     var containingLibrary = request.result.libraryElement;
 
     // Recompute the target since resolution may have changed it
-    var expression = _computeDotTarget(request, entryPoint);
+    var expression = _computeDotTarget(entryPoint, request.offset);
     if (expression == null || expression.isSynthetic) {
       return;
     }
@@ -50,10 +50,8 @@
   }
 
   /// Update the completion [target] and [dotTarget] based on the given [unit].
-  Expression? _computeDotTarget(
-      DartCompletionRequest request, AstNode? entryPoint) {
-    var target = CompletionTarget.forOffset(request.result.unit, request.offset,
-        entryPoint: entryPoint);
+  Expression? _computeDotTarget(AstNode entryPoint, int offset) {
+    var target = CompletionTarget.forOffset(entryPoint, offset);
     return target.dotTarget;
   }
 
diff --git a/pkg/analyzer_utilities/test/check/check_test.dart b/pkg/analyzer_utilities/test/check/check_test.dart
index 532eea7..cc52f80 100644
--- a/pkg/analyzer_utilities/test/check/check_test.dart
+++ b/pkg/analyzer_utilities/test/check/check_test.dart
@@ -150,7 +150,7 @@
     group('type', () {
       test('isA', () {
         check(0).isA<int>();
-        _fails(() => check(0.0 as dynamic).isA<int>());
+        _fails(() => check('abc' as dynamic).isA<int>());
       });
     });
   });
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 69a999f..8a48496 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1397,8 +1397,8 @@
 
   @override
   void visitSwitch(js.Switch node) {
-    if (!node.cases.any(shouldTransform)) {
-      // If only the key has an await, translation can be simplified.
+    if (!shouldTransform(node)) {
+      // TODO(sra): If only the key has an await, translation can be simplified.
       bool oldInsideUntranslated = insideUntranslatedBreakable;
       insideUntranslatedBreakable = true;
       withExpression(node.key, (js.Expression key) {
@@ -2824,10 +2824,9 @@
   @override
   bool visitSwitch(js.Switch node) {
     loopsAndSwitches.add(node);
-    // If the key has an `await` expression, do not transform the
-    // body of the switch.
-    visit(node.key);
-    bool result = false;
+    // TODO(sra): If just the key has an `await` expression, do not transform
+    // the body of the switch.
+    bool result = visit(node.key);
     for (js.SwitchClause clause in node.cases) {
       if (visit(clause)) result = true;
     }
diff --git a/pkg/compiler/test/async_await/async_await_js_transform_test.dart b/pkg/compiler/test/async_await/async_await_js_transform_test.dart
index 4ea675b..5897259 100644
--- a/pkg/compiler/test/async_await/async_await_js_transform_test.dart
+++ b/pkg/compiler/test/async_await/async_await_js_transform_test.dart
@@ -1085,20 +1085,116 @@
       switch (__goto) {
         case 0:
           // Function start
-          __goto = 2;
-          return awaitHelper(l, body);
         case 2:
+          // switch
+          __goto = 7;
+          return awaitHelper(l, body);
+        case 7:
           // returning from await.
           switch (__result) {
             case 1:
-              print(1);
+              // goto case
+              __goto = 4;
               break;
             case 2:
-              print(1);
+              // goto case
+              __goto = 5;
+              break;
             default:
-              print(2);
+              // goto default
+              __goto = 6;
               break;
           }
+          break;
+        case 4:
+          // case
+          print(1);
+          // goto after switch
+          __goto = 3;
+          break;
+        case 5:
+          // case
+          print(1);
+        case 6:
+          // default
+          print(2);
+          // goto after switch
+          __goto = 3;
+          break;
+        case 3:
+          // after switch
+          // implicit return
+          return returnHelper(null, __completer);
+      }
+  });
+  return startHelper(body, __completer);
+}""");
+
+  testAsyncTransform("""
+  // This example is like #47566
+  function(b, l) async {
+    print("start");
+    if (b) {
+      switch(await l) {
+        case 1:
+          print(1);
+          break;
+        default:
+          print(2);
+          break;
+      }
+    }
+    print("end");
+  }""", """
+function(b, l) {
+  var __goto = 0,
+    __completer = NewCompleter(CompleterType);
+  var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
+    if (__errorCode === 1)
+      return rethrowHelper(__result, __completer);
+    while (true)
+      switch (__goto) {
+        case 0:
+          // Function start
+          print("start");
+          __goto = b ? 2 : 3;
+          break;
+        case 2:
+          // then
+        case 4:
+          // switch
+          __goto = 8;
+          return awaitHelper(l, body);
+        case 8:
+          // returning from await.
+          switch (__result) {
+            case 1:
+              // goto case
+              __goto = 6;
+              break;
+            default:
+              // goto default
+              __goto = 7;
+              break;
+          }
+          break;
+        case 6:
+          // case
+          print(1);
+          // goto after switch
+          __goto = 5;
+          break;
+        case 7:
+          // default
+          print(2);
+          // goto after switch
+          __goto = 5;
+          break;
+        case 5:
+          // after switch
+        case 3:
+          // join
+          print("end");
           // implicit return
           return returnHelper(null, __completer);
       }
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 0ef4650..b53dc75 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -939,7 +939,7 @@
 
 SuperInitializerNotLast:
   problemMessage: "Can't have initializers after 'super'."
-  analyzerCode: INVALID_SUPER_INVOCATION
+  analyzerCode: SUPER_INVOCATION_NOT_LAST
   script:
     - "class C { int x; C.bad() : super(), x = 5; }"
 
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index 0574603..6525627 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -6,6 +6,8 @@
 # Run dartanalyzer.dart on the Dart VM. This script assumes the Dart repo's
 # directory structure.
 
+echo "Warning: 'dartanalyzer' is deprecated. Please use 'dart analyze'." 1>&2
+
 function follow_links() {
   file="$1"
   while [ -h "$file" ]; do
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index efa3a6a..122e9b3 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -3,6 +3,8 @@
 REM for details. All rights reserved. Use of this source code is governed by a
 REM BSD-style license that can be found in the LICENSE file.
 
+echo Warning: 'dartanalyzer' is deprecated. Please use 'dart analyze'. 1>&2
+
 setlocal
 rem Handle the case where dart-sdk/bin has been symlinked to.
 set DIR_NAME_WITH_SLASH=%~dp0
diff --git a/sdk/lib/convert/ascii.dart b/sdk/lib/convert/ascii.dart
index 9f62c2d..30a9599 100644
--- a/sdk/lib/convert/ascii.dart
+++ b/sdk/lib/convert/ascii.dart
@@ -35,7 +35,7 @@
   /// Encoders will not accept invalid (non ASCII) characters.
   const AsciiCodec({bool allowInvalid = false}) : _allowInvalid = allowInvalid;
 
-  /// The name of this codec, "us-ascii".
+  /// The name of this codec is "us-ascii".
   String get name => "us-ascii";
 
   Uint8List encode(String source) => encoder.convert(source);
@@ -103,7 +103,15 @@
   Stream<List<int>> bind(Stream<String> stream) => super.bind(stream);
 }
 
-/// This class converts strings of only ASCII characters to bytes.
+/// Converts strings of only ASCII characters to bytes.
+///
+/// Example:
+/// ```dart import:typed_data
+/// const asciiEncoder = AsciiEncoder();
+/// const sample = 'Dart';
+/// final asciiValues = asciiEncoder.convert(sample);
+/// print(asciiValues); // [68, 97, 114, 116]
+/// ```
 class AsciiEncoder extends _UnicodeSubsetEncoder {
   const AsciiEncoder() : super(_asciiMask);
 }
@@ -195,6 +203,29 @@
   Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
 }
 
+/// Converts ASCII bytes to string.
+///
+/// Example:
+/// ```dart
+/// const asciiDecoder = AsciiDecoder();
+/// final asciiValues = [68, 97, 114, 116];
+/// final result = asciiDecoder.convert(asciiValues);
+/// print(result); // Dart
+/// ```
+/// Throws a [FormatException] if [bytes] contains values that are not
+/// in the range 0 .. 127, and [allowInvalid] is `false` (the default).
+///
+/// If [allowInvalid] is `true`, any byte outside the range 0..127 is replaced
+/// by the Unicode replacement character, U+FFFD ('�').
+///
+/// Example with `allowInvalid` set to true:
+/// ```dart
+/// const asciiDecoder = AsciiDecoder(allowInvalid: true);
+/// final asciiValues = [68, 97, 114, 116, 20, 0xFF];
+/// final result = asciiDecoder.convert(asciiValues);
+/// print(result); // Dart �
+/// print(result.codeUnits.last.toRadixString(16)); // fffd
+/// ```
 class AsciiDecoder extends _UnicodeSubsetDecoder {
   const AsciiDecoder({bool allowInvalid = false})
       : super(allowInvalid, _asciiMask);
diff --git a/sdk/lib/convert/line_splitter.dart b/sdk/lib/convert/line_splitter.dart
index 85f0ab6..2e01ae6 100644
--- a/sdk/lib/convert/line_splitter.dart
+++ b/sdk/lib/convert/line_splitter.dart
@@ -10,12 +10,31 @@
 
 /// A [StreamTransformer] that splits a [String] into individual lines.
 ///
-/// A line is terminated by either a CR (U+000D), a LF (U+000A), a
-/// CR+LF sequence (DOS line ending),
-/// and a final non-empty line can be ended by the end of the string.
+/// A line is terminated by either:
+/// * a CR, carriage return: U+000D ('\r')
+/// * a LF, line feed (Unix line break): U+000A ('\n') or
+/// * a CR+LF sequence (DOS/Windows line break), and
+/// * a final non-empty line can be ended by the end of the input.
 ///
-/// The returned lines do not contain the line terminators.
-
+/// The resulting lines do not contain the line terminators.
+///
+/// Example:
+/// ```dart
+/// const splitter = LineSplitter();
+/// const sampleText =
+///     'Dart is: \r an object-oriented \n class-based \n garbage-collected '
+///     '\r\n language with C-style syntax \r\n';
+///
+/// final sampleTextLines = splitter.convert(sampleText);
+/// for (var i = 0; i < sampleTextLines.length; i++) {
+///   print('$i: ${sampleTextLines[i]}');
+/// }
+/// // 0: Dart is:
+/// // 1:  an object-oriented
+/// // 2:  class-based
+/// // 3:  garbage-collected
+/// // 4:  language with C-style syntax
+/// ```
 class LineSplitter extends StreamTransformerBase<String, String> {
   const LineSplitter();
 
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 57a2dac..47f2647 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -40,7 +40,7 @@
   const Utf8Codec({bool allowMalformed = false})
       : _allowMalformed = allowMalformed;
 
-  /// The name of this codec, "utf-8".
+  /// The name of this codec is "utf-8".
   String get name => "utf-8";
 
   /// Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
@@ -49,7 +49,7 @@
   /// If the [codeUnits] start with the encoding of a
   /// [unicodeBomCharacterRune], that character is discarded.
   ///
-  /// If [allowMalformed] is `true` the decoder replaces invalid (or
+  /// If [allowMalformed] is `true`, the decoder replaces invalid (or
   /// unterminated) character sequences with the Unicode Replacement character
   /// `U+FFFD` (�). Otherwise it throws a [FormatException].
   ///
@@ -74,6 +74,14 @@
 
 /// This class converts strings to their UTF-8 code units (a list of
 /// unsigned 8-bit integers).
+///
+/// Example:
+/// ```dart
+/// final utf8Encoder = utf8.encoder;
+/// const sample = 'Îñţérñåţîöñåļîžåţîờñ';
+/// final encodedSample = utf8Encoder.convert(sample);
+/// print(encodedSample);
+/// ```
 class Utf8Encoder extends Converter<String, List<int>> {
   const Utf8Encoder();
 
@@ -148,10 +156,10 @@
   /// writes it to [_buffer].
   ///
   /// Returns true if the [nextCodeUnit] was combined with the
-  /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
+  /// [leadingSurrogate]. If it wasn't, then nextCodeUnit was not a trailing
   /// surrogate and has not been written yet.
   ///
-  /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+  /// It is safe to pass 0 for [nextCodeUnit], in which case a replacement
   /// character is written to represent the unpaired lead surrogate.
   bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
     if (_isTailSurrogate(nextCodeUnit)) {
@@ -285,6 +293,31 @@
 
 /// This class converts UTF-8 code units (lists of unsigned 8-bit integers)
 /// to a string.
+///
+/// Example:
+/// ```dart
+/// final utf8Decoder = utf8.decoder;
+/// const encodedBytes = [
+///   195, 142, 195, 177, 197, 163, 195, 169, 114, 195, 177, 195, 165, 197,
+///   163, 195, 174, 195, 182, 195, 177, 195, 165, 196, 188, 195, 174, 197,
+///   190, 195, 165, 197, 163, 195, 174, 225, 187, 157, 195, 177];
+///
+/// final decodedBytes = utf8Decoder.convert(encodedBytes);
+/// print(decodedBytes); // Îñţérñåţîöñåļîžåţîờñ
+/// ```
+/// Throws a [FormatException] if the encoded input contains
+/// invalid UTF-8 byte sequences and [allowMalformed] is `false` (the default).
+///
+/// If [allowMalformed] is `true`, invalid byte sequences are converted into
+/// one or more Unicode replacement characters, U+FFFD ('�').
+///
+/// Example with `allowMalformed` set to true:
+/// ```dart
+/// const utf8Decoder = Utf8Decoder(allowMalformed: true);
+/// const encodedBytes = [0xFF];
+/// final decodedBytes = utf8Decoder.convert(encodedBytes);
+/// print(decodedBytes); // �
+/// ```
 class Utf8Decoder extends Converter<List<int>, String> {
   final bool _allowMalformed;
 
@@ -293,7 +326,7 @@
   /// The optional [allowMalformed] argument defines how [convert] deals
   /// with invalid or unterminated character sequences.
   ///
-  /// If it is `true` [convert] replaces invalid (or unterminated) character
+  /// If it is `true`, [convert] replaces invalid (or unterminated) character
   /// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise
   /// it throws a [FormatException].
   const Utf8Decoder({bool allowMalformed = false})
@@ -302,7 +335,7 @@
   /// Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
   /// corresponding string.
   ///
-  /// Uses the code units from [start] to, but no including, [end].
+  /// Uses the code units from [start] to, but not including, [end].
   /// If [end] is omitted, it defaults to `codeUnits.length`.
   ///
   /// If the [codeUnits] start with the encoding of a
diff --git a/tests/language/regress/regress47566_test.dart b/tests/language/regress/regress47566_test.dart
new file mode 100644
index 0000000..4ba35ae
--- /dev/null
+++ b/tests/language/regress/regress47566_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47566
+
+import 'package:expect/expect.dart';
+
+final List trace = [];
+void log(String s) {
+  trace.add(s);
+}
+
+Future<void> test(bool value) async {
+  log('f1');
+
+  if (value) {
+    final result = await bar();
+    switch (result) {
+      case 1:
+        log('sb');
+        break;
+      case 0:
+        return;
+    }
+    log('sc');
+  }
+
+  log('f2');
+}
+
+Future<int> bar() async => 1;
+
+Future<void> main() async {
+  trace.clear();
+  await test(true);
+  Expect.equals('f1,sb,sc,f2', trace.join(','));
+
+  trace.clear();
+  await test(false);
+  Expect.equals('f1,f2', trace.join(','));
+}
diff --git a/tests/language/variable/initializer_super_last_test.dart b/tests/language/variable/initializer_super_last_test.dart
index 7e2b0b8..6bb1022 100644
--- a/tests/language/variable/initializer_super_last_test.dart
+++ b/tests/language/variable/initializer_super_last_test.dart
@@ -40,7 +40,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -48,7 +48,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -56,7 +56,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -64,7 +64,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -72,7 +72,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -83,7 +83,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -94,7 +94,7 @@
       : x = x,
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -102,7 +102,7 @@
       : x = x,
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -133,7 +133,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -141,7 +141,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -149,7 +149,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -157,7 +157,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -165,7 +165,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -176,7 +176,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -187,7 +187,7 @@
       : x = x,
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -195,7 +195,7 @@
       : x = x,
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
diff --git a/tests/language_2/variable/initializer_super_last_test.dart b/tests/language_2/variable/initializer_super_last_test.dart
index a466562..bdc36e7 100644
--- a/tests/language_2/variable/initializer_super_last_test.dart
+++ b/tests/language_2/variable/initializer_super_last_test.dart
@@ -42,7 +42,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -50,7 +50,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -58,7 +58,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -66,7 +66,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -74,7 +74,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -85,7 +85,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -96,7 +96,7 @@
       : x = x,
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -104,7 +104,7 @@
       : x = x,
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -135,7 +135,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -143,7 +143,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x;
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -151,7 +151,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -159,7 +159,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -167,7 +167,7 @@
       : //
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -178,7 +178,7 @@
       : //
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         x = x,
         //^
         // [cfe] Can't have initializers after 'super'.
@@ -189,7 +189,7 @@
       : x = x,
         super(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
@@ -197,7 +197,7 @@
       : x = x,
         super.named(),
 //      ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
         assert(x == x);
 //      ^
 // [cfe] Can't have initializers after 'super'.
diff --git a/tools/VERSION b/tools/VERSION
index a3fcafc..7b162d3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 295
+PRERELEASE 296
 PRERELEASE_PATCH 0
\ No newline at end of file