Version 2.10.0-22.0.dev

Merge commit '7e42cbf5828ae800853c4baf1745d17ebc01bf2f' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 2a728d5..12d346c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -1121,8 +1121,8 @@
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
-    listener?.handleClassExtends(extendsKeyword);
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
+    listener?.handleClassExtends(extendsKeyword, typeCount);
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 53906bc..735b41c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -126,7 +126,10 @@
 
   /// Handle an extends clause in a class declaration. Substructures:
   /// - supertype (may be a mixin application)
-  void handleClassExtends(Token extendsKeyword) {
+  /// The typeCount is for error recovery: Invalid code might have more than one
+  /// class specified in the extends clause. A parser error has already been
+  /// issued.
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     logEvent("ClassExtends");
   }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 4d1f27b..3a835f3 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -1903,10 +1903,7 @@
           const ['extend', 'on'].contains(token.next.lexeme)) {
         reportRecoverableError(
             token.next, codes.templateExpectedInstead.withArguments('extends'));
-        Token incorrectExtendsKeyword = token.next;
-        token = computeType(incorrectExtendsKeyword, /* required = */ true)
-            .ensureTypeNotVoid(incorrectExtendsKeyword, this);
-        listener.handleClassExtends(incorrectExtendsKeyword);
+        token = parseClassExtendsSeenExtendsClause(token.next, token);
       } else {
         token = parseClassExtendsOpt(token);
       }
@@ -1966,17 +1963,36 @@
     // extends <typeNotVoid>
     Token next = token.next;
     if (optional('extends', next)) {
-      Token extendsKeyword = next;
-      token = computeType(next, /* required = */ true)
-          .ensureTypeNotVoid(next, this);
-      listener.handleClassExtends(extendsKeyword);
+      token = parseClassExtendsSeenExtendsClause(next, token);
     } else {
       listener.handleNoType(token);
-      listener.handleClassExtends(/* extendsKeyword = */ null);
+      listener.handleClassExtends(null, 1);
     }
     return token;
   }
 
+  Token parseClassExtendsSeenExtendsClause(Token extendsKeyword, Token token) {
+    Token next = extendsKeyword;
+    token =
+        computeType(next, /* required = */ true).ensureTypeNotVoid(next, this);
+    int count = 1;
+
+    // Error recovery: extends <typeNotVoid>, <typeNotVoid> [...]
+    if (optional(',', token.next)) {
+      reportRecoverableError(token.next, codes.messageMultipleExtends);
+
+      while (optional(',', token.next)) {
+        next = token.next;
+        token = computeType(next, /* required = */ true)
+            .ensureTypeNotVoid(next, this);
+        count++;
+      }
+    }
+
+    listener.handleClassExtends(extendsKeyword, count);
+    return token;
+  }
+
   /// ```
   /// implementsClause:
   ///   'implements' typeName (',' typeName)*
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart b/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
index 4c1921b..9320871 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
@@ -18,9 +18,9 @@
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     this.extendsKeyword = extendsKeyword;
-    super.handleClassExtends(extendsKeyword);
+    super.handleClassExtends(extendsKeyword, typeCount);
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index b5b58a5..a29d6f0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -306,7 +306,7 @@
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     debugEvent("ClassExtends");
   }
 
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 839f9a6..0421a6d 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2447,10 +2447,16 @@
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     assert(extendsKeyword == null || extendsKeyword.isKeywordOrIdentifier);
     debugEvent("ClassExtends");
 
+    // If more extends clauses was specified (parser has already issued an
+    // error) throw them away for now and pick the first one.
+    while (typeCount > 1) {
+      pop();
+      typeCount--;
+    }
     TypeName supertype = pop();
     if (supertype != null) {
       push(ast.extendsClause(extendsKeyword, supertype));
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index bb429e9..130997a 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -1260,9 +1260,9 @@
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     expectIn('ClassDeclaration');
-    listener.handleClassExtends(extendsKeyword);
+    listener.handleClassExtends(extendsKeyword, typeCount);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 7fa2286..4ed6843 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -522,6 +522,11 @@
   @override
   void handleRecoverClassHeader() {
     debugEvent("handleRecoverClassHeader");
+    // TODO(jensj): Possibly use these instead... E.g. "class A extend B {}"
+    // will get here (because it's 'extends' with an 's') and discard the B...
+    // Also Analyzer actually merges the information meaning that the two could
+    // give different errors (if, say, one later assigns
+    // A to a variable of type B).
     pop(NullValue.TypeBuilderList); // Interfaces.
     pop(); // Supertype offset.
     pop(); // Supertype.
@@ -530,13 +535,19 @@
   @override
   void handleRecoverMixinHeader() {
     debugEvent("handleRecoverMixinHeader");
+    // TODO(jensj): Possibly use these instead...
+    // See also handleRecoverClassHeader
     pop(NullValue.TypeBuilderList); // Interfaces.
     pop(NullValue.TypeBuilderList); // Supertype constraints.
   }
 
   @override
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     debugEvent("handleClassExtends");
+    while (typeCount > 1) {
+      pop();
+      typeCount--;
+    }
     push(extendsKeyword?.charOffset ?? -1);
   }
 
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 04ff108..a16abd1 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -481,8 +481,6 @@
 MixinInferenceNoMatchingClass/example: Fail
 ModifierOutOfOrder/part_wrapped_script1: Fail
 ModifierOutOfOrder/script1: Fail
-MultipleExtends/part_wrapped_script: Fail
-MultipleExtends/script: Fail
 MultipleImplements/part_wrapped_script: Fail
 MultipleImplements/script: Fail
 MultipleLibraryDirectives/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index d41b3ac..c5a9dce 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -366,7 +366,9 @@
   template: "Each class definition can have at most one extends clause."
   tip: "Try choosing one superclass and define your class to implement (or mix in) the others."
   analyzerCode: ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES
-  script: "class A extends B extends C {}"
+  script:
+    - "class B{} class C{} class A extends B extends C {}"
+    - "class B{} class C{} class A extends B, C {}"
 
 MultipleWith:
   index: 24
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
index 9dc7216..ce13632 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
@@ -28,7 +28,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -128,7 +128,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, D)
       handleNoType(D)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
