Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b4d5dd7

Browse files
author
Dart CI
committed
Version 2.17.0-66.0.dev
Merge commit '7ad1786e45a8056269103576b05d0d4d69b38f13' into 'dev'
2 parents 1e9d438 + 7ad1786 commit b4d5dd7

File tree

10 files changed

+376
-413
lines changed

10 files changed

+376
-413
lines changed

pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart

Lines changed: 125 additions & 217 deletions
Large diffs are not rendered by default.

pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart

Lines changed: 75 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ import 'package:analyzer_plugin/protocol/protocol_common.dart';
3131
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
3232
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
3333

34-
class CompletionHandler
35-
extends MessageHandler<CompletionParams, List<CompletionItem>>
34+
class CompletionHandler extends MessageHandler<CompletionParams, CompletionList>
3635
with LspPluginRequestHandlerMixin {
36+
/// Whether to include symbols from libraries that have not been imported.
3737
final bool suggestFromUnimportedLibraries;
38-
CompletionHandler(
39-
LspAnalysisServer server, this.suggestFromUnimportedLibraries)
40-
: super(server);
38+
39+
CompletionHandler(LspAnalysisServer server, LspInitializationOptions options)
40+
: suggestFromUnimportedLibraries = options.suggestFromUnimportedLibraries,
41+
super(server);
4142

4243
@override
4344
Method get handlesMessage => Method.textDocument_completion;
@@ -47,7 +48,7 @@ class CompletionHandler
4748
CompletionParams.jsonHandler;
4849

4950
@override
50-
Future<ErrorOr<List<CompletionItem>>> handle(
51+
Future<ErrorOr<CompletionList>> handle(
5152
CompletionParams params, CancellationToken token) async {
5253
final clientCapabilities = server.clientCapabilities;
5354
if (clientCapabilities == null) {
@@ -56,9 +57,6 @@ class CompletionHandler
5657
'Requests not before server is initilized');
5758
}
5859

59-
final includeSuggestionSets =
60-
suggestFromUnimportedLibraries && clientCapabilities.applyEdit;
61-
6260
final triggerCharacter = params.context?.triggerCharacter;
6361
final pos = params.position;
6462
final path = pathOfDoc(params.textDocument);
@@ -75,14 +73,13 @@ class CompletionHandler
7573
await lineInfo.mapResult((lineInfo) => toOffset(lineInfo, pos));
7674

7775
return offset.mapResult((offset) async {
78-
Future<ErrorOr<List<CompletionItem>>>? serverResultsFuture;
76+
Future<ErrorOr<CompletionList>>? serverResultsFuture;
7977
final pathContext = server.resourceProvider.pathContext;
8078
final fileExtension = pathContext.extension(path.result);
8179

8280
if (fileExtension == '.dart' && !unit.isError) {
8381
serverResultsFuture = _getServerDartItems(
8482
clientCapabilities,
85-
includeSuggestionSets,
8683
unit.result,
8784
offset,
8885
triggerCharacter,
@@ -110,7 +107,8 @@ class CompletionHandler
110107
}
111108
}
112109

113-
serverResultsFuture ??= Future.value(success(const <CompletionItem>[]));
110+
serverResultsFuture ??=
111+
Future.value(success(CompletionList(isIncomplete: false, items: [])));
114112

115113
final pluginResultsFuture = _getPluginResults(
116114
clientCapabilities, lineInfo.result, path.result, offset);
@@ -125,9 +123,15 @@ class CompletionHandler
125123
if (serverResults.isError) return serverResults;
126124
if (pluginResults.isError) return pluginResults;
127125

128-
return success(
129-
serverResults.result.followedBy(pluginResults.result).toList(),
130-
);
126+
return success(CompletionList(
127+
// If any set of the results is incomplete, the whole batch must be
128+
// marked as such.
129+
isIncomplete: serverResults.result.isIncomplete ||
130+
pluginResults.result.isIncomplete,
131+
items: serverResults.result.items
132+
.followedBy(pluginResults.result.items)
133+
.toList(),
134+
));
131135
});
132136
}
133137

@@ -174,7 +178,7 @@ class CompletionHandler
174178
String _createImportedSymbolKey(String name, Uri declaringUri) =>
175179
'$name/$declaringUri';
176180

177-
Future<ErrorOr<List<CompletionItem>>> _getPluginResults(
181+
Future<ErrorOr<CompletionList>> _getPluginResults(
178182
LspClientCapabilities capabilities,
179183
LineInfo lineInfo,
180184
String path,
@@ -188,22 +192,27 @@ class CompletionHandler
188192
.map((e) => plugin.CompletionGetSuggestionsResult.fromResponse(e))
189193
.toList();
190194

191-
return success(_pluginResultsToItems(
192-
capabilities,
193-
lineInfo,
194-
offset,
195-
pluginResults,
196-
).toList());
195+
return success(CompletionList(
196+
isIncomplete: false,
197+
items: _pluginResultsToItems(
198+
capabilities,
199+
lineInfo,
200+
offset,
201+
pluginResults,
202+
).toList(),
203+
));
197204
}
198205

199-
Future<ErrorOr<List<CompletionItem>>> _getServerDartItems(
206+
Future<ErrorOr<CompletionList>> _getServerDartItems(
200207
LspClientCapabilities capabilities,
201-
bool includeSuggestionSets,
202208
ResolvedUnitResult unit,
203209
int offset,
204210
String? triggerCharacter,
205211
CancellationToken token,
206212
) async {
213+
final useSuggestionSets =
214+
suggestFromUnimportedLibraries && capabilities.applyEdit;
215+
207216
var performance = OperationPerformanceImpl('<root>');
208217
return await performance.runAsync(
209218
'request',
@@ -226,14 +235,14 @@ class CompletionHandler
226235

227236
if (triggerCharacter != null) {
228237
if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
229-
return success([]);
238+
return success(CompletionList(isIncomplete: false, items: []));
230239
}
231240
}
232241

233242
Set<ElementKind>? includedElementKinds;
234243
Set<String>? includedElementNames;
235244
List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
236-
if (includeSuggestionSets) {
245+
if (useSuggestionSets) {
237246
includedElementKinds = <ElementKind>{};
238247
includedElementNames = <String>{};
239248
includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
@@ -284,18 +293,22 @@ class CompletionHandler
284293
offset, itemReplacementOffset, itemInsertLength);
285294
}
286295

296+
// Convert to LSP ranges using the LineInfo.
297+
Range? replacementRange = toRange(
298+
unit.lineInfo, itemReplacementOffset, itemReplacementLength);
299+
Range? insertionRange = toRange(
300+
unit.lineInfo, itemReplacementOffset, itemInsertLength);
301+
287302
return toCompletionItem(
288303
capabilities,
289304
unit.lineInfo,
290305
item,
291-
itemReplacementOffset,
292-
itemInsertLength,
293-
itemReplacementLength,
294-
// TODO(dantup): Including commit characters in every completion
295-
// increases the payload size. The LSP spec is ambigious
296-
// about how this should be handled (and VS Code requires it) but
297-
// this should be removed (or made conditional based on a capability)
298-
// depending on how the spec is updated.
306+
replacementRange: replacementRange,
307+
insertionRange: insertionRange,
308+
// TODO(dantup): Move commit characters to the main response
309+
// and remove from each individual item (to reduce payload size)
310+
// once the following change ships (and the Dart VS Code
311+
// extension is updated to use it).
299312
// https://github.com/microsoft/vscode-languageserver-node/issues/673
300313
includeCommitCharacters:
301314
server.clientConfiguration.global.previewCommitCharacters,
@@ -390,11 +403,10 @@ class CompletionHandler
390403
completionRequest.replacementOffset,
391404
insertLength,
392405
completionRequest.replacementLength,
393-
// TODO(dantup): Including commit characters in every completion
394-
// increases the payload size. The LSP spec is ambigious
395-
// about how this should be handled (and VS Code requires it) but
396-
// this should be removed (or made conditional based on a capability)
397-
// depending on how the spec is updated.
406+
// TODO(dantup): Move commit characters to the main response
407+
// and remove from each individual item (to reduce payload size)
408+
// once the following change ships (and the Dart VS Code
409+
// extension is updated to use it).
398410
// https://github.com/microsoft/vscode-languageserver-node/issues/673
399411
includeCommitCharacters: server
400412
.clientConfiguration.global.previewCommitCharacters,
@@ -415,15 +427,16 @@ class CompletionHandler
415427

416428
completionPerformance.suggestionCount = results.length;
417429

418-
return success(matchingResults);
430+
return success(
431+
CompletionList(isIncomplete: false, items: matchingResults));
419432
} on AbortCompletion {
420-
return success([]);
433+
return success(CompletionList(isIncomplete: false, items: []));
421434
}
422435
},
423436
);
424437
}
425438

426-
Future<ErrorOr<List<CompletionItem>>> _getServerYamlItems(
439+
Future<ErrorOr<CompletionList>> _getServerYamlItems(
427440
YamlCompletionGenerator generator,
428441
LspClientCapabilities capabilities,
429442
String path,
@@ -437,23 +450,25 @@ class CompletionHandler
437450
suggestions.replacementOffset,
438451
suggestions.replacementLength,
439452
);
453+
final replacementRange = toRange(
454+
lineInfo, suggestions.replacementOffset, suggestions.replacementLength);
455+
final insertionRange =
456+
toRange(lineInfo, suggestions.replacementOffset, insertLength);
457+
440458
final completionItems = suggestions.suggestions
441459
.map(
442460
(item) => toCompletionItem(
443461
capabilities,
444462
lineInfo,
445463
item,
446-
suggestions.replacementOffset,
447-
insertLength,
448-
suggestions.replacementLength,
464+
replacementRange: replacementRange,
465+
insertionRange: insertionRange,
449466
includeCommitCharacters: false,
450467
completeFunctionCalls: false,
451468
// Add on any completion-kind-specific resolution data that will be
452469
// used during resolve() calls to provide additional information.
453470
resolutionData: item.kind == CompletionSuggestionKind.PACKAGE_NAME
454471
? PubPackageCompletionItemResolutionInfo(
455-
file: path,
456-
offset: offset,
457472
// The completion for package names may contain a trailing
458473
// ': ' for convenience, so if it's there, trim it off.
459474
packageName: item.completion.split(':').first,
@@ -462,7 +477,7 @@ class CompletionHandler
462477
),
463478
)
464479
.toList();
465-
return success(completionItems);
480+
return success(CompletionList(isIncomplete: false, items: completionItems));
466481
}
467482

468483
/// Returns true if [node] is part of an invocation and already has an argument
@@ -495,18 +510,23 @@ class CompletionHandler
495510
List<plugin.CompletionGetSuggestionsResult> pluginResults,
496511
) {
497512
return pluginResults.expand((result) {
513+
final insertLength = _computeInsertLength(
514+
offset,
515+
result.replacementOffset,
516+
result.replacementLength,
517+
);
518+
final replacementRange =
519+
toRange(lineInfo, result.replacementOffset, result.replacementLength);
520+
final insertionRange =
521+
toRange(lineInfo, result.replacementOffset, insertLength);
522+
498523
return result.results.map(
499524
(item) => toCompletionItem(
500525
capabilities,
501526
lineInfo,
502527
item,
503-
result.replacementOffset,
504-
_computeInsertLength(
505-
offset,
506-
result.replacementOffset,
507-
result.replacementLength,
508-
),
509-
result.replacementLength,
528+
replacementRange: replacementRange,
529+
insertionRange: insertionRange,
510530
// Plugins cannot currently contribute commit characters and we should
511531
// not assume that the Dart ones would be correct for all of their
512532
// completions.

0 commit comments

Comments
 (0)