[analysis_server] Disallow extract method on all prefixes

Change-Id: I63ecfab4fad63797358dc2cfb7d5cf79ca444dc7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252340
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 4dfd72a..fcfcab8 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -989,14 +989,14 @@
       if (element is FunctionElement || element is MethodElement) {
         invalidSelection('Cannot extract a single method name.');
       }
+      if (element is PrefixElement) {
+        invalidSelection('Cannot extract an import prefix.');
+      }
       var parent = node.parent;
       if (parent is PrefixedIdentifier) {
         if (parent.identifier == node) {
           // name in property access
           invalidSelection('Cannot extract name part of a property access.');
-        } else if (parent.prefix == node && parent.parent is NamedType) {
-          // prefix in a named type (for example `io` in `io.File`)
-          invalidSelection('Cannot extract prefix part of a type reference.');
         }
       }
       // part of a named type (for example `int` in `int?`)
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 35cf422..4335a2d 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -395,6 +395,17 @@
         'Not all selected statements are enclosed by the same parent statement.');
   }
 
+  Future<void> test_bad_function_prefix() async {
+    await indexTestUnit('''
+import 'dart:io' as io;
+void f() {
+  io.exit(1);
+}
+''');
+    _createRefactoringWithSuffix('io', '.exit');
+    return _assertConditionsFatal('Cannot extract an import prefix.');
+  }
+
   Future<void> test_bad_methodName_reference() async {
     await indexTestUnit('''
 void f() {
@@ -769,8 +780,7 @@
 }
 ''');
     _createRefactoringWithSuffix('io', '.File f');
-    return _assertConditionsFatal(
-        'Cannot extract prefix part of a type reference.');
+    return _assertConditionsFatal('Cannot extract an import prefix.');
   }
 
   Future<void> test_bad_variableDeclarationFragment() async {
@@ -2463,6 +2473,25 @@
     await assertRefactoringConditionsOK();
   }
 
+  Future<void> test_statements_functionPrefix() async {
+    await indexTestUnit('''
+import 'dart:io' as io;
+void f() {
+  io.exit(1);
+}
+''');
+    _createRefactoringForString('io.exit(1)');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+import 'dart:io' as io;
+void f() {
+  res();
+}
+
+Never res() => io.exit(1);
+''');
+  }
+
   Future<void> test_statements_hasAwait_dynamicReturnType() async {
     await indexTestUnit('''
 import 'dart:async';