ChangeBuilder.writeType to handle nullability of Function

Bug: 29050
Change-Id: I2ec8e0a49c626f75ebd1d21adad5d0d63123c54f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212760
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index de7daf0..694ecfc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -168,6 +168,29 @@
 ''');
   }
 
+  Future<void> test_functionTypedParameter_nullable() async {
+    await resolveTestCode('''
+abstract class A {
+  void forEach(int f(double p1, String p2)?);
+}
+
+class B extends A {
+}
+''');
+    await assertHasFix('''
+abstract class A {
+  void forEach(int f(double p1, String p2)?);
+}
+
+class B extends A {
+  @override
+  void forEach(int Function(double p1, String p2)? f) {
+    // TODO: implement forEach
+  }
+}
+''');
+  }
+
   Future<void> test_generics_typeArguments() async {
     await resolveTestCode('''
 class Iterator<T> {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 0738926..3a1b365 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1234,6 +1234,9 @@
       writeTypeParameters(type.typeFormals,
           methodBeingCopied: methodBeingCopied);
       writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
+      if (type.nullabilitySuffix == NullabilitySuffix.question) {
+        write('?');
+      }
       return true;
     }
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index ac77675..c58eee8 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -48,6 +48,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('required a'));
   }
 
+  Future<void> test_writeType_function_nullable() async {
+    await _assertWriteType('int Function(double a, String b)?');
+  }
+
   Future<void> test_writeType_Never_none() async {
     await _assertWriteType('Never');
   }