Version 2.16.0-130.0.dev

Merge commit '2fb63da09ff48bcd912a680a0b4c4416a0f3e207' into 'dev'
diff --git a/DEPS b/DEPS
index 727fe76..b98102b 100644
--- a/DEPS
+++ b/DEPS
@@ -107,7 +107,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_rev": "08b0294d0a500d5c02168ef57dcb8868d0c3cb48",
 
-  "dartdoc_rev" : "ff0d94bdb87f11c04a7e0ddab811bf94211b08a4",
+  "dartdoc_rev" : "11c4b3c9723bfa7155efcf0fef02329233a6381d",
   "devtools_rev" : "85932bb66aa782c4b2c528be7718960bf256ffb7",
   "jsshell_tag": "version:88.0",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart
new file mode 100644
index 0000000..8b37810
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddReturnNull extends CorrectionProducer {
+  @override
+  bool get canBeAppliedInBulk => true;
+
+  @override
+  bool get canBeAppliedToFile => true;
+
+  @override
+  FixKind get fixKind => DartFixKind.ADD_RETURN_NULL;
+
+  @override
+  FixKind? get multiFixKind => DartFixKind.ADD_RETURN_NULL_MULTI;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    Block block;
+
+    var coveringNode = coveredNode;
+    if (coveringNode is Block) {
+      block = coveringNode;
+    } else if (coveringNode is SimpleIdentifier) {
+      var declaration = coveringNode.parent;
+      if (declaration is FunctionDeclaration) {
+        var body = declaration.functionExpression.body;
+        if (body is BlockFunctionBody) {
+          block = body.block;
+        } else {
+          return;
+        }
+      } else if (declaration is MethodDeclaration) {
+        var body = declaration.body;
+        if (body is BlockFunctionBody) {
+          block = body.block;
+        } else {
+          return;
+        }
+      } else {
+        return;
+      }
+    } else {
+      return;
+    }
+    int position;
+    String returnStatement;
+    if (block.statements.isEmpty) {
+      position = block.offset + 1;
+      var prefix = utils.getLinePrefix(block.offset);
+      returnStatement =
+          '$eol$prefix${utils.getIndent(1)}return null;$eol$prefix';
+    } else {
+      var lastStatement = block.statements.last;
+      position = lastStatement.offset + lastStatement.length;
+      var prefix = utils.getNodePrefix(lastStatement);
+      returnStatement = '$eol${prefix}return null;';
+    }
+
+    await builder.addDartFileEdit(file, (builder) {
+      builder.addInsertion(position, (builder) {
+        builder.write(returnStatement);
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddReturnNull newInstance() => AddReturnNull();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index e802922..59471b3 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -213,6 +213,16 @@
     DartFixKindPriority.IN_FILE,
     "Add 'required' keywords everywhere in file",
   );
+  static const ADD_RETURN_NULL = FixKind(
+    'dart.fix.add.returnNull',
+    DartFixKindPriority.DEFAULT,
+    "Add 'return null'",
+  );
+  static const ADD_RETURN_NULL_MULTI = FixKind(
+    'dart.fix.add.returnNull.multi',
+    DartFixKindPriority.IN_FILE,
+    "Add 'return null' everywhere in file",
+  );
   static const ADD_RETURN_TYPE = FixKind(
     'dart.fix.add.returnType',
     DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 6b3f145..128e4eb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -25,6 +25,7 @@
 import 'package:analysis_server/src/services/correction/dart/add_override.dart';
 import 'package:analysis_server/src/services/correction/dart/add_required.dart';
 import 'package:analysis_server/src/services/correction/dart/add_required_keyword.dart';
+import 'package:analysis_server/src/services/correction/dart/add_return_null.dart';
 import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
 import 'package:analysis_server/src/services/correction/dart/add_static.dart';
 import 'package:analysis_server/src/services/correction/dart/add_super_constructor_invocation.dart';
@@ -1077,6 +1078,9 @@
       MakeReturnTypeNullable.newInstance,
     ],
 
+    HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE: [
+      AddReturnNull.newInstance,
+    ],
     HintCode.CAN_BE_NULL_AFTER_NULL_AWARE: [
       ReplaceWithNullAware.inChain,
     ],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_return_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_return_null_test.dart
new file mode 100644
index 0000000..f12fd37
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_return_null_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddReturnNullBulkTest);
+    defineReflectiveTests(AddReturnNullTest);
+  });
+}
+
+@reflectiveTest
+class AddReturnNullBulkTest extends BulkFixProcessorTest {
+  Future<void> test_singleFile() async {
+    await resolveTestCode('''
+int? f() {
+  // ignore: unused_element
+  int? g() {
+    if (1 == 2) return 5;
+  }
+  if (1 == 2) return 7;
+}
+''');
+    await assertHasFix('''
+int? f() {
+  // ignore: unused_element
+  int? g() {
+    if (1 == 2) return 5;
+    return null;
+  }
+  if (1 == 2) return 7;
+  return null;
+}
+''');
+  }
+}
+
+@reflectiveTest
+class AddReturnNullTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.ADD_RETURN_NULL;
+
+  Future<void> test_functionExpression() async {
+    await resolveTestCode('''
+int? Function() f = () {
+  if (1 == 2) return 7;
+};
+''');
+    await assertHasFix('''
+int? Function() f = () {
+  if (1 == 2) return 7;
+  return null;
+};
+''');
+  }
+
+  Future<void> test_functionExpression_empty() async {
+    await resolveTestCode('''
+int? Function() f = () {};
+''');
+    await assertHasFix('''
+int? Function() f = () {
+  return null;
+};
+''');
+  }
+
+  Future<void> test_localFunction() async {
+    await resolveTestCode('''
+void m() {
+  // ignore: unused_element
+  int? f() {
+    if (1 == 2) return 7;
+  }
+}
+''');
+    await assertHasFix('''
+void m() {
+  // ignore: unused_element
+  int? f() {
+    if (1 == 2) return 7;
+    return null;
+  }
+}
+''');
+  }
+
+  Future<void> test_method() async {
+    await resolveTestCode('''
+class A {
+  int? m() {
+    if (1 == 2) return 7;
+  }
+}
+''');
+    await assertHasFix('''
+class A {
+  int? m() {
+    if (1 == 2) return 7;
+    return null;
+  }
+}
+''');
+  }
+
+  Future<void> test_topLevelFunction_block() async {
+    await resolveTestCode('''
+int? f() {
+  if (1 == 2) return 7;
+}
+''');
+    await assertHasFix('''
+int? f() {
+  if (1 == 2) return 7;
+  return null;
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 3753bfb..46e09ff 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -30,6 +30,7 @@
 import 'add_null_check_test.dart' as add_null_check;
 import 'add_override_test.dart' as add_override;
 import 'add_required_test.dart' as add_required;
+import 'add_return_null_test.dart' as add_return_null;
 import 'add_return_type_test.dart' as add_return_type;
 import 'add_static_test.dart' as add_static;
 import 'add_super_constructor_invocation_test.dart'
@@ -234,6 +235,7 @@
     add_null_check.main();
     add_override.main();
     add_required.main();
+    add_return_null.main();
     add_return_type.main();
     add_static.main();
     add_super_constructor_invocation.main();
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 105ec72..a6f4d42 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,5 +1,6 @@
 ## 3.1.0-dev
 * New internal API for `package:dart_style`.
+* Removed deprecated non-API `MockSdk` class.
 
 ## 3.0.0
 * Removed deprecated `DartType.aliasElement/aliasArguments`.
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 8a34bc8..25895fe 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -523,6 +523,7 @@
   FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH,
   HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE_TO_ERROR_HANDLER,
   HintCode.ASSIGNMENT_OF_DO_NOT_STORE,
+  HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE,
   HintCode.CAN_BE_NULL_AFTER_NULL_AWARE,
   HintCode.DEAD_CODE,
   HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index c24474a..8c78fc5 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -91,6 +91,19 @@
   );
 
   /**
+   * Parameters:
+   * 0: the name of the declared return type
+   */
+  static const HintCode BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE = HintCode(
+    'BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE',
+    "This function has a nullable return type of '{0}', but ends without "
+        "returning a value.",
+    correctionMessage:
+        "Try adding a return statement, or if no value is ever returned, try "
+        "changing the return type to 'void'.",
+  );
+
+  /**
    * When the target expression uses '?.' operator, it can be `null`, so all the
    * subsequent invocations should also use '?.' operator.
    */
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
index be1eec6..2558708 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
 import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
 import 'package:analyzer/src/generated/migration.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -64,9 +63,7 @@
     _resolve2(node);
 
     if (_resolver.flowAnalysis.flow != null && !isFunctionDeclaration) {
-      var bodyContext = BodyInferenceContext.of(node.body);
       _resolver.checkForBodyMayCompleteNormally(
-        returnType: bodyContext?.contextType,
         body: body,
         errorNode: body,
       );
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index b6c24eb..42f8ae1 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -1115,13 +1115,15 @@
   // }
   // ```
   //
-  // If the method intentionally returns `null` at the end, then change the
+  // If the method intentionally returns `null` at the end, then add an
+  // explicit return of `null` at the end of the method and change the
   // return type so that it's valid to return `null`:
   //
   // ```dart
   // class C<T> {
   //   T? m(T t) {
   //     print(t);
+  //     return null;
   //   }
   // }
   // ```
@@ -1129,7 +1131,7 @@
       CompileTimeErrorCode(
     'BODY_MIGHT_COMPLETE_NORMALLY',
     "The body might complete normally, causing 'null' to be returned, but the "
-        "return type is a potentially non-nullable type.",
+        "return type, '{0}', is a potentially non-nullable type.",
     correctionMessage:
         "Try adding either a return or a throw statement at the end.",
     hasPublishedDocs: true,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 95f6e32..ddcbc07 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -472,7 +472,6 @@
   }
 
   void checkForBodyMayCompleteNormally({
-    required DartType? returnType,
     required FunctionBody body,
     required AstNode errorNode,
   }) {
@@ -481,6 +480,12 @@
       return;
     }
 
+    // TODO(scheglov) encapsulate
+    var bodyContext = BodyInferenceContext.of(body);
+    if (bodyContext == null) {
+      return null;
+    }
+    var returnType = bodyContext.contextType;
     if (returnType == null) {
       return;
     }
@@ -490,24 +495,59 @@
         return;
       }
 
-      if (typeSystem.isPotentiallyNonNullable(returnType)) {
-        if (errorNode is ConstructorDeclaration) {
-          errorReporter.reportErrorForName(
-            CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
-            errorNode,
-          );
-        } else if (errorNode is BlockFunctionBody) {
-          errorReporter.reportErrorForToken(
-            CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
-            errorNode.block.leftBracket,
-          );
-        } else {
-          errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY,
-            errorNode,
-          );
+      if (body.isAsynchronous) {
+        // Check whether the return type is legal. If not, return rather than
+        // reporting a second error.
+
+        // This is the same check as [ReturnTypeVerifier._isLegalReturnType].
+        // TODO(srawlins): When this check is moved into the resolution stage,
+        // use the result of that check to determine whether this check should
+        // be done.
+        var lowerBound = typeProvider.futureElement.instantiate(
+          typeArguments: [NeverTypeImpl.instance],
+          nullabilitySuffix: NullabilitySuffix.star,
+        );
+        var imposedType = bodyContext.imposedType;
+        if (imposedType != null &&
+            !typeSystem.isSubtypeOf(lowerBound, imposedType)) {
+          // [imposedType] is an illegal return type for an asynchronous
+          // non-generator function; do not report an additional error here.
+          return;
         }
       }
+
+      ErrorCode errorCode;
+      if (typeSystem.isPotentiallyNonNullable(returnType)) {
+        errorCode = CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY;
+      } else {
+        var returnTypeBase = typeSystem.futureOrBase(returnType);
+        if (returnTypeBase.isVoid ||
+            returnTypeBase.isDynamic ||
+            returnTypeBase.isDartCoreNull) {
+          return;
+        } else {
+          errorCode = HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE;
+        }
+      }
+      if (errorNode is ConstructorDeclaration) {
+        errorReporter.reportErrorForName(
+          errorCode,
+          errorNode,
+          arguments: [returnType],
+        );
+      } else if (errorNode is BlockFunctionBody) {
+        errorReporter.reportErrorForToken(
+          errorCode,
+          errorNode.block.leftBracket,
+          [returnType],
+        );
+      } else {
+        errorReporter.reportErrorForNode(
+          errorCode,
+          errorNode,
+          [returnType],
+        );
+      }
     }
   }
 
@@ -1342,9 +1382,7 @@
     }
 
     if (node.factoryKeyword != null) {
-      var bodyContext = BodyInferenceContext.of(node.body);
       checkForBodyMayCompleteNormally(
-        returnType: bodyContext?.contextType,
         body: node.body,
         errorNode: node,
       );
@@ -1573,12 +1611,7 @@
     }
 
     if (!node.isSetter) {
-      // TODO(scheglov) encapsulate
-      var bodyContext = BodyInferenceContext.of(
-        node.functionExpression.body,
-      );
       checkForBodyMayCompleteNormally(
-        returnType: bodyContext?.contextType,
         body: node.functionExpression.body,
         errorNode: node.name,
       );
@@ -1804,10 +1837,7 @@
     }
 
     if (!node.isSetter) {
-      // TODO(scheglov) encapsulate
-      var bodyContext = BodyInferenceContext.of(node.body);
       checkForBodyMayCompleteNormally(
-        returnType: bodyContext?.contextType,
         body: node.body,
         errorNode: node.name,
       );
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 44de859..4b84ce8 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -352,9 +352,6 @@
       _enclosingContext.addParameter(null, element);
     }
     element.hasImplicitType = node.type == null && node.parameters == null;
-    // TODO(scheglov) Do we need these two below?
-    element.isExplicitlyCovariant = node.covariantKeyword != null;
-    element.isFinal = node.isFinal;
     element.metadata = _buildAnnotations(node.metadata);
     _setCodeRange(element, node);
 
@@ -823,9 +820,6 @@
       _enclosingContext.addParameter(null, element);
     }
     element.hasImplicitType = node.type == null && node.parameters == null;
-    // TODO(scheglov) Do we need these two below?
-    // element.isExplicitlyCovariant = node.covariantKeyword != null;
-    // element.isFinal = node.isFinal;
     element.metadata = _buildAnnotations(node.metadata);
     _setCodeRange(element, node);
 
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 6589d31..4208e83 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -383,8 +383,6 @@
 
     scope = TypeParameterScope(scope, element.typeParameters);
 
-    // TODO(scheglov) More tests when the parse issue fixed.
-    // https://github.com/dart-lang/sdk/issues/47951
     node.type?.accept(this);
     node.typeParameters?.accept(this);
     node.parameters?.accept(this);
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index fc19a52..53b27e3 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -313,8 +313,6 @@
   }
 
   void _superFormalParameter(SuperFormalParameter node) {
-    // TODO(scheglov) More tests when the parse issue fixed.
-    // https://github.com/dart-lang/sdk/issues/47951
     var element = node.declaredElement as SuperFormalParameterElementImpl;
     var parameterList = node.parameters;
     if (parameterList != null) {
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index d13df5d..44a6369 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -7,13 +7,9 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:meta/meta.dart';
 
-@Deprecated('Use createMockSdk() instead')
-const String sdkRoot = '/sdk';
-
 final MockSdkLibrary _LIB_ASYNC = MockSdkLibrary('async', [
   MockSdkLibraryUnit(
     'async/async.dart',
@@ -1303,51 +1299,6 @@
       );
 }
 
-@Deprecated('Use createMockSdk() and FolderBasedDartSdk instead.')
-class MockSdk extends FolderBasedDartSdk {
-  /// Optional [additionalLibraries] should have unique URIs, and paths in
-  /// their units are relative (will be put into `sdkRoot/lib`).
-  factory MockSdk({
-    required MemoryResourceProvider resourceProvider,
-    List<MockSdkLibrary> additionalLibraries = const [],
-  }) {
-    var sdkDirectory = resourceProvider.getFolder(
-      resourceProvider.convertPath(sdkRoot),
-    );
-    createMockSdk(
-      resourceProvider: resourceProvider,
-      root: sdkDirectory,
-      additionalLibraries: additionalLibraries,
-    );
-    return MockSdk._(resourceProvider, sdkDirectory);
-  }
-
-  /// Initialize a newly created SDK to represent the Dart SDK installed in the
-  /// [sdkDirectory].
-  MockSdk._(ResourceProvider resourceProvider, Folder sdkDirectory)
-      : super(resourceProvider, sdkDirectory);
-
-  @override
-  MemoryResourceProvider get resourceProvider {
-    return super.resourceProvider as MemoryResourceProvider;
-  }
-
-  @override
-  List<SdkLibraryImpl> get sdkLibraries {
-    return super.sdkLibraries.map((library) {
-      var pathContext = resourceProvider.pathContext;
-      var path = library.path;
-      if (pathContext.isAbsolute(path)) {
-        return library;
-      }
-      return SdkLibraryImpl(library.shortName)
-        ..path = pathContext.join(directory.path, 'lib', path)
-        ..category = library.category
-        ..documented = library.isDocumented;
-    }).toList();
-  }
-}
-
 class MockSdkLibrary implements SdkLibrary {
   final String name;
   final String categories;
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 675733f..b079038 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -1082,7 +1082,7 @@
       immediately enclosing _a_ is not declared asynchronous. (Where _a_ is the
       await expression.)
   BODY_MIGHT_COMPLETE_NORMALLY:
-    problemMessage: "The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type."
+    problemMessage: "The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type."
     correctionMessage: Try adding either a return or a throw statement at the end.
     hasPublishedDocs: true
     comment: No parameters.
@@ -1146,13 +1146,15 @@
       }
       ```
 
-      If the method intentionally returns `null` at the end, then change the
+      If the method intentionally returns `null` at the end, then add an
+      explicit return of `null` at the end of the method and change the
       return type so that it's valid to return `null`:
 
       ```dart
       class C<T> {
         T? m(T t) {
           print(t);
+          return null;
         }
       }
       ```
@@ -14069,6 +14071,13 @@
     problemMessage: "'{0}' is marked 'doNotStore' and shouldn't be assigned to a field or top-level variable."
     correctionMessage: Try removing the assignment.
     comment: Users should not assign values marked `@doNotStore`.
+  BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE:
+    problemMessage: "This function has a nullable return type of '{0}', but ends without returning a value."
+    correctionMessage: "Try adding a return statement, or if no value is ever returned, try changing the return type to 'void'."
+    hasPublishedDocs: false
+    comment: |-
+      Parameters:
+      0: the name of the declared return type
   CAN_BE_NULL_AFTER_NULL_AWARE:
     problemMessage: "The receiver uses '?.', so its value can be null."
     correctionMessage: "Replace the '.' with a '?.' in the invocation."
diff --git a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_nullable_test.dart b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_nullable_test.dart
new file mode 100644
index 0000000..3925f45
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_nullable_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BodyMightCompleteNormallyNullableTest);
+  });
+}
+
+@reflectiveTest
+class BodyMightCompleteNormallyNullableTest extends PubPackageResolutionTest {
+  test_function_async_block_futureOrIntQuestion() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+FutureOr<int?> f(Future f) async {}
+''', [
+      error(HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE, 36, 1),
+    ]);
+  }
+
+  test_function_async_block_futureOrVoid() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+FutureOr<void> f(Future f) async {}
+''');
+  }
+
+  test_function_async_block_void() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+void f(Future f) async {}
+''');
+  }
+
+  test_function_sync_block_dynamic() async {
+    await assertNoErrorsInCode('''
+dynamic f() {}
+''');
+  }
+
+  test_function_sync_block_intQuestion() async {
+    await assertErrorsInCode('''
+int? f() {}
+''', [
+      error(HintCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE, 5, 1),
+    ]);
+  }
+
+  test_function_sync_block_intQuestion_definiteReturn() async {
+    await assertNoErrorsInCode('''
+int? f() {
+  return null;
+}
+''');
+  }
+
+  test_function_sync_block_Null() async {
+    await assertNoErrorsInCode('''
+Null f() {}
+''');
+  }
+
+  test_function_sync_block_void() async {
+    await assertNoErrorsInCode('''
+void f() {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
index e223720..973910e 100644
--- a/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/body_might_complete_normally_test.dart
@@ -222,16 +222,6 @@
 ''');
   }
 
