Generalize extracting leading identifiers in fuzzyFilterSort().

Change-Id: Id24afe3ff4b107956887561c30708c60e2e3033d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239243
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/fuzzy_filter_sort.dart b/pkg/analysis_server/lib/src/services/completion/dart/fuzzy_filter_sort.dart
index b1247c7..69e49fe 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/fuzzy_filter_sort.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/fuzzy_filter_sort.dart
@@ -6,6 +6,8 @@
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
 
+final _identifierPattern = RegExp(r'([_a-zA-Z][_a-zA-Z0-9]*)');
+
 /// Filters and scores [suggestions] according to how well they match the
 /// [pattern]. Sorts [suggestions] by the score, relevance, and name.
 List<CompletionSuggestionBuilder> fuzzyFilterSort({
@@ -15,21 +17,18 @@
   var matcher = FuzzyMatcher(pattern, matchStyle: MatchStyle.SYMBOL);
 
   double score(CompletionSuggestionBuilder suggestion) {
-    var suggestionTextToMatch = suggestion.completion;
+    var textToMatch = suggestion.completion;
 
-    if (suggestion.kind == CompletionSuggestionKind.KEYWORD) {
-      var index = suggestionTextToMatch.indexOf(' ');
-      if (index != -1) {
-        suggestionTextToMatch = suggestionTextToMatch.substring(0, index);
+    if (suggestion.kind == CompletionSuggestionKind.KEYWORD ||
+        suggestion.kind == CompletionSuggestionKind.NAMED_ARGUMENT) {
+      var identifier = _identifierPattern.matchAsPrefix(textToMatch)?.group(1);
+      if (identifier == null) {
+        return -1;
       }
-    } else if (suggestion.kind == CompletionSuggestionKind.NAMED_ARGUMENT) {
-      var index = suggestionTextToMatch.indexOf(':');
-      if (index != -1) {
-        suggestionTextToMatch = suggestionTextToMatch.substring(0, index);
-      }
+      textToMatch = identifier;
     }
 
-    return matcher.score(suggestionTextToMatch);
+    return matcher.score(textToMatch);
   }
 
   var scored = suggestions