Fix handling of `@Injectable` functions

Recent changes that made migration tool more conservative affected
functions used in Angular's DI: functions annotated with `@Injectable`
must have non-nullable non-annotated arguments. Previously that
worked just because there was no reason to make them nullable.

Make such functions' arguments explicitly non-nullable.

Bug: b/250862403
Change-Id: I27207994b058ba845aafd7776d14380e8104e8f8
Tested: added a test
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289505
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Ilya Yanok <yanok@google.com>
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index eed9bb4..3d8f310 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -881,8 +881,11 @@
         }
       }
     }
-    if (declaredElement.enclosingElement is ConstructorElement &&
-        (_isInsideAngularComponent || _isInjectable) &&
+    final enclosingElement = declaredElement.enclosingElement;
+    if ((enclosingElement is ConstructorElement &&
+                (_isInsideAngularComponent || _isInjectable) ||
+            (enclosingElement is FunctionElement) &&
+                _hasInjectable(enclosingElement)) &&
         !isAnnotated) {
       _graph.makeNonNullable(
           decoratedType!.node, AngularConstructorArgumentOrigin(source, node));
@@ -976,6 +979,9 @@
         declaredElement, decoratedSupertypes);
   }
 
+  bool _hasInjectable(Element element) => element.metadata
+      .any((ann) => _isAngularConstructor(ann.element, 'Injectable'));
+
   /// Determines whether [element] is a constructor named [name] from Angular
   /// package.
   bool _isAngularConstructor(Element? element, String name) =>
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index d4d649b..eb63db6 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -556,6 +556,27 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_angular_injectable_function() async {
+    addAngularPackage();
+    var content = '''
+import 'package:angular/angular.dart';
+
+class C {}
+
+@Injectable()
+C createC(int n, @Optional() int x) => C();
+''';
+    var expected = '''
+import 'package:angular/angular.dart';
+
+class C {}
+
+@Injectable()
+C createC(int n, @Optional() int? x) => C();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_angular_optional_constructor_param() async {
     addAngularPackage();
     var content = '''