index 75db5c6..eb5a793 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
@@ -263,7 +263,7 @@
           parseClassHeaderOpt(D, class, class)
             parseClassExtendsOpt(D)
               listener: handleNoType(D)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(D)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(D)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
index 6a0a8a9..e21f896 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
@@ -128,7 +128,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
index f3d8756..5590321 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
index d876a54..cae9938 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
@@ -36,7 +36,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
index 5d87d53..6b6b94b 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
index 2939c3c..df016c6 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
@@ -32,7 +32,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
index 9fd9286..960ba0b 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
index a6c7f4b..4fdb547 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
@@ -32,7 +32,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
index 41adc50..5b09d19 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
index 32c5c13..0a3de66 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
@@ -32,7 +32,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
index 8dd7398..f618dcd 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.expect
index 6993a8e..003aeba 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.intertwined.expect
index 742aa8b..07a34d8 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_ok.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.expect
index a000871..91ce6a3 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.expect
@@ -80,7 +80,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.intertwined.expect
index a035119..99def95 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_operator.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.expect
index e78442d..3bcea14 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.expect
@@ -24,7 +24,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.intertwined.expect
index 4bbafcb..cde829e 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_return_type.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.expect
index 4240ac2..3219c73 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.expect
@@ -24,7 +24,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.intertwined.expect
index 223fd14..7233bf3 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_set.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart
new file mode 100644
index 0000000..b6a003a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart
@@ -0,0 +1,15 @@
+class A { }
+
+class B { }
+
+class Foo extends A, B {
+  Foo() { }
+}
+
+class Bar extend A, B {
+  Bar() { }
+}
+
+class Baz on A, B {
+  Baz() { }
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.expect
new file mode 100644
index 0000000..cf35cb4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.expect
@@ -0,0 +1,174 @@
+Problems reported:
+
+parser/error_recovery/issue_22313:5:20: Each class definition can have at most one extends clause.
+class Foo extends A, B {
+                   ^
+
+parser/error_recovery/issue_22313:9:11: Expected 'extends' instead of this.
+class Bar extend A, B {
+          ^^^^^^
+
+parser/error_recovery/issue_22313:9:19: Each class definition can have at most one extends clause.
+class Bar extend A, B {
+                  ^
+
+parser/error_recovery/issue_22313:13:11: Expected 'extends' instead of this.
+class Baz on A, B {
+          ^^
+
+parser/error_recovery/issue_22313:13:15: Each class definition can have at most one extends clause.
+class Baz on A, B {
+              ^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(A, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, A)
+      handleNoType(A)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(B, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, B)
+      handleNoType(B)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(Foo, classOrMixinDeclaration)
+    handleNoTypeVariables(extends)
+    beginClassDeclaration(class, null, Foo)
+      handleIdentifier(A, typeReference)
+      handleNoTypeArguments(,)
+      handleType(A, null)
+      handleRecoverableError(MultipleExtends, ,, ,)
+      handleIdentifier(B, typeReference)
+      handleNoTypeArguments({)
+      handleType(B, null)
+      handleClassExtends(extends, 2)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(Foo)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, Foo)
+            handleNoType({)
+            handleIdentifier(Foo, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+            endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+            endBlockFunctionBody(0, {, })
+          endClassConstructor(null, Foo, (, null, })
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(Bar, classOrMixinDeclaration)
+    handleNoTypeVariables(extend)
+    beginClassDeclaration(class, null, Bar)
+      handleNoType(Bar)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      handleRecoverableError(Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}], extend, extend)
+      handleIdentifier(A, typeReference)
+      handleNoTypeArguments(,)
+      handleType(A, null)
+      handleRecoverableError(MultipleExtends, ,, ,)
+      handleIdentifier(B, typeReference)
+      handleNoTypeArguments({)
+      handleType(B, null)
+      handleClassExtends(extend, 2)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleRecoverClassHeader()
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(Bar)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, Bar)
+            handleNoType({)
+            handleIdentifier(Bar, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+            endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+            endBlockFunctionBody(0, {, })
+          endClassConstructor(null, Bar, (, null, })
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(Baz, classOrMixinDeclaration)
+    handleNoTypeVariables(on)
+    beginClassDeclaration(class, null, Baz)
+      handleNoType(Baz)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      handleRecoverableError(Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}], on, on)
+      handleIdentifier(A, typeReference)
+      handleNoTypeArguments(,)
+      handleType(A, null)
+      handleRecoverableError(MultipleExtends, ,, ,)
+      handleIdentifier(B, typeReference)
+      handleNoTypeArguments({)
+      handleType(B, null)
+      handleClassExtends(on, 2)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleRecoverClassHeader()
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(Baz)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, Baz)
+            handleNoType({)
+            handleIdentifier(Baz, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+            endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+            endBlockFunctionBody(0, {, })
+          endClassConstructor(null, Baz, (, null, })
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.intertwined.expect
new file mode 100644
index 0000000..f7a6a40
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.intertwined.expect
@@ -0,0 +1,295 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(A, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, A)
+        parseClass(A, class, class, A)
+          parseClassHeaderOpt(A, class, class)
+            parseClassExtendsOpt(A)
+              listener: handleNoType(A)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(A)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(A)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(A, DeclarationKind.Class, A)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(class)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(}, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(B, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, B)
+        parseClass(B, class, class, B)
+          parseClassHeaderOpt(B, class, class)
+            parseClassExtendsOpt(B)
+              listener: handleNoType(B)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(B)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(B)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(B, DeclarationKind.Class, B)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(class)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(}, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(Foo, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(extends)
+        listener: beginClassDeclaration(class, null, Foo)
+        parseClass(Foo, class, class, Foo)
+          parseClassHeaderOpt(Foo, class, class)
+            parseClassExtendsOpt(Foo)
+              listener: handleIdentifier(A, typeReference)
+              listener: handleNoTypeArguments(,)
+              listener: handleType(A, null)
+              reportRecoverableError(,, MultipleExtends)
+                listener: handleRecoverableError(MultipleExtends, ,, ,)
+              listener: handleIdentifier(B, typeReference)
+              listener: handleNoTypeArguments({)
+              listener: handleType(B, null)
+              listener: handleClassExtends(extends, 2)
+            parseWithClauseOpt(B)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(B)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(B, DeclarationKind.Class, Foo)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, Foo)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+              parseMetadataStar({)
+                listener: beginMetadataStar(Foo)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isReservedKeyword(()
+              parseMethod({, null, null, null, null, null, null, {, Instance of 'NoType', null, Foo, DeclarationKind.Class, Foo, false)
+                listener: beginMethod(null, null, null, null, null, Foo)
+                listener: handleNoType({)
+                ensureIdentifierPotentiallyRecovered({, methodDeclaration, false)
+                  listener: handleIdentifier(Foo, methodDeclaration)
+                parseQualifiedRestOpt(Foo, methodDeclarationContinuation)
+                parseMethodTypeVar(Foo)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(Foo, Foo, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(Foo, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(0, {, })
+                listener: endClassConstructor(null, Foo, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(class)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(}, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(Bar, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(extend)
+        listener: beginClassDeclaration(class, null, Bar)
+        parseClass(Bar, class, class, Bar)
+          parseClassHeaderOpt(Bar, class, class)
+            parseClassExtendsOpt(Bar)
+              listener: handleNoType(Bar)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(Bar)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(Bar)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassHeaderRecovery(Bar, class, class)
+            parseClassHeaderOpt(Bar, class, class)
+              parseClassExtendsOpt(Bar)
+              parseWithClauseOpt(Bar)
+              parseClassOrMixinImplementsOpt(Bar)
+            skipUnexpectedTokenOpt(Bar, [extends, with, implements, {])
+            reportRecoverableError(extend, Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}])
+              listener: handleRecoverableError(Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}], extend, extend)
+            listener: handleIdentifier(A, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(A, null)
+            reportRecoverableError(,, MultipleExtends)
+              listener: handleRecoverableError(MultipleExtends, ,, ,)
+            listener: handleIdentifier(B, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(B, null)
+            listener: handleClassExtends(extend, 2)
+            parseWithClauseOpt(B)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(B)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleRecoverClassHeader()
+          ensureBlock(B, null, class declaration)
+          parseClassOrMixinOrExtensionBody(B, DeclarationKind.Class, Bar)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, Bar)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Bar)
+              parseMetadataStar({)
+                listener: beginMetadataStar(Bar)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isReservedKeyword(()
+              parseMethod({, null, null, null, null, null, null, {, Instance of 'NoType', null, Bar, DeclarationKind.Class, Bar, false)
+                listener: beginMethod(null, null, null, null, null, Bar)
+                listener: handleNoType({)
+                ensureIdentifierPotentiallyRecovered({, methodDeclaration, false)
+                  listener: handleIdentifier(Bar, methodDeclaration)
+                parseQualifiedRestOpt(Bar, methodDeclarationContinuation)
+                parseMethodTypeVar(Bar)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(Bar, Bar, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(Bar, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(0, {, })
+                listener: endClassConstructor(null, Bar, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(class)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(}, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(Baz, classOrMixinDeclaration)
+        listener: handleNoTypeVariables(on)
+        listener: beginClassDeclaration(class, null, Baz)
+        parseClass(Baz, class, class, Baz)
+          parseClassHeaderOpt(Baz, class, class)
+            parseClassExtendsOpt(Baz)
+              listener: handleNoType(Baz)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(Baz)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(Baz)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassHeaderRecovery(Baz, class, class)
+            parseClassHeaderOpt(Baz, class, class)
+              parseClassExtendsOpt(Baz)
+              parseWithClauseOpt(Baz)
+              parseClassOrMixinImplementsOpt(Baz)
+            skipUnexpectedTokenOpt(Baz, [extends, with, implements, {])
+            reportRecoverableError(on, Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}])
+              listener: handleRecoverableError(Message[ExpectedInstead, Expected 'extends' instead of this., null, {string: extends}], on, on)
+            listener: handleIdentifier(A, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(A, null)
+            reportRecoverableError(,, MultipleExtends)
+              listener: handleRecoverableError(MultipleExtends, ,, ,)
+            listener: handleIdentifier(B, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(B, null)
+            listener: handleClassExtends(on, 2)
+            parseWithClauseOpt(B)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(B)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleRecoverClassHeader()
+          ensureBlock(B, null, class declaration)
+          parseClassOrMixinOrExtensionBody(B, DeclarationKind.Class, Baz)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, Baz)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Baz)
+              parseMetadataStar({)
+                listener: beginMetadataStar(Baz)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isReservedKeyword(()
+              parseMethod({, null, null, null, null, null, null, {, Instance of 'NoType', null, Baz, DeclarationKind.Class, Baz, false)
+                listener: beginMethod(null, null, null, null, null, Baz)
+                listener: handleNoType({)
+                ensureIdentifierPotentiallyRecovered({, methodDeclaration, false)
+                  listener: handleIdentifier(Baz, methodDeclaration)
+                parseQualifiedRestOpt(Baz, methodDeclarationContinuation)
+                parseMethodTypeVar(Baz)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(Baz, Baz, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(Baz, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(0, {, })
+                listener: endClassConstructor(null, Baz, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.parser.expect
new file mode 100644
index 0000000..ebddffb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.parser.expect
@@ -0,0 +1,33 @@
+class A { }
+
+class B { }
+
+class Foo extends A, B {
+Foo() { }
+}
+
+class Bar extend A, B {
+Bar() { }
+}
+
+class Baz on A, B {
+Baz() { }
+}
+
+
+class[KeywordToken] A[StringToken] {[BeginToken] }[SimpleToken]
+
+class[KeywordToken] B[StringToken] {[BeginToken] }[SimpleToken]
+
+class[KeywordToken] Foo[StringToken] extends[KeywordToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] Bar[StringToken] extend[StringToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] Baz[StringToken] on[KeywordToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.scanner.expect
new file mode 100644
index 0000000..ebddffb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_22313.dart.scanner.expect
@@ -0,0 +1,33 @@
+class A { }
+
+class B { }
+
+class Foo extends A, B {
+Foo() { }
+}
+
+class Bar extend A, B {
+Bar() { }
+}
+
+class Baz on A, B {
+Baz() { }
+}
+
+
+class[KeywordToken] A[StringToken] {[BeginToken] }[SimpleToken]
+
+class[KeywordToken] B[StringToken] {[BeginToken] }[SimpleToken]
+
+class[KeywordToken] Foo[StringToken] extends[KeywordToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] Bar[StringToken] extend[StringToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Bar[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] Baz[StringToken] on[KeywordToken] A[StringToken],[SimpleToken] B[StringToken] {[BeginToken]
+Baz[StringToken]([BeginToken])[SimpleToken] {[BeginToken] }[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.expect
index 0f4b8c9..2ae2a55 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.expect
@@ -16,7 +16,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.intertwined.expect
index 740482c..6a32cbd 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39026.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.expect
index ada43dbc..36cbb74 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.expect
@@ -12,7 +12,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.intertwined.expect
index cb81bba..cecf6e2 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39026_prime.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.expect
index 1c9e85a..ee6d967 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.expect
@@ -24,7 +24,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.intertwined.expect
index 3784f8cb..f3f8e88 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39230.crash_dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect
index 885081b..fe48acf 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.expect
@@ -20,7 +20,7 @@
     endTypeVariables(<, >)
     beginClassDeclaration(class, null, A)
       handleNoType(>)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -58,7 +58,7 @@
       handleIdentifier(Object, typeReference)
       handleNoTypeArguments(with)
       handleType(Object, null)
-      handleClassExtends(extends)
+      handleClassExtends(extends, 1)
       beginTypeList(M)
         beginFunctionType(M)
           handleNoTypeVariables(()
@@ -78,7 +78,7 @@
       handleClassHeader(class, class, null)
       handleRecoverableError(Message[UnexpectedToken, Unexpected token '>'., null, {token: >}], >, >)
       handleNoType(>)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleRecoverClassHeader()
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect
index bceda2e..ae6d79e 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_41265.crash_dart.intertwined.expect
@@ -26,7 +26,7 @@
           parseClassHeaderOpt(>, class, class)
             parseClassExtendsOpt(>)
               listener: handleNoType(>)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(>)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(>)
@@ -88,7 +88,7 @@
               listener: handleIdentifier(Object, typeReference)
               listener: handleNoTypeArguments(with)
               listener: handleType(Object, null)
-              listener: handleClassExtends(extends)
+              listener: handleClassExtends(extends, 1)
             parseWithClauseOpt(Object)
               parseTypeList(with)
                 listener: beginTypeList(M)
@@ -126,7 +126,7 @@
                 listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token '>'., null, {token: >}], >, >)
             parseClassExtendsOpt(>)
               listener: handleNoType(>)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(>)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(>)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.expect
index c905844..29dba13 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.expect
@@ -140,7 +140,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, WrapperClass)
       handleNoType(WrapperClass)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.intertwined.expect
index 8235cd1..baabede 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_fields.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(WrapperClass, class, class)
             parseClassExtendsOpt(WrapperClass)
               listener: handleNoType(WrapperClass)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(WrapperClass)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(WrapperClass)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
index c19c42d..256ca6c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
@@ -480,7 +480,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, WrapperClass)
       handleNoType(WrapperClass)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
index 561f3c5..d61d8a2 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(WrapperClass, class, class)
             parseClassExtendsOpt(WrapperClass)
               listener: handleNoType(WrapperClass)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(WrapperClass)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(WrapperClass)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect
index 78a35b1..18cdecd 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.expect
@@ -32,7 +32,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect
index ac132e0..5086644 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect
index aba18fb..efaa895 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect
index 07e7ab5..cf0e350 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.expect
index 662eec3..b8be769 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.expect
@@ -28,7 +28,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, B)
       handleNoType(B)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -53,7 +53,7 @@
   handleNoTypeVariables({)
   beginClassDeclaration(class, null, M1)
     handleNoType(M1)
-    handleClassExtends(null)
+    handleClassExtends(null, 1)
     handleClassNoWithClause()
     handleClassOrMixinImplements(null, 0)
     handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.intertwined.expect
index 1b4821c..d6a21e4 100644
--- a/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/method_called_with_prime2.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(B, class, class)
             parseClassExtendsOpt(B)
               listener: handleNoType(B)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(B)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(B)
@@ -68,7 +68,7 @@
           parseClassHeaderOpt(M1, class, class)
             parseClassExtendsOpt(M1)
               listener: handleNoType(M1)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(M1)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(M1)
diff --git a/pkg/front_end/parser_testcases/extensions/covariant.dart.expect b/pkg/front_end/parser_testcases/extensions/covariant.dart.expect
index c797564..0b1d80d 100644
--- a/pkg/front_end/parser_testcases/extensions/covariant.dart.expect
+++ b/pkg/front_end/parser_testcases/extensions/covariant.dart.expect
@@ -12,7 +12,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -29,7 +29,7 @@
       handleIdentifier(A, typeReference)
       handleNoTypeArguments({)
       handleType(A, null)
-      handleClassExtends(extends)
+      handleClassExtends(extends, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/extensions/covariant.dart.intertwined.expect b/pkg/front_end/parser_testcases/extensions/covariant.dart.intertwined.expect
index a6bfc1c..2c95ee7 100644
--- a/pkg/front_end/parser_testcases/extensions/covariant.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/extensions/covariant.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
@@ -48,7 +48,7 @@
               listener: handleIdentifier(A, typeReference)
               listener: handleNoTypeArguments({)
               listener: handleType(A, null)
-              listener: handleClassExtends(extends)
+              listener: handleClassExtends(extends, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/extensions/not_covariant.dart.expect b/pkg/front_end/parser_testcases/extensions/not_covariant.dart.expect
index 53bb150..4bdbe33 100644
--- a/pkg/front_end/parser_testcases/extensions/not_covariant.dart.expect
+++ b/pkg/front_end/parser_testcases/extensions/not_covariant.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -23,7 +23,7 @@
       handleIdentifier(A, typeReference)
       handleNoTypeArguments({)
       handleType(A, null)
-      handleClassExtends(extends)
+      handleClassExtends(extends, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/extensions/not_covariant.dart.intertwined.expect b/pkg/front_end/parser_testcases/extensions/not_covariant.dart.intertwined.expect
index 9bfe405..79a28b8 100644
--- a/pkg/front_end/parser_testcases/extensions/not_covariant.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/extensions/not_covariant.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
@@ -48,7 +48,7 @@
               listener: handleIdentifier(A, typeReference)
               listener: handleNoTypeArguments({)
               listener: handleType(A, null)
-              listener: handleClassExtends(extends)
+              listener: handleClassExtends(extends, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/extensions/static.dart.expect b/pkg/front_end/parser_testcases/extensions/static.dart.expect
index 2552e83..9579c65 100644
--- a/pkg/front_end/parser_testcases/extensions/static.dart.expect
+++ b/pkg/front_end/parser_testcases/extensions/static.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -23,7 +23,7 @@
       handleIdentifier(A, typeReference)
       handleNoTypeArguments({)
       handleType(A, null)
-      handleClassExtends(extends)
+      handleClassExtends(extends, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/extensions/static.dart.intertwined.expect b/pkg/front_end/parser_testcases/extensions/static.dart.intertwined.expect
index cd427ab..6811d6a 100644
--- a/pkg/front_end/parser_testcases/extensions/static.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/extensions/static.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
@@ -48,7 +48,7 @@
               listener: handleIdentifier(A, typeReference)
               listener: handleNoTypeArguments({)
               listener: handleType(A, null)
-              listener: handleClassExtends(extends)
+              listener: handleClassExtends(extends, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/extensions/static_covariant.dart.expect b/pkg/front_end/parser_testcases/extensions/static_covariant.dart.expect
index 1468b4e..160198b 100644
--- a/pkg/front_end/parser_testcases/extensions/static_covariant.dart.expect
+++ b/pkg/front_end/parser_testcases/extensions/static_covariant.dart.expect
@@ -12,7 +12,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -29,7 +29,7 @@
       handleIdentifier(A, typeReference)
       handleNoTypeArguments({)
       handleType(A, null)
-      handleClassExtends(extends)
+      handleClassExtends(extends, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/extensions/static_covariant.dart.intertwined.expect b/pkg/front_end/parser_testcases/extensions/static_covariant.dart.intertwined.expect
index ff30f70..43700a3 100644
--- a/pkg/front_end/parser_testcases/extensions/static_covariant.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/extensions/static_covariant.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
@@ -48,7 +48,7 @@
               listener: handleIdentifier(A, typeReference)
               listener: handleNoTypeArguments({)
               listener: handleType(A, null)
-              listener: handleClassExtends(extends)
+              listener: handleClassExtends(extends, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect
index 12a9f7e..b92e229 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, WrapperClass)
       handleNoType(WrapperClass)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect
index 5a37e7f..768939b 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_fields.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(WrapperClass, class, class)
             parseClassExtendsOpt(WrapperClass)
               listener: handleNoType(WrapperClass)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(WrapperClass)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(WrapperClass)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
index 4e94eac..fcefd36 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, WrapperClass)
       handleNoType(WrapperClass)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
index b7770f9..5c01063 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(WrapperClass, class, class)
             parseClassExtendsOpt(WrapperClass)
               listener: handleNoType(WrapperClass)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(WrapperClass)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(WrapperClass)
diff --git a/pkg/front_end/parser_testcases/general/issue_41121.dart.expect b/pkg/front_end/parser_testcases/general/issue_41121.dart.expect
index bda3eda..9c8e9bd 100644
--- a/pkg/front_end/parser_testcases/general/issue_41121.dart.expect
+++ b/pkg/front_end/parser_testcases/general/issue_41121.dart.expect
@@ -48,7 +48,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, ConfigurationService)
       handleNoType(ConfigurationService)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -276,7 +276,7 @@
   handleNoTypeVariables({)
   beginClassDeclaration(class, null, Configuration)
     handleNoType(Configuration)
-    handleClassExtends(null)
+    handleClassExtends(null, 1)
     handleClassNoWithClause()
     handleClassOrMixinImplements(null, 0)
     handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/general/issue_41121.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_41121.dart.intertwined.expect
index 3adc87e..2f233a3 100644
--- a/pkg/front_end/parser_testcases/general/issue_41121.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_41121.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(ConfigurationService, class, class)
             parseClassExtendsOpt(ConfigurationService)
               listener: handleNoType(ConfigurationService)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(ConfigurationService)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(ConfigurationService)
@@ -509,7 +509,7 @@
           parseClassHeaderOpt(Configuration, class, class)
             parseClassExtendsOpt(Configuration)
               listener: handleNoType(Configuration)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Configuration)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Configuration)
diff --git a/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.expect b/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.expect
index 448f507..d5836cb 100644
--- a/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.expect
@@ -13,7 +13,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, operator)
       handleNoType(operator)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.intertwined.expect
index beab6b7..5926593 100644
--- a/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/operator_hat_class.crash_dart.intertwined.expect
@@ -20,7 +20,7 @@
           parseClassHeaderOpt(operator, class, class)
             parseClassExtendsOpt(operator)
               listener: handleNoType(operator)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(operator)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(operator)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
index 27c1185..7296a62 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
index 1b89b04..9d5ceaf 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
index c08e774..6fd348f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, A)
       handleNoType(A)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
index 4ef31d6..39b35af 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(A, class, class)
             parseClassExtendsOpt(A)
               listener: handleNoType(A)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(A)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(A)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.expect
index 20f0ebf..7679ad7 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.expect
@@ -32,7 +32,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.intertwined.expect
index 32130fd..e830646 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39858.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.expect
index af2a1c3..69d129c 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.intertwined.expect
index 11a7f1d..45d8491 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39858_prime1.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.expect
index 839d117..7c818a2 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.intertwined.expect
index c2748ff9..9c4a02e 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_01.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.expect
index 15a8d14..f228d46 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.expect
@@ -12,7 +12,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.intertwined.expect
index f654dbd..4d308f2 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_02.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.expect
index 5d46ab3..25f761d 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.expect
@@ -12,7 +12,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.intertwined.expect
index 97b6f75..dc89a35 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40805_03.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
index 8427048..1c8b158 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
index 1dc1fd0..8c591ce 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_01.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
index 2302dd7..44a6b48 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
index 8d144f8..5edc2bf 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_02.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
index 9aac61a..aa81a89 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Foo)
       handleNoType(Foo)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
index c80682c..4a96eb21 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Foo, class, class)
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Foo)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
index 9f7ec29..e2450db 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
@@ -72,7 +72,7 @@
 handleNoTypeVariables({)
 beginClassDeclaration(class, null, C)
   handleNoType(C)
-  handleClassExtends(null)
+  handleClassExtends(null, 1)
   handleClassNoWithClause()
   handleClassOrMixinImplements(null, 0)
   handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
index c37975a..bb28e5b 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
@@ -190,7 +190,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.expect
index 533eec5..c9fe677 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.expect
@@ -310,7 +310,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Order)
       handleNoType(Order)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
index 15743a9..c196fb5 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
@@ -628,7 +628,7 @@
           parseClassHeaderOpt(Order, class, class)
             parseClassExtendsOpt(Order)
               listener: handleNoType(Order)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Order)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Order)
diff --git a/pkg/front_end/parser_testcases/nnbd/late_member.dart.expect b/pkg/front_end/parser_testcases/nnbd/late_member.dart.expect
index 1a7d7f8..a13f528 100644
--- a/pkg/front_end/parser_testcases/nnbd/late_member.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/late_member.dart.expect
@@ -125,7 +125,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -163,7 +163,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Y)
       handleNoType(Y)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/late_member.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/late_member.dart.intertwined.expect
index f6800aa..5eea6a8 100644
--- a/pkg/front_end/parser_testcases/nnbd/late_member.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/late_member.dart.intertwined.expect
@@ -327,7 +327,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
@@ -418,7 +418,7 @@
           parseClassHeaderOpt(Y, class, class)
             parseClassExtendsOpt(Y)
               listener: handleNoType(Y)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Y)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Y)
diff --git a/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.expect b/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.expect
index 50fcc6a..c8f987c 100644
--- a/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.expect
@@ -143,7 +143,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -181,7 +181,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Y)
       handleNoType(Y)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.intertwined.expect
index 275889e..8e0a141 100644
--- a/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/late_modifier.dart.intertwined.expect
@@ -375,7 +375,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
@@ -466,7 +466,7 @@
           parseClassHeaderOpt(Y, class, class)
             parseClassExtendsOpt(Y)
               listener: handleNoType(Y)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Y)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Y)
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
index f9edc0e..939cdb7 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Class1)
       handleNoType(Class1)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
index 39fda9b..89f7fa9 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Class1, class, class)
             parseClassExtendsOpt(Class1)
               listener: handleNoType(Class1)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Class1)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Class1)
diff --git a/pkg/front_end/parser_testcases/nnbd/required_member.dart.expect b/pkg/front_end/parser_testcases/nnbd/required_member.dart.expect
index aa7af99..2258220 100644
--- a/pkg/front_end/parser_testcases/nnbd/required_member.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/required_member.dart.expect
@@ -125,7 +125,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -163,7 +163,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Y)
       handleNoType(Y)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/required_member.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/required_member.dart.intertwined.expect
index 1cacfb4..d9fa92e 100644
--- a/pkg/front_end/parser_testcases/nnbd/required_member.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/required_member.dart.intertwined.expect
@@ -327,7 +327,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
@@ -418,7 +418,7 @@
           parseClassHeaderOpt(Y, class, class)
             parseClassExtendsOpt(Y)
               listener: handleNoType(Y)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Y)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Y)
diff --git a/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.expect b/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.expect
index ea95318..31a989f 100644
--- a/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.expect
@@ -136,7 +136,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, X)
       handleNoType(X)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -174,7 +174,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Y)
       handleNoType(Y)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.intertwined.expect
index 6d72b6d..3acf91c 100644
--- a/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/required_modifier.dart.intertwined.expect
@@ -343,7 +343,7 @@
           parseClassHeaderOpt(X, class, class)
             parseClassExtendsOpt(X)
               listener: handleNoType(X)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(X)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(X)
@@ -434,7 +434,7 @@
           parseClassHeaderOpt(Y, class, class)
             parseClassExtendsOpt(Y)
               listener: handleNoType(Y)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Y)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Y)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.expect
index 80a4e35..da71b09 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, late)
       handleNoType(late)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -37,7 +37,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, required)
       handleNoType(required)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -68,7 +68,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.intertwined.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.intertwined.expect
index 686b0f5..00d7363 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40288.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(late, class, class)
             parseClassExtendsOpt(late)
               listener: handleNoType(late)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(late)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(late)
@@ -83,7 +83,7 @@
           parseClassHeaderOpt(required, class, class)
             parseClassExtendsOpt(required)
               listener: handleNoType(required)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(required)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(required)
@@ -148,7 +148,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.expect
index ea0ece2..6a706d5 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.expect
@@ -6,7 +6,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Xlate)
       handleNoType(Xlate)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -37,7 +37,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, Xrequired)
       handleNoType(Xrequired)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -68,7 +68,7 @@
     handleNoTypeVariables({)
     beginClassDeclaration(class, null, C)
       handleNoType(C)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.intertwined.expect
index 66943ef..b8149b9 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40288_prime.dart.intertwined.expect
@@ -18,7 +18,7 @@
           parseClassHeaderOpt(Xlate, class, class)
             parseClassExtendsOpt(Xlate)
               listener: handleNoType(Xlate)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Xlate)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Xlate)
@@ -83,7 +83,7 @@
           parseClassHeaderOpt(Xrequired, class, class)
             parseClassExtendsOpt(Xrequired)
               listener: handleNoType(Xrequired)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(Xrequired)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(Xrequired)
@@ -148,7 +148,7 @@
           parseClassHeaderOpt(C, class, class)
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(C)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(C)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.expect b/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.expect
index 3222c32..bc75d92 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.expect
@@ -14,7 +14,7 @@
     endTypeVariables(<, >)
     beginClassDeclaration(class, null, A)
       handleNoType(>)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleClassOrMixinImplements(null, 0)
       handleClassHeader(class, class, null)
@@ -29,7 +29,7 @@
     handleNoTypeVariables(implements)
     beginClassDeclaration(class, null, B)
       handleNoType(B)
-      handleClassExtends(null)
+      handleClassExtends(null, 1)
       handleClassNoWithClause()
       handleIdentifier(A, typeReference)
       beginTypeArguments(<)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.intertwined.expect b/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.intertwined.expect
index 85abfa4..9baf74c 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/nullable_type_argument.dart.intertwined.expect
@@ -26,7 +26,7 @@
           parseClassHeaderOpt(>, class, class)
             parseClassExtendsOpt(>)
               listener: handleNoType(>)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(>)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(>)
@@ -54,7 +54,7 @@
           parseClassHeaderOpt(B, class, class)
             parseClassExtendsOpt(B)
               listener: handleNoType(B)
-              listener: handleClassExtends(null)
+              listener: handleClassExtends(null, 1)
             parseWithClauseOpt(B)
               listener: handleClassNoWithClause()
             parseClassOrMixinImplementsOpt(B)
diff --git a/pkg/front_end/test/fasta/textual_outline_suite.dart b/pkg/front_end/test/fasta/textual_outline_suite.dart
index fa98bdb..f13c047 100644
--- a/pkg/front_end/test/fasta/textual_outline_suite.dart
+++ b/pkg/front_end/test/fasta/textual_outline_suite.dart
@@ -88,7 +88,7 @@
       result = sb.toString().trim();
 
       // Try to format.
-      Exception formatterException;
+      dynamic formatterException;
       StackTrace formatterExceptionSt;
       try {
         result = new DartFormatter().format(result);
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index f49b00a..cfccc6a 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -192,9 +192,9 @@
     indent++;
   }
 
-  void handleClassExtends(Token extendsKeyword) {
+  void handleClassExtends(Token extendsKeyword, int typeCount) {
     seen(extendsKeyword);
-    doPrint('handleClassExtends(' '$extendsKeyword)');
+    doPrint('handleClassExtends(' '$extendsKeyword, ' '$typeCount)');
   }
 
   void handleClassOrMixinImplements(
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_22313.dart b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart
new file mode 100644
index 0000000..c1b9282
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart
@@ -0,0 +1,17 @@
+class A { }
+
+class B { }
+
+class Foo extends A, B {
+  Foo() { }
+}
+
+class Bar extend A, B {
+  Bar() { }
+}
+
+class Baz on A, B {
+  Baz() { }
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.outline.expect
new file mode 100644
index 0000000..531e339
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.outline.expect
@@ -0,0 +1,92 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:5:20: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Foo extends A, B {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:11: Error: Expected 'extends' instead of this.
+// class Bar extend A, B {
+//           ^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:19: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Bar extend A, B {
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:11: Error: Expected 'extends' instead of this.
+// class Baz on A, B {
+//           ^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:15: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Baz on A, B {
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Foo extends self::A {
+  constructor •() → self::Foo*
+    ;
+}
+class Bar extends core::Object {
+  constructor •() → self::Bar*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Baz extends core::Object {
+  constructor •() → self::Baz*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.expect b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.expect
new file mode 100644
index 0000000..f1f9cb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.expect
@@ -0,0 +1,93 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:5:20: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Foo extends A, B {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:11: Error: Expected 'extends' instead of this.
+// class Bar extend A, B {
+//           ^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:19: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Bar extend A, B {
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:11: Error: Expected 'extends' instead of this.
+// class Baz on A, B {
+//           ^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:15: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Baz on A, B {
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Foo extends self::A {
+  constructor •() → self::Foo*
+    : super self::A::•() {}
+}
+class Bar extends core::Object {
+  constructor •() → self::Bar*
+    : super core::Object::•() {}
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Baz extends core::Object {
+  constructor •() → self::Baz*
+    : super core::Object::•() {}
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.transformed.expect
new file mode 100644
index 0000000..f1f9cb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.strong.transformed.expect
@@ -0,0 +1,93 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:5:20: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Foo extends A, B {
+//                    ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:11: Error: Expected 'extends' instead of this.
+// class Bar extend A, B {
+//           ^^^^^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:9:19: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Bar extend A, B {
+//                   ^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:11: Error: Expected 'extends' instead of this.
+// class Baz on A, B {
+//           ^^
+//
+// pkg/front_end/testcases/general/error_recovery/issue_22313.dart:13:15: Error: Each class definition can have at most one extends clause.
+// Try choosing one superclass and define your class to implement (or mix in) the others.
+// class Baz on A, B {
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Foo extends self::A {
+  constructor •() → self::Foo*
+    : super self::A::•() {}
+}
+class Bar extends core::Object {
+  constructor •() → self::Bar*
+    : super core::Object::•() {}
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+class Baz extends core::Object {
+  constructor •() → self::Baz*
+    : super core::Object::•() {}
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.textual_outline.expect
new file mode 100644
index 0000000..f3f3b60
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_22313.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+}
+class B {
+}
+class Foo extends A, B {
+  Foo() { }
+}
+class Bar extend A, B {
+  Bar() { }
+}
+class Baz on A, B {
+  Baz() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index f05e3ba..6603dc9 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -109,6 +109,7 @@
 general/error_recovery/constructor_recovery_operator.crash: FormatterCrash
 general/error_recovery/constructor_recovery_return_type: FormatterCrash
 general/error_recovery/constructor_recovery_set: FormatterCrash
+general/error_recovery/issue_22313: FormatterCrash
 general/error_recovery/issue_39033.crash: FormatterCrash
 general/error_recovery/issue_39058_prime.crash: FormatterCrash
 general/error_recovery/issue_39202.crash: FormatterCrash
diff --git a/tools/VERSION b/tools/VERSION
index 10ca838..771453f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 21
+PRERELEASE 22
 PRERELEASE_PATCH 0
\ No newline at end of file