Version 2.15.0-97.0.dev

Merge commit 'd80cff6b2ba676fff3eca3eaae1b2855d92718d9' into 'dev'
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a508ebd..bf9f47d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,7 +12,7 @@
     * To report an API doc bug,
       [create an SDK issue](https://github.com/dart-lang/sdk/issues/new?title=API%20doc%20issue:).
   * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)) and [dart.dev/web](https://dart.dev/web) (repo: [dart-lang/site-www/src/web](https://github.com/dart-lang/site-www/tree/master/src/web)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/wiki/Writing-for-Dart-and-Flutter-websites).
-  * Improve the API reference docs at [api.dart.dev](https://api.dart.dev) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/master/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://dart.dev/guides/language/effective-dart/documentation).
+  * Improve the API reference docs at [api.dart.dev](https://api.dart.dev) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/main/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://dart.dev/guides/language/effective-dart/documentation).
 
 ## Before you contribute
 
@@ -41,10 +41,10 @@
 ...
 ```
 
-## Keeping your branch updated with origin/master
+## Keeping your branch updated with origin/main
 
 As you work, and before you send a patch for review, you should
-ensure your branch is merging cleanly to `origin/master`.
+ensure your branch is merging cleanly to `origin/main`.
 
 There are multiple ways to do this, but we generally recommend
 running:
@@ -56,7 +56,7 @@
 Note: you can run this command from any branch.
 
 This command will fetch
-origin/master, rebase all your open branches, and delete
+origin/main, rebase all your open branches, and delete
 cleanly merged branches.
 
 Your local workflow may vary.
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 99ccd1b..48a5828 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -81,6 +81,8 @@
     for git_file in input_api.AffectedTextFiles():
         if git_file.LocalPath().startswith("pkg/front_end/testcases/"):
             continue
+        if git_file.LocalPath().startswith("pkg/front_end/parser_testcases/"):
+            continue
         if should_skip(git_file.LocalPath()):
             continue
         filename = git_file.AbsoluteLocalPath()
diff --git a/README.md b/README.md
index 79cec90..a82e962 100644
--- a/README.md
+++ b/README.md
@@ -60,12 +60,12 @@
 You can also contribute patches, as described in [Contributing][contrib].
 
 [website]: https://dart.dev
-[license]: https://github.com/dart-lang/sdk/blob/master/LICENSE
+[license]: https://github.com/dart-lang/sdk/blob/main/LICENSE
 [repo]: https://github.com/dart-lang/sdk
 [lang]: https://dart.dev/guides/language/language-tour
 [tools]: https://dart.dev/tools
 [codelabs]: https://dart.dev/codelabs
 [dartbug]: http://dartbug.com
-[contrib]: https://github.com/dart-lang/sdk/blob/master/CONTRIBUTING.md
+[contrib]: https://github.com/dart-lang/sdk/blob/main/CONTRIBUTING.md
 [pubsite]: https://pub.dev
-[patent_grant]: https://github.com/dart-lang/sdk/blob/master/PATENT_GRANT
+[patent_grant]: https://github.com/dart-lang/sdk/blob/main/PATENT_GRANT
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
index 84f65f6..d599819 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
@@ -39,6 +39,8 @@
   /// Returns true if the type has type arguments.
   bool get hasTypeArguments;
 
+  bool get recovered => false;
+
   /// Call this function when the token after [token] must be a type (not void).
   /// This function will call the appropriate event methods on the [Parser]'s
   /// listener to handle the type, inserting a synthetic type reference if
@@ -150,6 +152,7 @@
     [bool inDeclaration = false, bool acceptKeywordForSimpleType = false]) {
   Token next = token.next!;
   if (!isValidTypeReference(next)) {
+    // As next is not a valid type reference, this is all recovery.
     if (next.type.isBuiltIn) {
       TypeParamOrArgInfo typeParamOrArg =
           computeTypeParamOrArg(next, inDeclaration);
@@ -157,7 +160,8 @@
         // Recovery: built-in `<` ... `>`
         if (required || looksLikeName(typeParamOrArg.skip(next).next!)) {
           return new ComplexTypeInfo(token, typeParamOrArg)
-              .computeBuiltinOrVarAsType(required);
+              .computeBuiltinOrVarAsType(required)
+            ..recovered = true;
         }
       } else if (required || isGeneralizedFunctionType(next.next!)) {
         String? value = next.stringValue;
@@ -167,21 +171,25 @@
             !identical('operator', value) &&
             !(identical('typedef', value) && next.next!.isIdentifier))) {
           return new ComplexTypeInfo(token, typeParamOrArg)
-              .computeBuiltinOrVarAsType(required);
+              .computeBuiltinOrVarAsType(required)
+            ..recovered = true;
         }
       }
     } else if (required) {
       // Recovery
       if (optional('.', next)) {
         // Looks like prefixed type missing the prefix
-        return new ComplexTypeInfo(
+        TypeInfo result = new ComplexTypeInfo(
                 token, computeTypeParamOrArg(next, inDeclaration))
             .computePrefixedType(required);
+        if (result is ComplexTypeInfo) result.recovered = true;
+        return result;
       } else if (optional('var', next) &&
           isOneOf(next.next!, const ['<', ',', '>'])) {
         return new ComplexTypeInfo(
                 token, computeTypeParamOrArg(next, inDeclaration))
-            .computeBuiltinOrVarAsType(required);
+            .computeBuiltinOrVarAsType(required)
+          ..recovered = true;
       }
     }
     return noType;
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
index 939bcc0..099319f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
@@ -108,6 +108,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token ensureTypeNotVoid(Token token, Parser parser) {
     parser.reportRecoverableErrorWithToken(
         token.next!, codes.templateExpectedType);
@@ -155,6 +158,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token ensureTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -207,6 +213,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token parseTypeRest(Token start, Token token, Parser parser) {
     token = token.next!;
     assert(optional('?', token));
@@ -244,6 +253,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token ensureTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -291,6 +303,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token parseTypeRest(Token start, Parser parser) {
     Token token = start.next!;
     assert(optional('?', token));
@@ -324,6 +339,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token ensureTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -375,6 +393,9 @@
   bool get isFunctionType => false;
 
   @override
+  bool get recovered => false;
+
+  @override
   Token ensureTypeNotVoid(Token token, Parser parser) {
     // Report an error, then parse `void` as if it were a type name.
     parser.reportRecoverableError(token.next!, codes.messageInvalidVoid);
@@ -486,21 +507,30 @@
   /// whether it has a return type, otherwise this is `null`.
   bool? gftHasReturnType;
 
+  @override
+  bool recovered;
+
   ComplexTypeInfo(Token beforeStart, this.typeArguments)
-      : this.start = beforeStart.next! {
+      : this.start = beforeStart.next!,
+        recovered = typeArguments.recovered {
     // ignore: unnecessary_null_comparison
     assert(typeArguments != null);
   }
 
   ComplexTypeInfo._nonNullable(this.start, this.typeArguments, this.end,
-      this.typeVariableStarters, this.gftHasReturnType);
+      this.typeVariableStarters, this.gftHasReturnType, this.recovered);
 
   @override
   TypeInfo get asNonNullable {
     return beforeQuestionMark == null
         ? this
-        : new ComplexTypeInfo._nonNullable(start, typeArguments,
-            beforeQuestionMark, typeVariableStarters, gftHasReturnType);
+        : new ComplexTypeInfo._nonNullable(
+            start,
+            typeArguments,
+            beforeQuestionMark,
+            typeVariableStarters,
+            gftHasReturnType,
+            recovered);
   }
 
   @override
@@ -689,7 +719,7 @@
 
   /// Given a builtin, return the receiver so that parseType will report
   /// an error for the builtin used as a type.
-  TypeInfo computeBuiltinOrVarAsType(bool required) {
+  ComplexTypeInfo computeBuiltinOrVarAsType(bool required) {
     assert(start.type.isBuiltIn || optional('var', start));
 
     end = typeArguments.skip(start);
@@ -963,6 +993,7 @@
     while (true) {
       TypeInfo typeInfo =
           computeType(next, /* required = */ true, inDeclaration);
+      recovered = recovered | typeInfo.recovered;
       if (typeInfo == noType) {
         while (typeInfo == noType && optional('@', next.next!)) {
           next = skipMetadata(next);
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 22d4a61..364ce65 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -882,7 +882,8 @@
 
     DartType getParameterType(ir.VariableDeclaration variable) {
       // isCovariant implies this FunctionNode is a class Procedure.
-      var isCovariant = variable.isCovariant || variable.isGenericCovariantImpl;
+      var isCovariant =
+          variable.isCovariantByDeclaration || variable.isCovariantByClass;
       var isFromNonNullableByDefaultLibrary = isCovariant &&
           (node.parent as ir.Procedure).enclosingLibrary.isNonNullableByDefault;
       return types.getTearOffParameterType(getDartType(variable.type),
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 7bf5db7..08eea71 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -518,7 +518,8 @@
 
     DartType getParameterType(ir.VariableDeclaration variable) {
       // isCovariant implies this FunctionNode is a class Procedure.
-      var isCovariant = variable.isCovariant || variable.isGenericCovariantImpl;
+      var isCovariant =
+          variable.isCovariantByDeclaration || variable.isCovariantByClass;
       var isFromNonNullableByDefaultLibrary = isCovariant &&
           (node.parent as ir.Procedure).enclosingLibrary.isNonNullableByDefault;
       return types.getTearOffParameterType(getDartType(variable.type),
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index e74ad8a..d1755aa 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1409,7 +1409,7 @@
 
       if (targetChecks.checkAllParameters ||
           (targetChecks.checkCovariantParameters &&
-              (variable.isGenericCovariantImpl || variable.isCovariant))) {
+              (variable.isCovariantByClass || variable.isCovariantByDeclaration))) {
         newParameter = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
             targetElement, newParameter, type);
       } else {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 102b0e8..dbea6f0 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -3719,7 +3719,7 @@
   void _emitCovarianceBoundsCheck(
       List<TypeParameter> typeFormals, List<js_ast.Statement> body) {
     for (var t in typeFormals) {
-      if (t.isGenericCovariantImpl && !_types.isTop(t.bound)) {
+      if (t.isCovariantByClass && !_types.isTop(t.bound)) {
         body.add(runtimeStatement('checkTypeBound(#, #, #)', [
           _emitTypeParameterType(TypeParameterType(t, Nullability.undetermined),
               emitNullability: false),
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 166080a..958e4af 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -211,13 +211,13 @@
 /// Whether the parameter [p] is covariant (either explicitly `covariant` or
 /// implicitly due to generics) and needs a check for soundness.
 bool isCovariantParameter(VariableDeclaration p) {
-  return p.isCovariant || p.isGenericCovariantImpl;
+  return p.isCovariantByDeclaration || p.isCovariantByClass;
 }
 
 /// Whether the field [p] is covariant (either explicitly `covariant` or
 /// implicitly due to generics) and needs a check for soundness.
 bool isCovariantField(Field f) {
-  return f.isCovariant || f.isGenericCovariantImpl;
+  return f.isCovariantByDeclaration || f.isCovariantByClass;
 }
 
 /// Returns true iff this factory constructor just throws [UnsupportedError]/
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index fc403b3..294b9a3 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -273,8 +273,8 @@
       var name = field.name.text;
       if (virtualAccessorNames.contains(name) ||
           fieldModel.isVirtual(field) ||
-          field.isCovariant ||
-          field.isGenericCovariantImpl) {
+          field.isCovariantByDeclaration ||
+          field.isCovariantByClass) {
         virtualFields[field] = js_ast.TemporaryId(js_ast.toJSIdentifier(name));
       }
     }
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 2bab515..2f8ae5c 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -276,14 +276,15 @@
 
   _CovarianceTransformer(this._library);
 
-  /// Transforms [_library], eliminating unncessary checks for private members.
+  /// Transforms [_library], eliminating unnecessary checks for private members.
   ///
   /// Kernel will mark covariance checks on members, for example:
-  /// - a field with [Field.isGenericCovariantImpl] or [Field.isCovariant].
+  /// - a field with [Field.isCovariantByClass] or
+  ///   [Field.isCovariantByDeclaration].
   /// - a method/setter with parameter(s) or type parameter(s) that have
-  ///   `isGenericCovariantImpl` or `isCovariant` set.
+  ///   `isCovariantByClass` or `isCovariantByDeclaration` set.
   ///
-  /// If the check can be safely eliminanted, those properties will be set to
+  /// If the check can be safely eliminated, those properties will be set to
   /// false so the JS compiler does not emit checks.
   ///
   /// Public members always need covariance checks (we cannot see all potential
@@ -319,13 +320,13 @@
     // Update the tree based on the methods that need checks.
     for (var field in _privateFields) {
       if (!_checkedMembers.contains(field)) {
-        field.isCovariant = false;
-        field.isGenericCovariantImpl = false;
+        field.isCovariantByDeclaration = false;
+        field.isCovariantByClass = false;
       }
     }
     void clearCovariant(VariableDeclaration parameter) {
-      parameter.isCovariant = false;
-      parameter.isGenericCovariantImpl = false;
+      parameter.isCovariantByDeclaration = false;
+      parameter.isCovariantByClass = false;
     }
 
     for (var member in _privateProcedures) {
@@ -334,7 +335,7 @@
         function.positionalParameters.forEach(clearCovariant);
         function.namedParameters.forEach(clearCovariant);
         for (var t in function.typeParameters) {
-          t.isGenericCovariantImpl = false;
+          t.isCovariantByClass = false;
         }
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index e3b28d2..2c6ea0c 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -50,7 +50,7 @@
 
   TypeBuilder? get type;
 
-  bool get isCovariant;
+  bool get isCovariantByDeclaration;
 
   bool get isLate;
 
@@ -154,7 +154,7 @@
           isAbstract: isAbstract,
           isExternal: isExternal,
           isFinal: isFinal,
-          isCovariant: isCovariant,
+          isCovariantByDeclaration: isCovariantByDeclaration,
           isNonNullableByDefault: library.isNonNullableByDefault);
     } else if (isLate &&
         libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
@@ -175,7 +175,7 @@
               lateIsSetSetterReference,
               lateGetterReference,
               lateSetterReference,
-              isCovariant,
+              isCovariantByDeclaration,
               isSetStrategy);
         } else {
           _fieldEncoding = new LateFieldWithInitializerEncoding(
@@ -190,7 +190,7 @@
               lateIsSetSetterReference,
               lateGetterReference,
               lateSetterReference,
-              isCovariant,
+              isCovariantByDeclaration,
               isSetStrategy);
         }
       } else {
@@ -207,7 +207,7 @@
               lateIsSetSetterReference,
               lateGetterReference,
               lateSetterReference,
-              isCovariant,
+              isCovariantByDeclaration,
               isSetStrategy);
         } else {
           _fieldEncoding = new LateFieldWithoutInitializerEncoding(
@@ -222,7 +222,7 @@
               lateIsSetSetterReference,
               lateGetterReference,
               lateSetterReference,
-              isCovariant,
+              isCovariantByDeclaration,
               isSetStrategy);
         }
       }
@@ -244,7 +244,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
       } else {
         _fieldEncoding = new LateFieldWithInitializerEncoding(
@@ -259,7 +259,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
       }
     } else {
@@ -320,7 +320,7 @@
   bool get isLate => (modifiers & lateMask) != 0;
 
   @override
-  bool get isCovariant => (modifiers & covariantMask) != 0;
+  bool get isCovariantByDeclaration => (modifiers & covariantMask) != 0;
 
   @override
   bool get hasInitializer => (modifiers & hasInitializerMask) != 0;
@@ -665,7 +665,7 @@
   @override
   void build(
       SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
-    _field..isCovariant = fieldBuilder.isCovariant;
+    _field..isCovariantByDeclaration = fieldBuilder.isCovariantByDeclaration;
     if (fieldBuilder.isExtensionMember) {
       _field
         ..isStatic = true
@@ -695,7 +695,7 @@
 
   @override
   void setGenericCovariantImpl() {
-    _field.isGenericCovariantImpl = true;
+    _field.isCovariantByClass = true;
   }
 
   @override
@@ -814,7 +814,7 @@
       Reference? lateIsSetSetterReference,
       Reference? lateGetterReference,
       Reference? lateSetterReference,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       late_lowering.IsSetStrategy isSetStrategy)
       : fileOffset = charOffset,
         fileEndOffset = charEndOffset,
@@ -867,7 +867,7 @@
         fileUri,
         charOffset,
         lateSetterReference,
-        isCovariant: isCovariant);
+        isCovariantByDeclaration: isCovariantByDeclaration);
   }
 
   late_lowering.IsSetEncoding get isSetEncoding {
@@ -975,11 +975,11 @@
 
   Procedure? _createSetter(
       Name name, Uri fileUri, int charOffset, Reference? reference,
-      {required bool isCovariant}) {
+      {required bool isCovariantByDeclaration}) {
     // ignore: unnecessary_null_comparison
-    assert(isCovariant != null);
+    assert(isCovariantByDeclaration != null);
     VariableDeclaration parameter = new VariableDeclaration(null)
-      ..isCovariant = isCovariant
+      ..isCovariantByDeclaration = isCovariantByDeclaration
       ..fileOffset = fileOffset;
     return new Procedure(
         name,
@@ -1025,9 +1025,8 @@
 
   @override
   void setGenericCovariantImpl() {
-    _field.isGenericCovariantImpl = true;
-    _lateSetter?.function.positionalParameters.single.isGenericCovariantImpl =
-        true;
+    _field.isCovariantByClass = true;
+    _lateSetter?.function.positionalParameters.single.isCovariantByClass = true;
   }
 
   @override
@@ -1198,7 +1197,7 @@
       Reference? lateIsSetSetterReference,
       Reference? lateGetterReference,
       Reference? lateSetterReference,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
             name,
@@ -1212,7 +1211,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
 }
 
@@ -1230,7 +1229,7 @@
       Reference? lateIsSetSetterReference,
       Reference? lateGetterReference,
       Reference? lateSetterReference,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
             name,
@@ -1244,7 +1243,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
 
   @override
@@ -1277,7 +1276,7 @@
       Reference? lateIsSetSetterReference,
       Reference? lateGetterReference,
       Reference? lateSetterReference,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
             name,
@@ -1291,7 +1290,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
 
   @override
@@ -1325,7 +1324,7 @@
       Reference? lateIsSetSetterReference,
       Reference? lateGetterReference,
       Reference? lateSetterReference,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
             name,
@@ -1339,7 +1338,7 @@
             lateIsSetSetterReference,
             lateGetterReference,
             lateSetterReference,
-            isCovariant,
+            isCovariantByDeclaration,
             isSetStrategy);
   @override
   Statement _createGetterBody(
@@ -1360,7 +1359,7 @@
   @override
   Procedure? _createSetter(
           Name name, Uri fileUri, int charOffset, Reference? reference,
-          {required bool isCovariant}) =>
+          {required bool isCovariantByDeclaration}) =>
       null;
 
   @override
@@ -1537,7 +1536,7 @@
       {required this.isAbstract,
       required this.isExternal,
       required bool isFinal,
-      required bool isCovariant,
+      required bool isCovariantByDeclaration,
       required bool isNonNullableByDefault})
       // ignore: unnecessary_null_comparison
       : assert(isAbstract != null),
@@ -1546,7 +1545,7 @@
         // ignore: unnecessary_null_comparison
         assert(isFinal != null),
         // ignore: unnecessary_null_comparison
-        assert(isCovariant != null),
+        assert(isCovariantByDeclaration != null),
         // ignore: unnecessary_null_comparison
         assert(isNonNullableByDefault != null),
         _isExtensionInstanceMember = isExternal &&
@@ -1567,7 +1566,7 @@
       if (!isFinal) {
         VariableDeclaration parameter =
             new VariableDeclaration("#externalFieldValue")
-              ..isCovariant = isCovariant
+              ..isCovariantByDeclaration = isCovariantByDeclaration
               ..fileOffset = charOffset;
         _setter = new Procedure(
             nameScheme.getProcedureName(ProcedureKind.Setter, name),
@@ -1600,7 +1599,7 @@
       if (!isFinal) {
         VariableDeclaration parameter =
             new VariableDeclaration("#externalFieldValue")
-              ..isCovariant = isCovariant
+              ..isCovariantByDeclaration = isCovariantByDeclaration
               ..fileOffset = charOffset;
         _setter = new Procedure(
             nameScheme.getFieldName(FieldNameType.Setter, name,
@@ -1742,7 +1741,7 @@
 
   @override
   void setGenericCovariantImpl() {
-    _setter!.function.positionalParameters.first.isGenericCovariantImpl = true;
+    _setter!.function.positionalParameters.first.isCovariantByClass = true;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 216d044..bd77903 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -116,7 +116,7 @@
 
   bool get isInitializingFormal => (modifiers & initializingFormalMask) != 0;
 
-  bool get isCovariant => (modifiers & covariantMask) != 0;
+  bool get isCovariantByDeclaration => (modifiers & covariantMask) != 0;
 
   // An initializing formal parameter might be final without its
   // VariableDeclaration being final. See
@@ -142,7 +142,7 @@
           isFinal: isFinal,
           isConst: isConst,
           isFieldFormal: isInitializingFormal,
-          isCovariant: isCovariant,
+          isCovariantByDeclaration: isCovariantByDeclaration,
           isRequired: isNamedRequired,
           hasDeclaredInitializer: hasDeclaredInitializer,
           isLowered: isExtensionThis)
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index c462800..0f1cb27 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -346,7 +346,7 @@
         function.typeParameters.add(parameter);
         if (needsCheckVisitor != null) {
           if (parameter.bound.accept(needsCheckVisitor)) {
-            parameter.isGenericCovariantImpl = true;
+            parameter.isCovariantByClass = true;
           }
         }
       }
@@ -358,7 +358,7 @@
             nonInstanceContext: !isConstructor && !isDeclarationInstanceMember);
         if (needsCheckVisitor != null) {
           if (parameter.type.accept(needsCheckVisitor)) {
-            parameter.isGenericCovariantImpl = true;
+            parameter.isCovariantByClass = true;
           }
         }
         if (formal.isNamed) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 99eba28..b11496e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -422,7 +422,9 @@
   List<TypeParameter> aTypeParameters = a.typeParameters;
   List<TypeParameter> bTypeParameters = b.typeParameters;
   int typeParameterCount = aTypeParameters.length;
-  if (typeParameterCount != bTypeParameters.length) return false;
+  if (typeParameterCount != bTypeParameters.length) {
+    return false;
+  }
   Substitution? substitution;
   if (typeParameterCount != 0) {
     List<DartType> types = new List<DartType>.generate(
@@ -434,11 +436,15 @@
     for (int i = 0; i < typeParameterCount; i++) {
       DartType aBound = aTypeParameters[i].bound;
       DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
-      if (aBound != bBound) return false;
+      if (aBound != bBound) {
+        return false;
+      }
     }
   }
 
-  if (a.requiredParameterCount != b.requiredParameterCount) return false;
+  if (a.requiredParameterCount != b.requiredParameterCount) {
+    return false;
+  }
   List<VariableDeclaration> aPositionalParameters = a.positionalParameters;
   List<VariableDeclaration> bPositionalParameters = b.positionalParameters;
   if (aPositionalParameters.length != bPositionalParameters.length) {
@@ -447,7 +453,10 @@
   for (int i = 0; i < aPositionalParameters.length; i++) {
     VariableDeclaration aParameter = aPositionalParameters[i];
     VariableDeclaration bParameter = bPositionalParameters[i];
-    if (aParameter.isCovariant != bParameter.isCovariant) return false;
+    if (aParameter.isCovariantByDeclaration !=
+        bParameter.isCovariantByDeclaration) {
+      return false;
+    }
     DartType aType = aParameter.type;
     DartType bType = bParameter.type;
     if (substitution != null) {
@@ -458,18 +467,27 @@
 
   List<VariableDeclaration> aNamedParameters = a.namedParameters;
   List<VariableDeclaration> bNamedParameters = b.namedParameters;
-  if (aNamedParameters.length != bNamedParameters.length) return false;
+  if (aNamedParameters.length != bNamedParameters.length) {
+    return false;
+  }
   for (int i = 0; i < aNamedParameters.length; i++) {
     VariableDeclaration aParameter = aNamedParameters[i];
     VariableDeclaration bParameter = bNamedParameters[i];
-    if (aParameter.isCovariant != bParameter.isCovariant) return false;
-    if (aParameter.name != bParameter.name) return false;
+    if (aParameter.isCovariantByDeclaration !=
+        bParameter.isCovariantByDeclaration) {
+      return false;
+    }
+    if (aParameter.name != bParameter.name) {
+      return false;
+    }
     DartType aType = aParameter.type;
     DartType bType = bParameter.type;
     if (substitution != null) {
       bType = substitution.substituteType(bType);
     }
-    if (aType != bType) return false;
+    if (aType != bType) {
+      return false;
+    }
   }
 
   DartType aReturnType = a.returnType;
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index 59f914c..414c8c2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -483,8 +483,8 @@
               member.function.positionalParameters.first;
           combinedMemberSignature = _createSetterMemberSignature(
               member, combinedMemberSignatureType!,
-              isGenericCovariantImpl: parameter.isGenericCovariantImpl,
-              isCovariant: parameter.isCovariant,
+              isCovariantByClass: parameter.isCovariantByClass,
+              isCovariantByDeclaration: parameter.isCovariantByDeclaration,
               parameter: parameter,
               copyLocation: copyLocation);
           break;
@@ -503,8 +503,8 @@
       if (forSetter) {
         combinedMemberSignature = _createSetterMemberSignature(
             member, combinedMemberSignatureType!,
-            isGenericCovariantImpl: member.isGenericCovariantImpl,
-            isCovariant: member.isCovariant,
+            isCovariantByClass: member.isCovariantByClass,
+            isCovariantByDeclaration: member.isCovariantByDeclaration,
             copyLocation: copyLocation);
       } else {
         combinedMemberSignature = _createGetterMemberSignature(
@@ -559,17 +559,18 @@
   }
 
   /// Creates a setter member signature for [member] with the given
-  /// [type]. The flags of parameter is set according to [isCovariant] and
-  /// [isGenericCovariantImpl] and the [parameterName] is used, if provided.
+  /// [type]. The flags of parameter is set according to
+  /// [isCovariantByDeclaration] and [isCovariantByClass] and the name of the
+  /// [parameter] is used, if provided.
   Procedure _createSetterMemberSignature(Member member, DartType type,
-      {required bool isCovariant,
-      required bool isGenericCovariantImpl,
+      {required bool isCovariantByDeclaration,
+      required bool isCovariantByClass,
       VariableDeclaration? parameter,
       required bool copyLocation}) {
     // ignore: unnecessary_null_comparison
-    assert(isCovariant != null);
+    assert(isCovariantByDeclaration != null);
     // ignore: unnecessary_null_comparison
-    assert(isGenericCovariantImpl != null);
+    assert(isCovariantByClass != null);
     // ignore: unnecessary_null_comparison
     assert(copyLocation != null);
     Class enclosingClass = classBuilder.cls;
@@ -594,8 +595,8 @@
           returnType: const VoidType(),
           positionalParameters: [
             new VariableDeclaration(parameter?.name ?? 'value',
-                type: type, isCovariant: isCovariant)
-              ..isGenericCovariantImpl = isGenericCovariantImpl
+                type: type, isCovariantByDeclaration: isCovariantByDeclaration)
+              ..isCovariantByClass = isCovariantByClass
               ..fileOffset = copyLocation
                   ? parameter?.fileOffset ?? fileOffset
                   : fileOffset
@@ -638,8 +639,9 @@
       VariableDeclaration parameter = function.positionalParameters[i];
       DartType parameterType = functionType.positionalParameters[i];
       positionalParameters.add(new VariableDeclaration(parameter.name,
-          type: parameterType, isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+          type: parameterType,
+          isCovariantByDeclaration: parameter.isCovariantByDeclaration)
+        ..isCovariantByClass = parameter.isCovariantByClass
         ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
     }
     List<VariableDeclaration> namedParameters = [];
@@ -650,8 +652,8 @@
       namedParameters.add(new VariableDeclaration(parameter.name,
           type: namedType.type,
           isRequired: namedType.isRequired,
-          isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+          isCovariantByDeclaration: parameter.isCovariantByDeclaration)
+        ..isCovariantByClass = parameter.isCovariantByClass
         ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
     } else if (namedParameterCount > 1) {
       Map<String, NamedType> namedTypes = {};
@@ -664,8 +666,8 @@
         namedParameters.add(new VariableDeclaration(parameter.name,
             type: namedParameterType.type,
             isRequired: namedParameterType.isRequired,
-            isCovariant: parameter.isCovariant)
-          ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+            isCovariantByDeclaration: parameter.isCovariantByDeclaration)
+          ..isCovariantByClass = parameter.isCovariantByClass
           ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 12ba226..2d5435a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -645,7 +645,7 @@
       bool isFinal: false,
       bool isConst: false,
       bool isFieldFormal: false,
-      bool isCovariant: false,
+      bool isCovariantByDeclaration: false,
       bool isLocalFunction: false}) {
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
@@ -655,7 +655,7 @@
         isFinal: isFinal,
         isConst: isConst,
         isFieldFormal: isFieldFormal,
-        isCovariant: isCovariant,
+        isCovariantByDeclaration: isCovariantByDeclaration,
         isLocalFunction: isLocalFunction,
         hasDeclaredInitializer: initializer != null);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 3a1de7d..92a9dca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1592,7 +1592,7 @@
       bool isFinal: false,
       bool isConst: false,
       bool isFieldFormal: false,
-      bool isCovariant: false,
+      bool isCovariantByDeclaration: false,
       bool isLocalFunction: false,
       bool isLate: false,
       bool isRequired: false,
@@ -1606,7 +1606,7 @@
             isFinal: isFinal,
             isConst: isConst,
             isFieldFormal: isFieldFormal,
-            isCovariant: isCovariant,
+            isCovariantByDeclaration: isCovariantByDeclaration,
             isLate: isLate,
             isRequired: isRequired,
             isLowered: isLowered);
diff --git a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
index 03c89ce..1e7600c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
@@ -17,32 +17,32 @@
 
   /// Returns the covariance mask for [parameter].
   static int covarianceFromParameter(VariableDeclaration parameter) =>
-      (parameter.isCovariant ? Covariant : 0) |
-      (parameter.isGenericCovariantImpl ? GenericCovariantImpl : 0);
+      (parameter.isCovariantByDeclaration ? Covariant : 0) |
+      (parameter.isCovariantByClass ? GenericCovariantImpl : 0);
 
   /// Returns the covariance mask for [field].
   static int covarianceFromField(Field field) =>
-      (field.isCovariant ? Covariant : 0) |
-      (field.isGenericCovariantImpl ? GenericCovariantImpl : 0);
+      (field.isCovariantByDeclaration ? Covariant : 0) |
+      (field.isCovariantByClass ? GenericCovariantImpl : 0);
 
   /// Applies the [covariance] mask to [parameter].
   static void covarianceToParameter(
       int covariance, VariableDeclaration parameter) {
     if ((covariance & Covariant) != 0) {
-      parameter.isCovariant = true;
+      parameter.isCovariantByDeclaration = true;
     }
     if ((covariance & GenericCovariantImpl) != 0) {
-      parameter.isGenericCovariantImpl = true;
+      parameter.isCovariantByClass = true;
     }
   }
 
   /// Applies the [covariance] mask to parameter.
   static void covarianceToField(int covariance, Field field) {
     if ((covariance & Covariant) != 0) {
-      field.isCovariant = true;
+      field.isCovariantByDeclaration = true;
     }
     if ((covariance & GenericCovariantImpl) != 0) {
-      field.isGenericCovariantImpl = true;
+      field.isCovariantByClass = true;
     }
   }
 
@@ -133,7 +133,7 @@
     List<bool>? typeParameters;
     if (function.typeParameters.isNotEmpty) {
       for (int index = 0; index < function.typeParameters.length; index++) {
-        if (function.typeParameters[index].isGenericCovariantImpl) {
+        if (function.typeParameters[index].isCovariantByClass) {
           typeParameters ??=
               new List<bool>.filled(function.typeParameters.length, false);
           typeParameters[index] = true;
@@ -289,7 +289,7 @@
         for (int index = 0; index < typeParameters.length; index++) {
           if (index < function.typeParameters.length) {
             if (typeParameters[index]) {
-              function.typeParameters[index].isGenericCovariantImpl = true;
+              function.typeParameters[index].isCovariantByClass = true;
             }
           }
         }
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index f6e9a39..db65cb2 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -519,6 +519,9 @@
     scope._local.forEach(mergeMember);
     map = _setters;
     scope._setters.forEach(mergeMember);
+    if (scope._extensions != null) {
+      (_extensions ??= {}).addAll(scope._extensions!);
+    }
   }
 
   void forEach(f(String name, Builder member)) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 0809082..cfd33e0 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -353,7 +353,7 @@
       }
       if (fieldBuilder.isClassInstanceMember &&
           fieldBuilder.isAssignable &&
-          !fieldBuilder.isCovariant) {
+          !fieldBuilder.isCovariantByDeclaration) {
         fieldVariance = Variance.combine(Variance.contravariant, fieldVariance);
         reportVariancePositionIfInvalid(fieldVariance, typeParameter,
             fieldBuilder.fileUri, fieldBuilder.charOffset);
@@ -385,7 +385,7 @@
     // ignore: unnecessary_null_comparison
     if (positionalParameters != null) {
       for (VariableDeclaration formal in positionalParameters) {
-        if (!formal.isCovariant) {
+        if (!formal.isCovariantByDeclaration) {
           for (TypeParameter typeParameter in typeParameters) {
             int formalVariance = Variance.combine(Variance.contravariant,
                 computeVariance(typeParameter, formal.type));
@@ -1285,7 +1285,7 @@
       for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
         TypeParameter declaredParameter = declaredFunction.typeParameters[i];
         TypeParameter interfaceParameter = interfaceFunction!.typeParameters[i];
-        if (!interfaceParameter.isGenericCovariantImpl) {
+        if (!interfaceParameter.isCovariantByClass) {
           DartType declaredBound = declaredParameter.bound;
           DartType interfaceBound = interfaceParameter.bound;
           if (interfaceSubstitution != null) {
@@ -1359,7 +1359,7 @@
       Member interfaceMemberOrigin,
       DartType declaredType,
       DartType interfaceType,
-      bool isCovariant,
+      bool isCovariantByDeclaration,
       VariableDeclaration? declaredParameter,
       bool isInterfaceCheck,
       bool declaredNeedsLegacyErasure,
@@ -1386,7 +1386,7 @@
     if (types.isSubtypeOf(
         subtype, supertype, SubtypeCheckMode.withNullabilities)) {
       // No problem--the proper subtyping relation is satisfied.
-    } else if (isCovariant &&
+    } else if (isCovariantByDeclaration &&
         types.isSubtypeOf(
             supertype, subtype, SubtypeCheckMode.withNullabilities)) {
       // No problem--the overriding parameter is marked "covariant" and has
@@ -1398,7 +1398,7 @@
       // Report an error.
       bool isErrorInNnbdOptedOutMode = !types.isSubtypeOf(
               subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
-          (!isCovariant ||
+          (!isCovariantByDeclaration ||
               !types.isSubtypeOf(
                   supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
       if (isErrorInNnbdOptedOutMode || library.isNonNullableByDefault) {
@@ -1493,8 +1493,8 @@
         interfaceMemberOrigin,
         declaredFunction.returnType,
         interfaceFunction.returnType,
-        false,
-        null,
+        /* isCovariantByDeclaration = */ false,
+        /* declaredParameter = */ null,
         isInterfaceCheck,
         declaredNeedsLegacyErasure);
     if (declaredFunction.positionalParameters.length <
@@ -1563,11 +1563,12 @@
           interfaceMemberOrigin,
           declaredParameter.type,
           interfaceParameter.type,
-          declaredParameter.isCovariant || interfaceParameter.isCovariant,
+          declaredParameter.isCovariantByDeclaration ||
+              interfaceParameter.isCovariantByDeclaration,
           declaredParameter,
           isInterfaceCheck,
           declaredNeedsLegacyErasure);
-      if (declaredParameter.isCovariant) seenCovariant = true;
+      if (declaredParameter.isCovariantByDeclaration) seenCovariant = true;
     }
     if (declaredFunction.namedParameters.isEmpty &&
         interfaceFunction.namedParameters.isEmpty) {
@@ -1643,7 +1644,7 @@
           interfaceMemberOrigin,
           declaredParameter.type,
           interfaceNamedParameters.current.type,
-          declaredParameter.isCovariant,
+          declaredParameter.isCovariantByDeclaration,
           declaredParameter,
           isInterfaceCheck,
           declaredNeedsLegacyErasure);
@@ -1670,7 +1671,7 @@
                       interfaceMemberOrigin.fileOffset, noLength)
             ]);
       }
-      if (declaredParameter.isCovariant) seenCovariant = true;
+      if (declaredParameter.isCovariantByDeclaration) seenCovariant = true;
     }
     return seenCovariant;
   }
@@ -1709,7 +1710,7 @@
         interfaceMemberOrigin,
         declaredType,
         interfaceType,
-        /* isCovariant = */ false,
+        /* isCovariantByDeclaration = */ false,
         /* declaredParameter = */ null,
         isInterfaceCheck,
         declaredNeedsLegacyErasure);
@@ -1745,12 +1746,13 @@
     DartType interfaceType = interfaceMember.setterType;
     VariableDeclaration? declaredParameter =
         declaredMember.function?.positionalParameters.elementAt(0);
-    bool isCovariant = declaredParameter?.isCovariant ?? false;
-    if (!isCovariant && declaredMember is Field) {
-      isCovariant = declaredMember.isCovariant;
+    bool isCovariantByDeclaration =
+        declaredParameter?.isCovariantByDeclaration ?? false;
+    if (!isCovariantByDeclaration && declaredMember is Field) {
+      isCovariantByDeclaration = declaredMember.isCovariantByDeclaration;
     }
-    if (!isCovariant && interfaceMember is Field) {
-      isCovariant = interfaceMember.isCovariant;
+    if (!isCovariantByDeclaration && interfaceMember is Field) {
+      isCovariantByDeclaration = interfaceMember.isCovariantByDeclaration;
     }
     _checkTypes(
         types,
@@ -1761,12 +1763,12 @@
         interfaceMemberOrigin,
         declaredType,
         interfaceType,
-        isCovariant,
+        isCovariantByDeclaration,
         declaredParameter,
         isInterfaceCheck,
         declaredNeedsLegacyErasure,
         asIfDeclaredParameter: true);
-    return isCovariant;
+    return isCovariantByDeclaration;
   }
 
   // When the overriding member is inherited, report the class containing
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart b/pkg/front_end/parser_testcases/general/issue_47008_01.dart
new file mode 100644
index 0000000..388e5d8
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart
@@ -0,0 +1,3 @@
+main() {
+  a(b < c, d < e, 1 >> (2));
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.expect b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.expect
new file mode 100644
index 0000000..c74a161
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.expect
@@ -0,0 +1,47 @@
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(b, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(b, <)
+          beginBinaryExpression(<)
+            handleIdentifier(c, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(c, ,)
+          endBinaryExpression(<)
+          handleIdentifier(d, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(d, <)
+          beginBinaryExpression(<)
+            handleIdentifier(e, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(e, ,)
+          endBinaryExpression(<)
+          handleLiteralInt(1)
+          beginBinaryExpression(>>)
+            handleLiteralInt(2)
+            handleParenthesizedExpression(()
+          endBinaryExpression(>>)
+        endArguments(3, (, ))
+        handleSend(a, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect
new file mode 100644
index 0000000..406fe2c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect
@@ -0,0 +1,137 @@
+parseUnit(main)
+  skipErrorTokens(main)
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, a)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(a)
+                                parseArguments(a)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              looksLikeFunctionBody())
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(b, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(b)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(b, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(c, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(c)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(c, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(d, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(d)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(d, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(e, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(e)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(e, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseLiteralInt(,)
+                                              listener: handleLiteralInt(1)
+                                        listener: beginBinaryExpression(>>)
+                                        parsePrecedenceExpression(>>, 13, true)
+                                          parseUnaryExpression(>>, true)
+                                            parsePrimary(>>, expression)
+                                              parseParenthesizedExpressionOrFunctionLiteral(>>)
+                                                parseParenthesizedExpression(>>)
+                                                  parseExpressionInParenthesis(>>)
+                                                    parseExpressionInParenthesisRest(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseLiteralInt(()
+                                                                listener: handleLiteralInt(2)
+                                                      ensureCloseParen(2, ()
+                                                  listener: handleParenthesizedExpression(()
+                                        listener: endBinaryExpression(>>)
+                                    listener: endArguments(3, (, ))
+                              listener: handleSend(a, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(main)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.parser.expect
new file mode 100644
index 0000000..f090739
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.parser.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, 1 >> (2));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] 1[StringToken] >>[SimpleToken] ([BeginToken]2[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.scanner.expect
new file mode 100644
index 0000000..f090739
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, 1 >> (2));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] 1[StringToken] >>[SimpleToken] ([BeginToken]2[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart b/pkg/front_end/parser_testcases/general/issue_47008_02.dart
new file mode 100644
index 0000000..33c62b6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart
@@ -0,0 +1,3 @@
+main() {
+  a(b < c, d < e, f < g, 1 >>> (2));
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.expect b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.expect
new file mode 100644
index 0000000..f0770d5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.expect
@@ -0,0 +1,57 @@
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(b, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(b, <)
+          beginBinaryExpression(<)
+            handleIdentifier(c, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(c, ,)
+          endBinaryExpression(<)
+          handleIdentifier(d, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(d, <)
+          beginBinaryExpression(<)
+            handleIdentifier(e, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(e, ,)
+          endBinaryExpression(<)
+          handleIdentifier(f, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(f, <)
+          beginBinaryExpression(<)
+            handleIdentifier(g, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(g, ,)
+          endBinaryExpression(<)
+          handleLiteralInt(1)
+          beginBinaryExpression(>>>)
+            handleLiteralInt(2)
+            handleParenthesizedExpression(()
+          endBinaryExpression(>>>)
+        endArguments(4, (, ))
+        handleSend(a, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect
new file mode 100644
index 0000000..4f3fe74
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect
@@ -0,0 +1,164 @@
+parseUnit(main)
+  skipErrorTokens(main)
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, a)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(a)
+                                parseArguments(a)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              looksLikeFunctionBody())
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(b, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(b)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(b, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(c, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(c)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(c, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(d, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(d)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(d, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(e, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(e)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(e, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(f, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(f)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(f, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(g, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(g)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(g, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseLiteralInt(,)
+                                              listener: handleLiteralInt(1)
+                                        listener: beginBinaryExpression(>>>)
+                                        parsePrecedenceExpression(>>>, 13, true)
+                                          parseUnaryExpression(>>>, true)
+                                            parsePrimary(>>>, expression)
+                                              parseParenthesizedExpressionOrFunctionLiteral(>>>)
+                                                parseParenthesizedExpression(>>>)
+                                                  parseExpressionInParenthesis(>>>)
+                                                    parseExpressionInParenthesisRest(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseLiteralInt(()
+                                                                listener: handleLiteralInt(2)
+                                                      ensureCloseParen(2, ()
+                                                  listener: handleParenthesizedExpression(()
+                                        listener: endBinaryExpression(>>>)
+                                    listener: endArguments(4, (, ))
+                              listener: handleSend(a, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(main)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.parser.expect
new file mode 100644
index 0000000..0e53edf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.parser.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, f < g, 1 >>> (2));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] f[StringToken] <[BeginToken] g[StringToken],[SimpleToken] 1[StringToken] >>>[SimpleToken] ([BeginToken]2[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.scanner.expect
new file mode 100644
index 0000000..0e53edf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, f < g, 1 >>> (2));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] f[StringToken] <[BeginToken] g[StringToken],[SimpleToken] 1[StringToken] >>>[SimpleToken] ([BeginToken]2[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart b/pkg/front_end/parser_testcases/general/issue_47009_01.dart
new file mode 100644
index 0000000..87237b9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart
@@ -0,0 +1,3 @@
+main() {
+  a(b < c, as > (1));
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.expect b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.expect
new file mode 100644
index 0000000..5e09e8f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.expect
@@ -0,0 +1,40 @@
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(b, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(b, <)
+          beginBinaryExpression(<)
+            handleIdentifier(c, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(c, ,)
+          endBinaryExpression(<)
+          handleIdentifier(as, expression)
+          handleNoTypeArguments(>)
+          handleNoArguments(>)
+          handleSend(as, >)
+          beginBinaryExpression(>)
+            handleLiteralInt(1)
+            handleParenthesizedExpression(()
+          endBinaryExpression(>)
+        endArguments(2, (, ))
+        handleSend(a, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect
new file mode 100644
index 0000000..1876a12
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect
@@ -0,0 +1,119 @@
+parseUnit(main)
+  skipErrorTokens(main)
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, a)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(a)
+                                parseArguments(a)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              looksLikeFunctionBody())
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(b, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(b)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(b, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(c, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(c)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(c, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            inPlainSync()
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  inPlainSync()
+                                                  listener: handleIdentifier(as, expression)
+                                                listener: handleNoTypeArguments(>)
+                                                parseArgumentsOpt(as)
+                                                  listener: handleNoArguments(>)
+                                                listener: handleSend(as, >)
+                                        listener: beginBinaryExpression(>)
+                                        parsePrecedenceExpression(>, 9, true)
+                                          parseUnaryExpression(>, true)
+                                            parsePrimary(>, expression)
+                                              parseParenthesizedExpressionOrFunctionLiteral(>)
+                                                parseParenthesizedExpression(>)
+                                                  parseExpressionInParenthesis(>)
+                                                    parseExpressionInParenthesisRest(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseLiteralInt(()
+                                                                listener: handleLiteralInt(1)
+                                                      ensureCloseParen(1, ()
+                                                  listener: handleParenthesizedExpression(()
+                                        listener: endBinaryExpression(>)
+                                    listener: endArguments(2, (, ))
+                              listener: handleSend(a, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(main)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.parser.expect
new file mode 100644
index 0000000..712e62b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.parser.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, as > (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] as[KeywordToken] >[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.scanner.expect
new file mode 100644
index 0000000..712e62b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, as > (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] as[KeywordToken] >[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart b/pkg/front_end/parser_testcases/general/issue_47009_02.dart
new file mode 100644
index 0000000..3d20a33
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart
@@ -0,0 +1,3 @@
+main() {
+  a(b < c, d < e, as >> (1));
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.expect b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.expect
new file mode 100644
index 0000000..a4e0369
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.expect
@@ -0,0 +1,50 @@
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(b, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(b, <)
+          beginBinaryExpression(<)
+            handleIdentifier(c, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(c, ,)
+          endBinaryExpression(<)
+          handleIdentifier(d, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(d, <)
+          beginBinaryExpression(<)
+            handleIdentifier(e, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(e, ,)
+          endBinaryExpression(<)
+          handleIdentifier(as, expression)
+          handleNoTypeArguments(>>)
+          handleNoArguments(>>)
+          handleSend(as, >>)
+          beginBinaryExpression(>>)
+            handleLiteralInt(1)
+            handleParenthesizedExpression(()
+          endBinaryExpression(>>)
+        endArguments(3, (, ))
+        handleSend(a, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect
new file mode 100644
index 0000000..91cb220
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect
@@ -0,0 +1,146 @@
+parseUnit(main)
+  skipErrorTokens(main)
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, a)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(a)
+                                parseArguments(a)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              looksLikeFunctionBody())
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(b, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(b)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(b, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(c, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(c)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(c, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(d, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(d)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(d, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(e, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(e)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(e, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            inPlainSync()
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  inPlainSync()
+                                                  listener: handleIdentifier(as, expression)
+                                                listener: handleNoTypeArguments(>>)
+                                                parseArgumentsOpt(as)
+                                                  listener: handleNoArguments(>>)
+                                                listener: handleSend(as, >>)
+                                        listener: beginBinaryExpression(>>)
+                                        parsePrecedenceExpression(>>, 13, true)
+                                          parseUnaryExpression(>>, true)
+                                            parsePrimary(>>, expression)
+                                              parseParenthesizedExpressionOrFunctionLiteral(>>)
+                                                parseParenthesizedExpression(>>)
+                                                  parseExpressionInParenthesis(>>)
+                                                    parseExpressionInParenthesisRest(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseLiteralInt(()
+                                                                listener: handleLiteralInt(1)
+                                                      ensureCloseParen(1, ()
+                                                  listener: handleParenthesizedExpression(()
+                                        listener: endBinaryExpression(>>)
+                                    listener: endArguments(3, (, ))
+                              listener: handleSend(a, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(main)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.parser.expect
new file mode 100644
index 0000000..1e4544c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.parser.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, as >> (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] as[KeywordToken] >>[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.scanner.expect
new file mode 100644
index 0000000..1e4544c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, as >> (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] as[KeywordToken] >>[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart b/pkg/front_end/parser_testcases/general/issue_47009_03.dart
new file mode 100644
index 0000000..8479533
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart
@@ -0,0 +1,3 @@
+main() {
+  a(b < c, d < e, f < g, as >>> (1));
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.expect b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.expect
new file mode 100644
index 0000000..1170055
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.expect
@@ -0,0 +1,60 @@
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(b, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(b, <)
+          beginBinaryExpression(<)
+            handleIdentifier(c, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(c, ,)
+          endBinaryExpression(<)
+          handleIdentifier(d, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(d, <)
+          beginBinaryExpression(<)
+            handleIdentifier(e, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(e, ,)
+          endBinaryExpression(<)
+          handleIdentifier(f, expression)
+          handleNoTypeArguments(<)
+          handleNoArguments(<)
+          handleSend(f, <)
+          beginBinaryExpression(<)
+            handleIdentifier(g, expression)
+            handleNoTypeArguments(,)
+            handleNoArguments(,)
+            handleSend(g, ,)
+          endBinaryExpression(<)
+          handleIdentifier(as, expression)
+          handleNoTypeArguments(>>>)
+          handleNoArguments(>>>)
+          handleSend(as, >>>)
+          beginBinaryExpression(>>>)
+            handleLiteralInt(1)
+            handleParenthesizedExpression(()
+          endBinaryExpression(>>>)
+        endArguments(4, (, ))
+        handleSend(a, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect
new file mode 100644
index 0000000..d685108
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect
@@ -0,0 +1,173 @@
+parseUnit(main)
+  skipErrorTokens(main)
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, a)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend({, expression)
+                              isNextIdentifier({)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(a)
+                                parseArguments(a)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              looksLikeFunctionBody())
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(b, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(b)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(b, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(c, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(c)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(c, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(d, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(d)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(d, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(e, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(e)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(e, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  listener: handleIdentifier(f, expression)
+                                                listener: handleNoTypeArguments(<)
+                                                parseArgumentsOpt(f)
+                                                  listener: handleNoArguments(<)
+                                                listener: handleSend(f, <)
+                                        listener: beginBinaryExpression(<)
+                                        parsePrecedenceExpression(<, 9, true)
+                                          parseUnaryExpression(<, true)
+                                            parsePrimary(<, expression)
+                                              parseSendOrFunctionLiteral(<, expression)
+                                                parseSend(<, expression)
+                                                  isNextIdentifier(<)
+                                                  ensureIdentifier(<, expression)
+                                                    listener: handleIdentifier(g, expression)
+                                                  listener: handleNoTypeArguments(,)
+                                                  parseArgumentsOpt(g)
+                                                    listener: handleNoArguments(,)
+                                                  listener: handleSend(g, ,)
+                                        listener: endBinaryExpression(<)
+                                    parseExpression(,)
+                                      parsePrecedenceExpression(,, 1, true)
+                                        parseUnaryExpression(,, true)
+                                          parsePrimary(,, expression)
+                                            inPlainSync()
+                                            parseSendOrFunctionLiteral(,, expression)
+                                              parseSend(,, expression)
+                                                isNextIdentifier(,)
+                                                ensureIdentifier(,, expression)
+                                                  inPlainSync()
+                                                  listener: handleIdentifier(as, expression)
+                                                listener: handleNoTypeArguments(>>>)
+                                                parseArgumentsOpt(as)
+                                                  listener: handleNoArguments(>>>)
+                                                listener: handleSend(as, >>>)
+                                        listener: beginBinaryExpression(>>>)
+                                        parsePrecedenceExpression(>>>, 13, true)
+                                          parseUnaryExpression(>>>, true)
+                                            parsePrimary(>>>, expression)
+                                              parseParenthesizedExpressionOrFunctionLiteral(>>>)
+                                                parseParenthesizedExpression(>>>)
+                                                  parseExpressionInParenthesis(>>>)
+                                                    parseExpressionInParenthesisRest(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseLiteralInt(()
+                                                                listener: handleLiteralInt(1)
+                                                      ensureCloseParen(1, ()
+                                                  listener: handleParenthesizedExpression(()
+                                        listener: endBinaryExpression(>>>)
+                                    listener: endArguments(4, (, ))
+                              listener: handleSend(a, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(main)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.parser.expect
new file mode 100644
index 0000000..1fbc7ff
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.parser.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, f < g, as >>> (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] f[StringToken] <[BeginToken] g[StringToken],[SimpleToken] as[KeywordToken] >>>[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.scanner.expect
new file mode 100644
index 0000000..1fbc7ff
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+a(b < c, d < e, f < g, as >>> (1));
+}
+
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+a[StringToken]([BeginToken]b[StringToken] <[BeginToken] c[StringToken],[SimpleToken] d[StringToken] <[BeginToken] e[StringToken],[SimpleToken] f[StringToken] <[BeginToken] g[StringToken],[SimpleToken] as[KeywordToken] >>>[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart b/pkg/front_end/testcases/extensions/multi_export.dart
new file mode 100644
index 0000000..ac46d9e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'multi_export_lib1.dart' as lib;
+import 'multi_export_lib2.dart' as lib;
+import 'multi_export_lib3.dart' as lib;
+import 'multi_export_lib4.dart' as lib;
+
+main() {
+  lib.SubClass1()..method();
+  lib.SubClass2()..method();
+  lib.SubClass3()..method();
+  lib.SubClass4()..method();
+}
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline.expect
new file mode 100644
index 0000000..fe7f24f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'multi_export_lib1.dart' as lib;
+import 'multi_export_lib2.dart' as lib;
+import 'multi_export_lib3.dart' as lib;
+import 'multi_export_lib4.dart' as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe7f24f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'multi_export_lib1.dart' as lib;
+import 'multi_export_lib2.dart' as lib;
+import 'multi_export_lib3.dart' as lib;
+import 'multi_export_lib4.dart' as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart.weak.expect b/pkg/front_end/testcases/extensions/multi_export.dart.weak.expect
new file mode 100644
index 0000000..b369c9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart.weak.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "multi_export_lib1.dart" as mul;
+import "multi_export_lib.dart" as mul2;
+import "multi_export_lib2.dart" as mul3;
+import "multi_export_lib3.dart" as mul4;
+import "multi_export_lib4.dart" as mul5;
+
+import "org-dartlang-testcase:///multi_export_lib1.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib2.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib3.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib4.dart" as lib;
+
+static method main() → dynamic {
+  let final mul::SubClass1 #t1 = new mul::SubClass1::•() in block {
+    mul2::Extension|method<mul::SubClass1>(#t1);
+  } =>#t1;
+  let final mul3::SubClass2 #t2 = new mul3::SubClass2::•() in block {
+    mul2::Extension|method<mul3::SubClass2>(#t2);
+  } =>#t2;
+  let final mul4::SubClass3 #t3 = new mul4::SubClass3::•() in block {
+    mul2::Extension|method<mul4::SubClass3>(#t3);
+  } =>#t3;
+  let final mul5::SubClass4 #t4 = new mul5::SubClass4::•() in block {
+    mul2::Extension|method<mul5::SubClass4>(#t4);
+  } =>#t4;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul;
+import "multi_export_lib.dart" as mul2;
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+
+class SubClass1 extends mul2::Class {
+  synthetic constructor •() → mul::SubClass1
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul3;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass2 extends mul2::Class {
+  synthetic constructor •() → mul3::SubClass2
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul4;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass3 extends mul2::Class {
+  synthetic constructor •() → mul4::SubClass3
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul5;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass4 extends mul2::Class {
+  synthetic constructor •() → mul5::SubClass4
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → mul2::Class
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends mul2::Class> on T {
+  method method = mul2::Extension|method;
+  tearoff method = mul2::Extension|get#method;
+}
+static method Extension|method<T extends mul2::Class>(lowered final mul2::Extension|method::T #this) → dynamic {}
+static method Extension|get#method<T extends mul2::Class>(lowered final mul2::Extension|get#method::T #this) → () → dynamic
+  return () → dynamic => mul2::Extension|method<mul2::Extension|get#method::T>(#this);
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/multi_export.dart.weak.outline.expect
new file mode 100644
index 0000000..73fb1e0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart.weak.outline.expect
@@ -0,0 +1,77 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///multi_export_lib1.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib2.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib3.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib4.dart" as lib;
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "multi_export_lib.dart" as mul;
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+
+class SubClass1 extends mul::Class {
+  synthetic constructor •() → self2::SubClass1
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self3;
+import "multi_export_lib.dart" as mul;
+additionalExports = (mul::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass2 extends mul::Class {
+  synthetic constructor •() → self3::SubClass2
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self4;
+import "multi_export_lib.dart" as mul;
+additionalExports = (mul::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass3 extends mul::Class {
+  synthetic constructor •() → self4::SubClass3
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self5;
+import "multi_export_lib.dart" as mul;
+additionalExports = (mul::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass4 extends mul::Class {
+  synthetic constructor •() → self5::SubClass4
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → mul::Class
+    ;
+}
+extension Extension<T extends mul::Class> on T {
+  method method = mul::Extension|method;
+  tearoff method = mul::Extension|get#method;
+}
+static method Extension|method<T extends mul::Class>(lowered final mul::Extension|method::T #this) → dynamic
+  ;
+static method Extension|get#method<T extends mul::Class>(lowered final mul::Extension|get#method::T #this) → () → dynamic
+  return () → dynamic => mul::Extension|method<mul::Extension|get#method::T>(#this);
diff --git a/pkg/front_end/testcases/extensions/multi_export.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/multi_export.dart.weak.transformed.expect
new file mode 100644
index 0000000..b369c9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export.dart.weak.transformed.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "multi_export_lib1.dart" as mul;
+import "multi_export_lib.dart" as mul2;
+import "multi_export_lib2.dart" as mul3;
+import "multi_export_lib3.dart" as mul4;
+import "multi_export_lib4.dart" as mul5;
+
+import "org-dartlang-testcase:///multi_export_lib1.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib2.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib3.dart" as lib;
+import "org-dartlang-testcase:///multi_export_lib4.dart" as lib;
+
+static method main() → dynamic {
+  let final mul::SubClass1 #t1 = new mul::SubClass1::•() in block {
+    mul2::Extension|method<mul::SubClass1>(#t1);
+  } =>#t1;
+  let final mul3::SubClass2 #t2 = new mul3::SubClass2::•() in block {
+    mul2::Extension|method<mul3::SubClass2>(#t2);
+  } =>#t2;
+  let final mul4::SubClass3 #t3 = new mul4::SubClass3::•() in block {
+    mul2::Extension|method<mul4::SubClass3>(#t3);
+  } =>#t3;
+  let final mul5::SubClass4 #t4 = new mul5::SubClass4::•() in block {
+    mul2::Extension|method<mul5::SubClass4>(#t4);
+  } =>#t4;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul;
+import "multi_export_lib.dart" as mul2;
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+
+class SubClass1 extends mul2::Class {
+  synthetic constructor •() → mul::SubClass1
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul3;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass2 extends mul2::Class {
+  synthetic constructor •() → mul3::SubClass2
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul4;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass3 extends mul2::Class {
+  synthetic constructor •() → mul4::SubClass3
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul5;
+import "multi_export_lib.dart" as mul2;
+additionalExports = (mul2::Extension)
+
+import "org-dartlang-testcase:///multi_export_lib.dart";
+export "org-dartlang-testcase:///multi_export_lib.dart" show Extension;
+
+class SubClass4 extends mul2::Class {
+  synthetic constructor •() → mul5::SubClass4
+    : super mul2::Class::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as mul2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → mul2::Class
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends mul2::Class> on T {
+  method method = mul2::Extension|method;
+  tearoff method = mul2::Extension|get#method;
+}
+static method Extension|method<T extends mul2::Class>(lowered final mul2::Extension|method::T #this) → dynamic {}
+static method Extension|get#method<T extends mul2::Class>(lowered final mul2::Extension|get#method::T #this) → () → dynamic
+  return () → dynamic => mul2::Extension|method<mul2::Extension|get#method::T>(#this);
diff --git a/pkg/front_end/testcases/extensions/multi_export_lib.dart b/pkg/front_end/testcases/extensions/multi_export_lib.dart
new file mode 100644
index 0000000..3c35b93
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {}
+
+extension Extension<T extends Class> on T {
+  method() {}
+}
diff --git a/pkg/front_end/testcases/extensions/multi_export_lib1.dart b/pkg/front_end/testcases/extensions/multi_export_lib1.dart
new file mode 100644
index 0000000..a9afcf3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export_lib1.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'multi_export_lib.dart';
+//export 'multi_export_lib.dart' show Extension;
+
+class SubClass1 extends Class {}
diff --git a/pkg/front_end/testcases/extensions/multi_export_lib2.dart b/pkg/front_end/testcases/extensions/multi_export_lib2.dart
new file mode 100644
index 0000000..16f208a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export_lib2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'multi_export_lib.dart';
+export 'multi_export_lib.dart' show Extension;
+
+class SubClass2 extends Class {}
diff --git a/pkg/front_end/testcases/extensions/multi_export_lib3.dart b/pkg/front_end/testcases/extensions/multi_export_lib3.dart
new file mode 100644
index 0000000..fd2c3a9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export_lib3.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'multi_export_lib.dart';
+export 'multi_export_lib.dart' show Extension;
+
+class SubClass3 extends Class {}
diff --git a/pkg/front_end/testcases/extensions/multi_export_lib4.dart b/pkg/front_end/testcases/extensions/multi_export_lib4.dart
new file mode 100644
index 0000000..6267625
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/multi_export_lib4.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'multi_export_lib.dart';
+export 'multi_export_lib.dart' show Extension;
+
+class SubClass4 extends Class {}
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart b/pkg/front_end/testcases/extensions/nested_on_types.dart
index e1fc07d..da3d2d7 100644
--- a/pkg/front_end/testcases/extensions/nested_on_types.dart
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // @dart=2.9
+
 class A<T> {}
 
 extension Extension<T> on A<A<T>> {
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart b/pkg/front_end/testcases/general/issue_47008_01.dart
new file mode 100644
index 0000000..7980b2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart
@@ -0,0 +1,11 @@
+main() {
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+  a(b < c, d < e, 1 >> (2));
+}
+
+void a(bool x, bool y, int z) {
+  print("$x $y $z");
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline.expect
new file mode 100644
index 0000000..c8a6141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, int z) {}
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c8a6141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, int z) {}
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart.weak.expect b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.expect
new file mode 100644
index 0000000..383dfab
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, 1.{core::int::>>}(2){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::int z) → void {
+  core::print("${x} ${y} ${z}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.outline.expect
new file mode 100644
index 0000000..35353cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method a(core::bool x, core::bool y, core::int z) → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue_47008_01.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.transformed.expect
new file mode 100644
index 0000000..54bfd70
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_01.dart.weak.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, 1.{core::int::>>}(2){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::int z) → void {
+  core::print("${x} ${y} ${z}");
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///issue_47008_01.dart:6:21 -> IntConstant(0)
+Extra constant evaluation: evaluated: 13, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart b/pkg/front_end/testcases/general/issue_47008_02.dart
new file mode 100644
index 0000000..996590a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart
@@ -0,0 +1,13 @@
+main() {
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+  int f = 5;
+  int g = 6;
+  a(b < c, d < e, f < g, 1 >>> (2));
+}
+
+void a(bool x, bool y, bool z1, int z2) {
+  print("$x $y $z1 $z2");
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline.expect
new file mode 100644
index 0000000..3f2b123
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, bool z1, int z2) {}
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3f2b123
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, bool z1, int z2) {}
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart.weak.expect b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.expect
new file mode 100644
index 0000000..d448313
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int f = 5;
+  core::int g = 6;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, f.{core::num::<}(g){(core::num) → core::bool}, 1.{core::int::>>>}(2){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void {
+  core::print("${x} ${y} ${z1} ${z2}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.outline.expect
new file mode 100644
index 0000000..b349da9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue_47008_02.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.transformed.expect
new file mode 100644
index 0000000..bc7f96a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47008_02.dart.weak.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int f = 5;
+  core::int g = 6;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, f.{core::num::<}(g){(core::num) → core::bool}, 1.{core::int::>>>}(2){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void {
+  core::print("${x} ${y} ${z1} ${z2}");
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///issue_47008_02.dart:8:28 -> IntConstant(0)
+Extra constant evaluation: evaluated: 17, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart b/pkg/front_end/testcases/general/issue_47009_01.dart
new file mode 100644
index 0000000..127b5fb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart
@@ -0,0 +1,10 @@
+main() {
+  int b = 1;
+  int c = 2;
+  int as = 3;
+  a(b < c, as > (1));
+}
+
+void a(bool x, bool y) {
+  print("$x $y");
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline.expect
new file mode 100644
index 0000000..8c1c1ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c1c1ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart.weak.expect b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.expect
new file mode 100644
index 0000000..a9de674
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int as = 3;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, as.{core::num::>}(1){(core::num) → core::bool});
+}
+static method a(core::bool x, core::bool y) → void {
+  core::print("${x} ${y}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.outline.expect
new file mode 100644
index 0000000..1e4d67b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method a(core::bool x, core::bool y) → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue_47009_01.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.transformed.expect
new file mode 100644
index 0000000..a9de674
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_01.dart.weak.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int as = 3;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, as.{core::num::>}(1){(core::num) → core::bool});
+}
+static method a(core::bool x, core::bool y) → void {
+  core::print("${x} ${y}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart b/pkg/front_end/testcases/general/issue_47009_02.dart
new file mode 100644
index 0000000..fc8dd12
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart
@@ -0,0 +1,12 @@
+main() {
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+  int as = 5;
+  a(b < c, d < e, as >> (1));
+}
+
+void a(bool x, bool y, int z) {
+  print("$x $y $z");
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline.expect
new file mode 100644
index 0000000..c8a6141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, int z) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c8a6141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, int z) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart.weak.expect b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.expect
new file mode 100644
index 0000000..c5218bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int as = 5;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, as.{core::int::>>}(1){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::int z) → void {
+  core::print("${x} ${y} ${z}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.outline.expect
new file mode 100644
index 0000000..35353cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method a(core::bool x, core::bool y, core::int z) → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue_47009_02.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.transformed.expect
new file mode 100644
index 0000000..c5218bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_02.dart.weak.transformed.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int as = 5;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, as.{core::int::>>}(1){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::int z) → void {
+  core::print("${x} ${y} ${z}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart b/pkg/front_end/testcases/general/issue_47009_03.dart
new file mode 100644
index 0000000..50afad9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart
@@ -0,0 +1,14 @@
+main() {
+  int b = 1;
+  int c = 2;
+  int d = 3;
+  int e = 4;
+  int f = 5;
+  int g = 6;
+  int as = 7;
+  a(b < c, d < e, f < g, as >>> (1));
+}
+
+void a(bool x, bool y, bool z1, int z2) {
+  print("$x $y $z1 $z2");
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline.expect
new file mode 100644
index 0000000..3f2b123
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, bool z1, int z2) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3f2b123
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void a(bool x, bool y, bool z1, int z2) {}
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart.weak.expect b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.expect
new file mode 100644
index 0000000..1d366c4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.expect
@@ -0,0 +1,17 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int f = 5;
+  core::int g = 6;
+  core::int as = 7;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, f.{core::num::<}(g){(core::num) → core::bool}, as.{core::int::>>>}(1){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void {
+  core::print("${x} ${y} ${z1} ${z2}");
+}
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.outline.expect
new file mode 100644
index 0000000..b349da9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue_47009_03.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.transformed.expect
new file mode 100644
index 0000000..1d366c4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue_47009_03.dart.weak.transformed.expect
@@ -0,0 +1,17 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int b = 1;
+  core::int c = 2;
+  core::int d = 3;
+  core::int e = 4;
+  core::int f = 5;
+  core::int g = 6;
+  core::int as = 7;
+  self::a(b.{core::num::<}(c){(core::num) → core::bool}, d.{core::num::<}(e){(core::num) → core::bool}, f.{core::num::<}(g){(core::num) → core::bool}, as.{core::int::>>>}(1){(core::int) → core::int});
+}
+static method a(core::bool x, core::bool y, core::bool z1, core::int z2) → void {
+  core::print("${x} ${y} ${z1} ${z2}");
+}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 9093936..3cd7ca1 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -69,7 +69,6 @@
 general/error_recovery/issue_39958_04: RuntimeError
 general/error_recovery/yield_not_in_generator: RuntimeError
 general/expressions: RuntimeError
-general/external_import: RuntimeError
 general/getter_vs_setter_type: TypeCheckError
 general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index bf0cb40..06ba968 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -368,8 +368,8 @@
   UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
-  UInt flags (isFinal, isConst, isStatic, isCovariant,
-                isGenericCovariantImpl, isLate, isExtensionMember,
+  UInt flags (isFinal, isConst, isStatic, isCovariantByDeclaration,
+                isCovariantByClass, isLate, isExtensionMember,
                 isNonNullableByDefault, isInternalImplementation);
   Name name;
   List<Expression> annotations;
@@ -1377,8 +1377,8 @@
 
   List<Expression> annotations;
 
-  Byte flags (isFinal, isConst, isFieldFormal, isCovariant,
-              isGenericCovariantImpl, isLate, isRequired, isLowered);
+  Byte flags (isFinal, isConst, isFieldFormal, isCovariantByDeclaration,
+              isCovariantByClass, isLate, isRequired, isLowered);
   // For named parameters, this is the parameter name.
   // For other variables, the name is cosmetic, may be empty,
   // and is not necessarily unique.
@@ -1501,7 +1501,7 @@
 
 type TypeParameter {
   // Note: there is no tag on TypeParameter
-  Byte flags (isGenericCovariantImpl);
+  Byte flags (isCovariantByClass);
   List<Expression> annotations;
   Byte variance; // Index into the Variance enum above
   StringReference name; // Cosmetic, may be empty, not unique.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a95b5d3..9a4165c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1865,7 +1865,7 @@
   Field.mutable(Name name,
       {this.type: const DynamicType(),
       this.initializer,
-      bool isCovariant: false,
+      bool isCovariantByDeclaration: false,
       bool isFinal: false,
       bool isStatic: false,
       bool isLate: false,
@@ -1879,7 +1879,7 @@
     // ignore: unnecessary_null_comparison
     assert(type != null);
     initializer?.parent = this;
-    this.isCovariant = isCovariant;
+    this.isCovariantByDeclaration = isCovariantByDeclaration;
     this.isFinal = isFinal;
     this.isStatic = isStatic;
     this.isLate = isLate;
@@ -1889,7 +1889,7 @@
   Field.immutable(Name name,
       {this.type: const DynamicType(),
       this.initializer,
-      bool isCovariant: false,
+      bool isCovariantByDeclaration: false,
       bool isFinal: false,
       bool isConst: false,
       bool isStatic: false,
@@ -1902,7 +1902,7 @@
     // ignore: unnecessary_null_comparison
     assert(type != null);
     initializer?.parent = this;
-    this.isCovariant = isCovariant;
+    this.isCovariantByDeclaration = isCovariantByDeclaration;
     this.isFinal = isFinal;
     this.isConst = isConst;
     this.isStatic = isStatic;
@@ -1922,14 +1922,14 @@
   static const int FlagConst = 1 << 1;
   static const int FlagStatic = 1 << 2;
   static const int FlagCovariant = 1 << 3;
-  static const int FlagGenericCovariantImpl = 1 << 4;
+  static const int FlagCovariantByClass = 1 << 4;
   static const int FlagLate = 1 << 5;
   static const int FlagExtensionMember = 1 << 6;
   static const int FlagNonNullableByDefault = 1 << 7;
   static const int FlagInternalImplementation = 1 << 8;
 
   /// Whether the field is declared with the `covariant` keyword.
-  bool get isCovariant => flags & FlagCovariant != 0;
+  bool get isCovariantByDeclaration => flags & FlagCovariant != 0;
 
   bool get isFinal => flags & FlagFinal != 0;
 
@@ -1946,7 +1946,7 @@
   ///
   /// When `true`, runtime checks may need to be performed; see
   /// [DispatchCategory] for details.
-  bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
+  bool get isCovariantByClass => flags & FlagCovariantByClass != 0;
 
   /// Whether the field is declared with the `late` keyword.
   bool get isLate => flags & FlagLate != 0;
@@ -1958,7 +1958,7 @@
   // lowering.
   bool get isInternalImplementation => flags & FlagInternalImplementation != 0;
 
-  void set isCovariant(bool value) {
+  void set isCovariantByDeclaration(bool value) {
     flags = value ? (flags | FlagCovariant) : (flags & ~FlagCovariant);
   }
 
@@ -1979,10 +1979,10 @@
         value ? (flags | FlagExtensionMember) : (flags & ~FlagExtensionMember);
   }
 
-  void set isGenericCovariantImpl(bool value) {
+  void set isCovariantByClass(bool value) {
     flags = value
-        ? (flags | FlagGenericCovariantImpl)
-        : (flags & ~FlagGenericCovariantImpl);
+        ? (flags | FlagCovariantByClass)
+        : (flags & ~FlagCovariantByClass);
   }
 
   void set isLate(bool value) {
@@ -2396,8 +2396,8 @@
   /// The stub target is `null`.
   Regular,
 
-  /// An abstract procedure inserted to add `isCovariant` and
-  /// `isGenericCovariantImpl` to parameters for a set of overridden members.
+  /// An abstract procedure inserted to add `isCovariantByDeclaration` and
+  /// `isCovariantByClass` to parameters for a set of overridden members.
   ///
   /// The stub is inserted when not all of the overridden members agree on
   /// the covariance flags. For instance:
@@ -2422,8 +2422,8 @@
   /// The stub target is one of the overridden members.
   AbstractForwardingStub,
 
-  /// A concrete procedure inserted to add `isCovariant` and
-  /// `isGenericCovariantImpl` checks to parameters before calling the
+  /// A concrete procedure inserted to add `isCovariantByDeclaration` and
+  /// `isCovariantByClass` checks to parameters before calling the
   /// overridden member in the superclass.
   ///
   /// The stub is inserted when not all of the overridden members agree on
@@ -9927,7 +9927,7 @@
       bool isFinal: false,
       bool isConst: false,
       bool isFieldFormal: false,
-      bool isCovariant: false,
+      bool isCovariantByDeclaration: false,
       bool isLate: false,
       bool isRequired: false,
       bool isLowered: false}) {
@@ -9940,7 +9940,7 @@
       this.isFinal = isFinal;
       this.isConst = isConst;
       this.isFieldFormal = isFieldFormal;
-      this.isCovariant = isCovariant;
+      this.isCovariantByDeclaration = isCovariantByDeclaration;
       this.isLate = isLate;
       this.isRequired = isRequired;
       this.isLowered = isLowered;
@@ -9981,7 +9981,7 @@
 
   /// Whether the parameter is declared with the `covariant` keyword.
   // TODO(johnniwinther): Rename to isCovariantByDeclaration
-  bool get isCovariant => flags & FlagCovariant != 0;
+  bool get isCovariantByDeclaration => flags & FlagCovariant != 0;
 
   /// Whether the variable is declared as a field formal parameter of
   /// a constructor.
@@ -9995,7 +9995,7 @@
   /// When `true`, runtime checks may need to be performed; see
   /// [DispatchCategory] for details.
   // TODO(johnniwinther): Rename to isCovariantByClass
-  bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
+  bool get isCovariantByClass => flags & FlagGenericCovariantImpl != 0;
 
   /// Whether the variable is declared with the `late` keyword.
   ///
@@ -10040,7 +10040,7 @@
     flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
   }
 
-  void set isCovariant(bool value) {
+  void set isCovariantByDeclaration(bool value) {
     flags = value ? (flags | FlagCovariant) : (flags & ~FlagCovariant);
   }
 
@@ -10049,7 +10049,7 @@
     flags = value ? (flags | FlagFieldFormal) : (flags & ~FlagFieldFormal);
   }
 
-  void set isGenericCovariantImpl(bool value) {
+  void set isCovariantByClass(bool value) {
     flags = value
         ? (flags | FlagGenericCovariantImpl)
         : (flags & ~FlagGenericCovariantImpl);
@@ -12032,7 +12032,7 @@
         defaultType = defaultType ?? unsetDefaultTypeSentinel;
 
   // Must match serialized bit positions.
-  static const int FlagGenericCovariantImpl = 1 << 0;
+  static const int FlagCovariantByClass = 1 << 0;
 
   /// If this [TypeParameter] is a type parameter of a generic method, indicates
   /// whether the method implementation needs to contain a runtime type check to
@@ -12040,12 +12040,12 @@
   ///
   /// When `true`, runtime checks may need to be performed; see
   /// [DispatchCategory] for details.
-  bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
+  bool get isCovariantByClass => flags & FlagCovariantByClass != 0;
 
-  void set isGenericCovariantImpl(bool value) {
+  void set isCovariantByClass(bool value) {
     flags = value
-        ? (flags | FlagGenericCovariantImpl)
-        : (flags & ~FlagGenericCovariantImpl);
+        ? (flags | FlagCovariantByClass)
+        : (flags & ~FlagCovariantByClass);
   }
 
   @override
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index 7470718..0f86d1c 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -75,11 +75,13 @@
       if (isSetter) {
         final DartType ownType = setterType(host, ownMember);
         final DartType superType = setterType(host, superMember);
-        final bool isCovariant = ownMember is Field
-            ? ownMember.isCovariant
-            : ownMember.function!.positionalParameters[0].isCovariant;
-        if (!_isValidParameterOverride(isCovariant, ownType, superType)) {
-          if (isCovariant) {
+        final bool isCovariantByDeclaration = ownMember is Field
+            ? ownMember.isCovariantByDeclaration
+            : ownMember
+                .function!.positionalParameters[0].isCovariantByDeclaration;
+        if (!_isValidParameterOverride(
+            isCovariantByDeclaration, ownType, superType)) {
+          if (isCovariantByDeclaration) {
             return failures.reportInvalidOverride(ownMember, superMember, '''
 ${ownType} is neither a subtype nor supertype of ${superType}
 ''');
@@ -198,7 +200,7 @@
       final VariableDeclaration superParameter =
           superFunction.positionalParameters[i];
       if (!_isValidParameterOverride(
-          ownParameter.isCovariant,
+          ownParameter.isCovariantByDeclaration,
           ownSubstitution.substituteType(ownParameter.type),
           superSubstitution.substituteType(superParameter.type))) {
         return '''
@@ -227,7 +229,7 @@
       }
 
       if (!_isValidParameterOverride(
-          ownParameter.isCovariant,
+          ownParameter.isCovariantByDeclaration,
           ownSubstitution.substituteType(ownParameter.type),
           superSubstitution.substituteType(superParameter.type))) {
         return '''
@@ -244,11 +246,11 @@
   /// Checks whether parameter with [ownParameterType] type is a valid override
   /// for parameter with [superParameterType] type taking into account its
   /// covariance and applying type parameter [substitution] if necessary.
-  bool _isValidParameterOverride(bool isCovariant, DartType ownParameterType,
-      DartType superParameterType) {
+  bool _isValidParameterOverride(bool isCovariantByDeclaration,
+      DartType ownParameterType, DartType superParameterType) {
     if (_isSubtypeOf(superParameterType, ownParameterType)) {
       return true;
-    } else if (isCovariant &&
+    } else if (isCovariantByDeclaration &&
         _isSubtypeOf(ownParameterType, superParameterType)) {
       return true;
     } else {
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 5485bdc..c7db100 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1123,8 +1123,8 @@
     writeIndentation();
     writeModifier(node.isLate, 'late');
     writeModifier(node.isStatic, 'static');
-    writeModifier(node.isCovariant, 'covariant');
-    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
+    writeModifier(node.isCovariantByDeclaration, 'covariant');
+    writeModifier(node.isCovariantByClass, 'generic-covariant-impl');
     writeModifier(node.isFinal, 'final');
     writeModifier(node.isConst, 'const');
     // Only show implicit getter/setter modifiers in cases where they are
@@ -2404,8 +2404,8 @@
     writeModifier(node.isLowered, 'lowered');
     writeModifier(node.isLate, 'late');
     writeModifier(node.isRequired, 'required');
-    writeModifier(node.isCovariant, 'covariant');
-    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
+    writeModifier(node.isCovariantByDeclaration, 'covariant');
+    writeModifier(node.isCovariantByClass, 'generic-covariant-impl');
     writeModifier(node.isFinal, 'final');
     writeModifier(node.isConst, 'const');
     // ignore: unnecessary_null_comparison
@@ -2623,7 +2623,7 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
+    writeModifier(node.isCovariantByClass, 'generic-covariant-impl');
     writeAnnotationList(node.annotations, separateLines: false);
     if (node.variance != Variance.covariant) {
       writeWord(const <String>[
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 0f6e9f5..aec6e35 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -1980,7 +1980,7 @@
   Field.FlagConst: "const",
   Field.FlagStatic: "static",
   Field.FlagCovariant: "covariant",
-  Field.FlagGenericCovariantImpl: "generic-covariant-impl",
+  Field.FlagCovariantByClass: "generic-covariant-impl",
   Field.FlagLate: "late",
   Field.FlagExtensionMember: "extension-member",
   Field.FlagNonNullableByDefault: "non-nullable-by-default",
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index 6c80c5a..d05be90 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -139,8 +139,8 @@
           setters.remove(field.name);
           VariableDeclaration parameter =
               setter.function.positionalParameters.first;
-          clone.isCovariant = parameter.isCovariant;
-          clone.isGenericCovariantImpl = parameter.isGenericCovariantImpl;
+          clone.isCovariantByDeclaration = parameter.isCovariantByDeclaration;
+          clone.isCovariantByClass = parameter.isCovariantByClass;
         }
         nonSetters.remove(field.name);
         class_.addField(clone);
@@ -225,10 +225,10 @@
         // TODO(kernel team): The named parameters are not sorted,
         // this might not be correct.
         for (int j = 0; j < src.namedParameters.length; ++j) {
-          dst.namedParameters[j].isCovariant =
-              src.namedParameters[j].isCovariant;
-          dst.namedParameters[j].isGenericCovariantImpl =
-              src.namedParameters[j].isGenericCovariantImpl;
+          dst.namedParameters[j].isCovariantByDeclaration =
+              src.namedParameters[j].isCovariantByDeclaration;
+          dst.namedParameters[j].isCovariantByClass =
+              src.namedParameters[j].isCovariantByClass;
         }
 
         class_.procedures[originalIndex] = clone;
diff --git a/pkg/vm/lib/transformations/call_site_annotator.dart b/pkg/vm/lib/transformations/call_site_annotator.dart
index 691ba84..e0267ca 100644
--- a/pkg/vm/lib/transformations/call_site_annotator.dart
+++ b/pkg/vm/lib/transformations/call_site_annotator.dart
@@ -110,7 +110,7 @@
   /// Return [true] if the given list of [VariableDeclaration] contains
   /// any annotated with generic-covariant-impl.
   static bool containsGenericCovariantImpl(List<VariableDeclaration> decls) =>
-      decls.any((p) => p.isGenericCovariantImpl);
+      decls.any((p) => p.isCovariantByClass);
 
   /// Returns [true] if the given [member] has any parameters annotated with
   /// generic-covariant-impl attribute.
@@ -120,7 +120,7 @@
               member.function.positionalParameters) ||
           containsGenericCovariantImpl(member.function.namedParameters);
     } else if (member is Field) {
-      return member.isGenericCovariantImpl;
+      return member.isCovariantByClass;
     }
 
     return false;
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 75eff47..989ad83 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -195,12 +195,12 @@
     final function = selector.member.function;
     if (function != null) {
       typeChecksNeeded =
-          function.typeParameters.any((t) => t.isGenericCovariantImpl);
+          function.typeParameters.any((t) => t.isCovariantByClass);
     } else {
       Field field = selector.member as Field;
       if (selector.callKind == CallKind.PropertySet) {
         // TODO(dartbug.com/40615): Use TFA results to improve this criterion.
-        typeChecksNeeded = field.isGenericCovariantImpl;
+        typeChecksNeeded = field.isCovariantByClass;
       }
     }
   }
@@ -1499,7 +1499,7 @@
     _FieldValue? fieldValue = _fieldValues[field];
     if (fieldValue == null) {
       Summary? typeGuardSummary = null;
-      if (field.isGenericCovariantImpl) {
+      if (field.isCovariantByClass) {
         typeGuardSummary = summaryCollector.createSummary(field,
             fieldSummaryType: FieldSummaryType.kFieldGuard);
       }
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
index f09fc1a..7ec6ff9 100644
--- a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -190,7 +190,7 @@
     // Covariant parameters have implicit type checks, which count as reads.
     // When run in weak mode with null assertions enabled, parameters with
     // non-nullable types have implicit null checks, which count as reads.
-    if ((param.isCovariant || param.isGenericCovariantImpl) ||
+    if ((param.isCovariantByDeclaration || param.isCovariantByClass) ||
         (!shaker.typeFlowAnalysis.target.flags.enableNullSafety &&
             param.type.nullability == Nullability.nonNullable &&
             (type == null || type is NullableType))) {
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index fb18cec..72b0b68 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -546,7 +546,7 @@
 
   TypeCheck(this.arg, this.type, this.node, this.staticType, this.kind)
       : isTestedOnlyOnCheckedEntryPoint =
-            node is VariableDeclaration && !node.isCovariant;
+            node is VariableDeclaration && !node.isCovariantByDeclaration;
 
   @override
   void accept(StatementVisitor visitor) => visitor.visitTypeCheck(this);
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 49ce917..952eefe 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -801,7 +801,7 @@
   }
 
   bool _useTypeCheckForParameter(VariableDeclaration decl) {
-    return decl.isCovariant || decl.isGenericCovariantImpl;
+    return decl.isCovariantByDeclaration || decl.isCovariantByClass;
   }
 
   Args<Type> rawArguments(Selector selector) {
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 2ed3a8e..13e7440 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -880,8 +880,8 @@
     if (isSetter) {
       final isAbstract = !shaker.isFieldSetterReachable(field);
       final parameter = new VariableDeclaration('value', type: field.type)
-        ..isCovariant = field.isCovariant
-        ..isGenericCovariantImpl = field.isGenericCovariantImpl
+        ..isCovariantByDeclaration = field.isCovariantByDeclaration
+        ..isCovariantByClass = field.isCovariantByClass
         ..fileOffset = field.fileOffset;
       accessor = new Procedure(
           field.name,
diff --git a/tools/VERSION b/tools/VERSION
index b356ec5..fd0afe8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 96
+PRERELEASE 97
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 5e3c9e2..4a68e261 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -22,7 +22,7 @@
   parser.addOption("branch",
       abbr: "B",
       help: "Select the builders building this branch",
-      defaultsTo: "master");
+      defaultsTo: "main");
   parser.addOption("count",
       abbr: "c", help: "List this many commits", defaultsTo: "1");
   parser.addFlag("help", help: "Show the program usage.", negatable: false);