Version 2.13.0-157.0.dev

Merge commit '55b21adf6b674605061a34fde38a055739e2ab1b' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart
index 6f3fa92..4ee5960 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart
@@ -15,6 +15,9 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     var declaration = node.thisOrAncestorOfType<FieldDeclaration>();
+    if (declaration == null) {
+      return;
+    }
     await builder.addDartFileEdit(file, (builder) {
       var offset = declaration.firstTokenAfterCommentAndMetadata.offset;
       builder.addSimpleInsertion(offset, 'static ');
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 3621e3b..9528af0 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -1765,10 +1765,10 @@
    * 1: the expected return type as defined by the type of the Future
    */
   static const HintCode RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR = HintCode(
-    'RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR',
-    "A value of type '{0}' can't be returned by the 'onError' handler because "
-        "it must be assignable to '{1}'.",
-  );
+      'INVALID_RETURN_TYPE_FOR_CATCH_ERROR',
+      "A value of type '{0}' can't be returned by the 'onError' handler "
+          "because it must be assignable to '{1}'.",
+      uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR');
 
   /**
    * Parameters:
@@ -1776,9 +1776,10 @@
    * 1: the expected return type as defined by the type of the Future
    */
   static const HintCode RETURN_TYPE_INVALID_FOR_CATCH_ERROR = HintCode(
-      'RETURN_TYPE_INVALID_FOR_CATCH_ERROR',
+      'INVALID_RETURN_TYPE_FOR_CATCH_ERROR',
       "The return type '{0}' isn't assignable to '{1}', as required by "
-          "'Future.catchError'.");
+          "'Future.catchError'.",
+      uniqueName: 'RETURN_TYPE_INVALID_FOR_CATCH_ERROR');
 
   /**
    * No parameters.
diff --git a/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart b/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
index 507ea06..49a8a88 100644
--- a/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
+++ b/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
@@ -209,15 +209,23 @@
 }
 
 extension on CommentToken {
+  /// The error codes currently do not contain digits or dollar signs, so we
+  /// can be a bit more restrictive in this test.
+  static final _identifierRegExp = RegExp(r'^[a-zA-Z][_a-zA-Z]*$');
+
   /// Return the diagnostic names contained in this comment, assuming that it is
   /// a correctly formatted ignore comment.
   Iterable<DiagnosticName> get diagnosticNames sync* {
+    bool isValidIdentifier(String text) {
+      return text.contains(_identifierRegExp);
+    }
+
     int offset = lexeme.indexOf(':') + 1;
     var names = lexeme.substring(offset).split(',');
     offset += this.offset;
     for (var name in names) {
       var trimmedName = name.trim();
-      if (trimmedName.isNotEmpty) {
+      if (trimmedName.isNotEmpty && isValidIdentifier(trimmedName)) {
         var innerOffset = name.indexOf(trimmedName);
         yield DiagnosticName(trimmedName.toLowerCase(), offset + innerOffset);
       }
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 6138667..1153c8e 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -84,7 +84,9 @@
     for (var cycle in allCycles) {
       for (var element in cycle) {
         var boundNode = element.parameter.bound;
-        if (boundNode is TypeNameImpl) {
+        if (boundNode is GenericFunctionTypeImpl) {
+          boundNode.type = DynamicTypeImpl.instance;
+        } else if (boundNode is TypeNameImpl) {
           boundNode.type = DynamicTypeImpl.instance;
         } else {
           throw UnimplementedError('(${boundNode.runtimeType}) $boundNode');
diff --git a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
index 969205a..d2c6f73 100644
--- a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
@@ -94,6 +94,14 @@
     ]);
   }
 
+  test_class_recursion_notInstantiated_genericFunctionType() async {
+    await assertErrorsInCode(r'''
+class A<T extends void Function(A)> {}
+''', [
+      error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 32, 1),
+    ]);
+  }
+
   test_class_recursion_typedef_notInstantiated() async {
     await assertErrorsInCode(r'''
 typedef F(C value);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 470764b..e4b74af 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1765,6 +1765,19 @@
 ''');
   }
 
+  test_class_typeParameters_defaultType_cycle_genericFunctionType() async {
+    var library = await checkLibrary(r'''
+class A<T extends void Function(A)> {}
+''');
+    checkElementText(
+        library,
+        r'''
+notSimplyBounded class A<covariant T extends void Function(A<dynamic>)> {
+}
+''',
+        withTypeParameterVariance: true);
+  }
+
   test_class_typeParameters_defaultType_functionTypeAlias_contravariant_legacy() async {
     featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary(r'''
diff --git a/tools/VERSION b/tools/VERSION
index 4177771..91d40c7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 156
+PRERELEASE 157
 PRERELEASE_PATCH 0
\ No newline at end of file