in lib/src/analysis_server.dart [141:189]
Future<proto.CompleteResponse> complete(String src, int offset) async {
final sources = <String, String>{kMainDart: src};
final location = Location(kMainDart, offset);
final results =
await _completeImpl(sources, location.sourceName, location.offset);
var suggestions = results.results;
final source = sources[location.sourceName]!;
final prefix = source.substring(results.replacementOffset, location.offset);
suggestions = suggestions.where((suggestion) {
return suggestion.completion
.toLowerCase()
.startsWith(prefix.toLowerCase());
}).where((CompletionSuggestion suggestion) {
// We do not want to enable arbitrary discovery of file system resources.
// In order to avoid returning local file paths, we only allow returning
// IMPORT kinds that are dart: or package: imports.
if (suggestion.kind == 'IMPORT') {
final completion = suggestion.completion;
return completion.startsWith('dart:') ||
completion.startsWith('package:');
} else {
return true;
}
}).toList();
suggestions.sort((CompletionSuggestion x, CompletionSuggestion y) {
if (x.relevance == y.relevance) {
return x.completion.compareTo(y.completion);
} else {
return y.relevance.compareTo(x.relevance);
}
});
return proto.CompleteResponse()
..replacementOffset = results.replacementOffset
..replacementLength = results.replacementLength
..completions
.addAll(suggestions.map((CompletionSuggestion c) => proto.Completion()
..completion.addAll(c.toMap().map((key, value) {
// TODO: Properly support Lists, Maps (this is a hack).
if (value is Map || value is List) {
value = json.encode(value);
}
return MapEntry(key.toString(), value.toString());
}))));
}