Library import quick-fix: support calls to top-level function variables

Fixes https://github.com/dart-lang/sdk/issues/34374

Change-Id: I6878d443afa2c70e3833fe4ed2118b28878b3210
Reviewed-on: https://dart-review.googlesource.com/c/89171
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
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 8601890..0db0fb2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -2157,8 +2157,10 @@
     _addFixFromBuilder(changeBuilder, kind, args: [uriText]);
   }
 
-  Future<void> _addFix_importLibrary_withElement(String name,
-      List<ElementKind> elementKinds, TopLevelDeclarationKind kind2) async {
+  Future<void> _addFix_importLibrary_withElement(
+      String name,
+      List<ElementKind> elementKinds,
+      List<TopLevelDeclarationKind> kinds2) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     // ignore if private
@@ -2231,7 +2233,7 @@
       var declarations = await session.getTopLevelDeclarations(name);
       for (TopLevelDeclarationInSource declaration in declarations) {
         // Check the kind.
-        if (declaration.declaration.kind != kind2) {
+        if (!kinds2.contains(declaration.declaration.kind)) {
           continue;
         }
         // Check the source.
@@ -2269,8 +2271,13 @@
       MethodInvocation invocation = node.parent as MethodInvocation;
       if (invocation.realTarget == null && invocation.methodName == node) {
         String name = (node as SimpleIdentifier).name;
-        await _addFix_importLibrary_withElement(name,
-            const [ElementKind.FUNCTION], TopLevelDeclarationKind.function);
+        await _addFix_importLibrary_withElement(name, const [
+          ElementKind.FUNCTION,
+          ElementKind.TOP_LEVEL_VARIABLE
+        ], const [
+          TopLevelDeclarationKind.function,
+          TopLevelDeclarationKind.variable
+        ]);
       }
     }
   }
@@ -2283,7 +2290,7 @@
       await _addFix_importLibrary_withElement(
           name,
           const [ElementKind.TOP_LEVEL_VARIABLE],
-          TopLevelDeclarationKind.variable);
+          const [TopLevelDeclarationKind.variable]);
     }
   }
 
@@ -2295,11 +2302,11 @@
       await _addFix_importLibrary_withElement(
           typeName,
           const [ElementKind.CLASS, ElementKind.FUNCTION_TYPE_ALIAS],
-          TopLevelDeclarationKind.type);
+          const [TopLevelDeclarationKind.type]);
     } else if (_mayBeImplicitConstructor(node)) {
       String typeName = (node as SimpleIdentifier).name;
-      await _addFix_importLibrary_withElement(
-          typeName, const [ElementKind.CLASS], TopLevelDeclarationKind.type);
+      await _addFix_importLibrary_withElement(typeName,
+          const [ElementKind.CLASS], const [TopLevelDeclarationKind.type]);
     }
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index 68d5820..78de092 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -362,6 +362,53 @@
 ''');
   }
 
+  test_withFunction_functionTopLevelVariable() async {
+    addSource('/home/test/lib/lib.dart', 'var myFunction = () {};');
+    await resolveTestUnit('''
+main() {
+  myFunction();
+}
+''');
+    await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+  myFunction();
+}
+''');
+  }
+
+  test_withFunction_preferFunctionOverTopLevelVariable() async {
+    _configureMyPkg({
+      'b.dart': 'var myFunction = () {};',
+      'a.dart': 'myFunction() {}',
+    });
+    await resolveTestUnit('''
+main() {
+  myFunction();
+}
+''');
+    await assertHasFix('''
+import 'package:my_pkg/a.dart';
+
+main() {
+  myFunction();
+}
+''');
+  }
+
+  @failingTest
+  test_withFunction_nonFunctionType() async {
+    // TODO Remove preferFunctionOverTopLevelVariable test once this is passing
+    addSource('/home/test/lib/lib.dart', 'int zero = 0;');
+    await resolveTestUnit('''
+main() {
+  zero();
+}
+''');
+    await assertNoFix();
+  }
+
   test_withTopLevelVariable() async {
     addSource('/home/test/lib/lib.dart', '''
 library lib;