-  test_functionExpression_nullable_blockBody() async {
-    await assertNoErrorsInCode(r'''
-main() {
-  int? Function() foo = () {
-  };
-  foo;
-}
-''');
-  }
-
   test_generativeConstructor_blockBody() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -350,14 +340,6 @@
 ''');
   }
 
-  test_method_nullable_blockBody() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  int? foo() {}
-}
-''');
-  }
-
   test_method_nullable_blockBody_return() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart b/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
index 01e30f0..1d56d74 100644
--- a/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/illegal_async_return_type_test.dart
@@ -17,7 +17,9 @@
 class IllegalAsyncReturnTypeTest extends PubPackageResolutionTest {
   test_function_nonFuture() async {
     await assertErrorsInCode('''
-int f() async {}
+int f() async {
+  return 1;
+}
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_ASYNC_RETURN_TYPE, 0, 3),
     ]);
@@ -53,7 +55,9 @@
   test_method_nonFuture() async {
     await assertErrorsInCode('''
 class C {
-  int m() async {}
+  int m() async {
+    return 1;
+  }
 }
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_ASYNC_RETURN_TYPE, 12, 3),
diff --git a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
index 7fbed0b..9f75275 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
@@ -140,7 +140,7 @@
   }
 
   test_functionExpression_sync_dynamic() async {
-    await assertNoErrorsInCode(r'''
+    await assertNoErrorsInCode('''
 Function() f = () {};
 ''');
   }
@@ -153,7 +153,7 @@
 
   test_localFunction_sync_dynamic() async {
     await assertNoErrorsInCode(r'''
-main() {
+void foo() {
   f() {}
   f;
 }
@@ -217,7 +217,26 @@
 
 @reflectiveTest
 class MissingReturnWithNullSafetyTest extends PubPackageResolutionTest {
-  test_returnNever() async {
+  test_function_async_block_futureOrVoid() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+FutureOr<void> f() async {}
+''');
+  }
+
+  test_function_async_block_void() async {
+    await assertNoErrorsInCode('''
+void f() async {}
+''');
+  }
+
+  test_function_sync_block_dynamic() async {
+    await assertNoErrorsInCode('''
+dynamic f() {}
+''');
+  }
+
+  test_function_sync_block_Never() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 Never foo() {
   throw 0;
@@ -232,4 +251,16 @@
 }
 ''');
   }
+
+  test_function_sync_block_Null() async {
+    await assertNoErrorsInCode('''
+Null f() {}
+''');
+  }
+
+  test_function_sync_block_void() async {
+    await assertNoErrorsInCode('''
+void f() {}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 4456cef..485fb55 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -41,6 +41,8 @@
     as await_in_late_local_variable_initializer;
 import 'await_in_wrong_context_test.dart' as await_in_wrong_context;
 import 'binary_operator_written_out_test.dart' as binary_operator_written_out;
+import 'body_might_complete_normally_nullable_test.dart'
+    as body_might_complete_normally_nullable;
 import 'body_might_complete_normally_test.dart' as body_might_complete_normally;
 import 'built_in_identifier_as_extension_name_test.dart'
     as built_in_as_extension_name;
@@ -751,6 +753,7 @@
     await_in_late_local_variable_initializer.main();
     await_in_wrong_context.main();
     binary_operator_written_out.main();
+    body_might_complete_normally_nullable.main();
     body_might_complete_normally.main();
     built_in_as_extension_name.main();
     built_in_as_prefix_name.main();
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 197ed0d..6040d05 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -632,7 +632,7 @@
       } else if (e.isOptionalPositional) {
         buffer.write('optionalPositional ');
       } else if (e.isRequiredNamed) {
-        buffer.write('requiredName ');
+        buffer.write('requiredNamed ');
       } else if (e.isOptionalNamed) {
         buffer.write('optionalNamed ');
       }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 0176996..9b74e08 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1453,6 +1453,78 @@
 ''');
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47951')
+  test_class_constructor_parameters_super_explicitType_function() async {
+    var library = await checkLibrary('''
+class A {
+  A(Object? a);
+}
+
+class B extends A {
+  B(int super.a<T extends num>(T d)?);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class A @6
+        constructors
+          @12
+            parameters
+              requiredPositional a @22
+                type: Object?
+      class B @35
+        supertype: A
+        constructors
+          @51
+            parameters
+              requiredPositional final super.a @63
+                type: int Function<T extends num>(T)?
+                typeParameters
+                  covariant T @65
+                    bound: num
+                parameters
+                  requiredPositional d @82
+                    type: T
+                superConstructorParameter: a@22
+            superConstructor: self::@class::A::@constructor::•
+''');
+  }
+
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47951')
+  test_class_constructor_parameters_super_explicitType_interface() async {
+    var library = await checkLibrary('''
+class A {
+  A(num a);
+}
+
+class B extends A {
+  B(int super.a);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class A @6
+        constructors
+          @12
+            parameters
+              requiredPositional a @18
+                type: num
+      class B @31
+        supertype: A
+        constructors
+          @47
+            parameters
+              requiredPositional final super.a @49
+                type: int
+                superConstructorParameter: a@18
+            superConstructor: self::@class::A::@constructor::•
+''');
+  }
+
   test_class_constructor_parameters_super_optionalNamed() async {
     var library = await checkLibrary('''
 class A {
@@ -1471,9 +1543,9 @@
         constructors
           @12
             parameters
-              requiredName a @28
+              requiredNamed a @28
                 type: int
-              requiredName b @47
+              requiredNamed b @47
                 type: double
       class B @61
         supertype: A
@@ -1512,7 +1584,7 @@
         constructors
           @12
             parameters
-              requiredName a @28
+              requiredNamed a @28
                 type: int
       class B @42
         supertype: A
@@ -1590,23 +1662,23 @@
         constructors
           @12
             parameters
-              requiredName a @28
+              requiredNamed a @28
                 type: int
-              requiredName b @47
+              requiredNamed b @47
                 type: double
       class B @61
         supertype: A
         constructors
           @77
             parameters
-              requiredName o1 @101
+              requiredNamed o1 @101
                 type: String
-              requiredName final super.a @124
+              requiredNamed final super.a @124
                 type: int
                 superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-              requiredName o2 @147
+              requiredNamed o2 @147
                 type: String
-              requiredName final super.b @170
+              requiredNamed final super.b @170
                 type: double
                 superConstructorParameter: self::@class::A::@constructor::•::@parameter::b
             superConstructor: self::@class::A::@constructor::•
@@ -27621,7 +27693,7 @@
     functions
       f @5
         parameters
-          requiredName f @22
+          requiredNamed f @22
             type: void Function<U>(int)
             typeParameters
               covariant U @24
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 97d64c9..8f8c3aa 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -1323,7 +1323,7 @@
 ### body_might_complete_normally
 
 _The body might complete normally, causing 'null' to be returned, but the return
-type is a potentially non-nullable type._
+type, '{0}', is a potentially non-nullable type._
 
 #### Description
 
@@ -1384,13 +1384,15 @@
 }
 {% endprettify %}
 
-If the method intentionally returns `null` at the end, then change the
+If the method intentionally returns `null` at the end, then add an
+explicit return of `null` at the end of the method and change the
 return type so that it's valid to return `null`:
 
 {% prettify dart tag=pre+code %}
 class C<T> {
   T? m(T t) {
     print(t);
+    return null;
   }
 }
 {% endprettify %}
diff --git a/tools/VERSION b/tools/VERSION
index 8f2a41d..880412c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 129
+PRERELEASE 130
 PRERELEASE_PATCH 0
\ No newline at end of file