[analysis_server] Fix context type for function expressions with implicit returns

Fixes https://github.com/Dart-Code/Dart-Code/issues/5162

Change-Id: I86148b3d847fc2a743307703390ff98c93b4c142
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/374600
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 9df58ee..caa2809 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -626,9 +626,13 @@
       if (parent is MethodDeclarationImpl) {
         return parent.body.bodyContext?.contextType;
       } else if (parent is FunctionExpressionImpl) {
-        var grandparent = parent.parent;
-        if (grandparent is FunctionDeclaration) {
-          return parent.body.bodyContext?.contextType;
+        // If the surrounding function has a context type, use it.
+        var functionContextType = parent.body.bodyContext?.contextType;
+        if (functionContextType != null) {
+          return functionContextType;
+        } else if (parent.parent is FunctionDeclaration) {
+          // Don't walk up past the function declaration.
+          return null;
         }
         return _visitParent(parent);
       }
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_test.dart
index c270aee..92dd886 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_test.dart
@@ -9556,7 +9556,7 @@
 }
 bar(p) {}
 void f(p) {
-  foo( Functions.^; );
+  foo( Functions.^ );
 }
 ''');
     assertResponse(r'''
@@ -9577,7 +9577,7 @@
 }
 bar(p) {}
 void f(p) {
-  foo( (int p) => Functions.^; );
+  foo( (int p) => Functions.^ );
 }
 ''');
     assertResponse(r'''
diff --git a/pkg/analysis_server/test/services/completion/dart/location/function_expression_test.dart b/pkg/analysis_server/test/services/completion/dart/location/function_expression_test.dart
index 3cd4b98..f95bcfa 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/function_expression_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/function_expression_test.dart
@@ -152,4 +152,50 @@
     kind: keyword
 ''');
   }
+
+  Future<void> test_contextType_return_explicit_record_namedField() async {
+    await computeSuggestions('''
+void f(({int i}) Function() callback) {
+  f(() { return (^); });
+}
+''');
+    assertResponse(r'''
+suggestions
+  |i: |
+    kind: namedArgument
+  const
+    kind: keyword
+  false
+    kind: keyword
+  null
+    kind: keyword
+  switch
+    kind: keyword
+  true
+    kind: keyword
+''');
+  }
+
+  Future<void> test_contextType_return_implicit_record_namedField() async {
+    await computeSuggestions('''
+void f(({int i}) Function() callback) {
+  f(() => (^));
+}
+''');
+    assertResponse(r'''
+suggestions
+  |i: |
+    kind: namedArgument
+  const
+    kind: keyword
+  false
+    kind: keyword
+  null
+    kind: keyword
+  switch
+    kind: keyword
+  true
+    kind: keyword
+''');
+  }
 }