Skip to content

Commit 12fded6

Browse files
author
Dart CI
committed
Version 2.12.0-62.0.dev
Merge commit 'db263169e5b6f3e20d38e6933fa63497e52dcdda' into 'dev'
2 parents 15ef7d9 + db26316 commit 12fded6

File tree

89 files changed

+2230
-256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+2230
-256
lines changed

pkg/analysis_server/lib/src/domain_completion.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import 'package:analysis_server/src/services/completion/token_details/token_deta
2020
import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
2121
import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
2222
import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
23+
import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
2324
import 'package:analyzer/dart/analysis/results.dart';
2425
import 'package:analyzer/dart/analysis/session.dart';
2526
import 'package:analyzer/exception/exception.dart';
@@ -150,7 +151,7 @@ class CompletionDomainHandler extends AbstractRequestHandler {
150151

151152
/// Return the suggestions that should be presented in the YAML [file] at the
152153
/// given [offset].
153-
List<CompletionSuggestion> computeYamlSuggestions(String file, int offset) {
154+
YamlCompletionResults computeYamlSuggestions(String file, int offset) {
154155
var provider = server.resourceProvider;
155156
if (AnalysisEngine.isAnalysisOptionsFileName(file)) {
156157
var generator = AnalysisOptionsGenerator(provider);
@@ -164,7 +165,7 @@ class CompletionDomainHandler extends AbstractRequestHandler {
164165
var generator = FixDataGenerator(provider);
165166
return generator.getSuggestions(file, offset);
166167
}
167-
return <CompletionSuggestion>[];
168+
return const YamlCompletionResults.empty();
168169
}
169170

170171
/// Process a `completion.getSuggestionDetails` request.
@@ -325,11 +326,12 @@ class CompletionDomainHandler extends AbstractRequestHandler {
325326
server.sendResponse(CompletionGetSuggestionsResult(completionId)
326327
.toResponse(request.id));
327328
// Send a notification with results.
329+
final suggestions = computeYamlSuggestions(file, offset);
328330
sendCompletionNotification(
329331
completionId,
330-
0, // replacementOffset
331-
0, // replacementLength,
332-
computeYamlSuggestions(file, offset),
332+
suggestions.replacementOffset,
333+
suggestions.replacementLength,
334+
suggestions.suggestions,
333335
null,
334336
null,
335337
null,

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

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ import 'package:analysis_server/src/services/completion/completion_core.dart';
1616
import 'package:analysis_server/src/services/completion/completion_performance.dart';
1717
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
1818
import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
19+
import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
20+
import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
21+
import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
22+
import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
1923
import 'package:analyzer/dart/analysis/results.dart';
2024
import 'package:analyzer/source/line_info.dart';
25+
import 'package:analyzer/src/generated/engine.dart';
2126
import 'package:analyzer/src/services/available_declarations.dart';
2227
import 'package:analyzer_plugin/protocol/protocol_common.dart';
2328
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -89,18 +94,47 @@ class CompletionHandler
8994
await lineInfo.mapResult((lineInfo) => toOffset(lineInfo, pos));
9095

9196
return offset.mapResult((offset) async {
92-
// For server results we need a valid unit, but if we don't have one
93-
// we shouldn't consider this an error when merging with plugin results.
94-
final serverResultsFuture = unit.isError
95-
? Future.value(success(const <CompletionItem>[]))
96-
: _getServerItems(
97-
completionCapabilities,
98-
clientSupportedCompletionKinds,
99-
includeSuggestionSets,
100-
unit.result,
101-
offset,
102-
token,
103-
);
97+
Future<ErrorOr<List<CompletionItem>>> serverResultsFuture;
98+
final pathContext = server.resourceProvider.pathContext;
99+
final filename = pathContext.basename(path.result);
100+
final fileExtension = pathContext.extension(path.result);
101+
102+
if (fileExtension == '.dart' && !unit.isError) {
103+
serverResultsFuture = _getServerDartItems(
104+
completionCapabilities,
105+
clientSupportedCompletionKinds,
106+
includeSuggestionSets,
107+
unit.result,
108+
offset,
109+
token,
110+
);
111+
} else if (fileExtension == '.yaml') {
112+
YamlCompletionGenerator generator;
113+
switch (filename) {
114+
case AnalysisEngine.PUBSPEC_YAML_FILE:
115+
generator = PubspecGenerator(server.resourceProvider);
116+
break;
117+
case AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE:
118+
generator = AnalysisOptionsGenerator(server.resourceProvider);
119+
break;
120+
case AnalysisEngine.FIX_DATA_FILE:
121+
generator = FixDataGenerator(server.resourceProvider);
122+
break;
123+
}
124+
if (generator != null) {
125+
serverResultsFuture = _getServerYamlItems(
126+
generator,
127+
completionCapabilities,
128+
clientSupportedCompletionKinds,
129+
path.result,
130+
lineInfo.result,
131+
offset,
132+
token,
133+
);
134+
}
135+
}
136+
137+
serverResultsFuture ??= Future.value(success(const <CompletionItem>[]));
104138

105139
final pluginResultsFuture = _getPluginResults(completionCapabilities,
106140
clientSupportedCompletionKinds, lineInfo.result, path.result, offset);
@@ -175,7 +209,7 @@ class CompletionHandler
175209
).toList());
176210
}
177211

178-
Future<ErrorOr<List<CompletionItem>>> _getServerItems(
212+
Future<ErrorOr<List<CompletionItem>>> _getServerDartItems(
179213
CompletionClientCapabilities completionCapabilities,
180214
HashSet<CompletionItemKind> clientSupportedCompletionKinds,
181215
bool includeSuggestionSets,
@@ -355,6 +389,33 @@ class CompletionHandler
355389
});
356390
}
357391

392+
Future<ErrorOr<List<CompletionItem>>> _getServerYamlItems(
393+
YamlCompletionGenerator generator,
394+
CompletionClientCapabilities completionCapabilities,
395+
HashSet<CompletionItemKind> clientSupportedCompletionKinds,
396+
String path,
397+
LineInfo lineInfo,
398+
int offset,
399+
CancellationToken token,
400+
) async {
401+
final suggestions = generator.getSuggestions(path, offset);
402+
final completionItems = suggestions.suggestions
403+
.map(
404+
(item) => toCompletionItem(
405+
completionCapabilities,
406+
clientSupportedCompletionKinds,
407+
lineInfo,
408+
item,
409+
suggestions.replacementOffset,
410+
suggestions.replacementLength,
411+
includeCommitCharacters: false,
412+
completeFunctionCalls: false,
413+
),
414+
)
415+
.toList();
416+
return success(completionItems);
417+
}
418+
358419
Iterable<CompletionItem> _pluginResultsToItems(
359420
CompletionClientCapabilities completionCapabilities,
360421
HashSet<CompletionItemKind> clientSupportedCompletionKinds,

pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,25 @@ class ServerCapabilitiesComputer {
242242
// folders as well.
243243
.map((glob) => DocumentFilter(scheme: 'file', pattern: '**/$glob'));
244244

245-
final allTypes = {dartFiles, ...pluginTypes}.toList();
245+
final fullySupportedTypes = {dartFiles, ...pluginTypes}.toList();
246246

247247
// Add pubspec + analysis options only for synchronisation. We do not support
248248
// things like hovers/formatting/etc. for these files so there's no point
249249
// in having the client send those requests (plus, for things like formatting
250250
// this could result in the editor reporting "multiple formatters installed"
251251
// and prevent a built-in YAML formatter from being selected).
252-
final allSynchronisedTypes = {
253-
...allTypes,
252+
final synchronisedTypes = {
253+
...fullySupportedTypes,
254+
pubspecFile,
255+
analysisOptionsFile,
256+
fixDataFile,
257+
}.toList();
258+
259+
// Completion is supported for some synchronised files that we don't _fully_
260+
// support (eg. YAML). If these gain support for things like hover, we may
261+
// wish to move them to fullySupprtedTypes but add an exclusion for formatting.
262+
final completionSupportedTypes = {
263+
...fullySupportedTypes,
254264
pubspecFile,
255265
analysisOptionsFile,
256266
fixDataFile,
@@ -278,25 +288,25 @@ class ServerCapabilitiesComputer {
278288
register(
279289
dynamicRegistrations.textSync,
280290
Method.textDocument_didOpen,
281-
TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
291+
TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
282292
);
283293
register(
284294
dynamicRegistrations.textSync,
285295
Method.textDocument_didClose,
286-
TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
296+
TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
287297
);
288298
register(
289299
dynamicRegistrations.textSync,
290300
Method.textDocument_didChange,
291301
TextDocumentChangeRegistrationOptions(
292302
syncKind: TextDocumentSyncKind.Incremental,
293-
documentSelector: allSynchronisedTypes),
303+
documentSelector: synchronisedTypes),
294304
);
295305
register(
296306
dynamicRegistrations.completion,
297307
Method.textDocument_completion,
298308
CompletionRegistrationOptions(
299-
documentSelector: allTypes,
309+
documentSelector: completionSupportedTypes,
300310
triggerCharacters: dartCompletionTriggerCharacters,
301311
allCommitCharacters:
302312
previewCommitCharacters ? dartCompletionCommitCharacters : null,
@@ -306,36 +316,36 @@ class ServerCapabilitiesComputer {
306316
register(
307317
dynamicRegistrations.hover,
308318
Method.textDocument_hover,
309-
TextDocumentRegistrationOptions(documentSelector: allTypes),
319+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
310320
);
311321
register(
312322
dynamicRegistrations.signatureHelp,
313323
Method.textDocument_signatureHelp,
314324
SignatureHelpRegistrationOptions(
315-
documentSelector: allTypes,
325+
documentSelector: fullySupportedTypes,
316326
triggerCharacters: dartSignatureHelpTriggerCharacters,
317327
retriggerCharacters: dartSignatureHelpRetriggerCharacters,
318328
),
319329
);
320330
register(
321331
dynamicRegistrations.references,
322332
Method.textDocument_references,
323-
TextDocumentRegistrationOptions(documentSelector: allTypes),
333+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
324334
);
325335
register(
326336
dynamicRegistrations.documentHighlights,
327337
Method.textDocument_documentHighlight,
328-
TextDocumentRegistrationOptions(documentSelector: allTypes),
338+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
329339
);
330340
register(
331341
dynamicRegistrations.documentSymbol,
332342
Method.textDocument_documentSymbol,
333-
TextDocumentRegistrationOptions(documentSelector: allTypes),
343+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
334344
);
335345
register(
336346
enableFormatter && dynamicRegistrations.formatting,
337347
Method.textDocument_formatting,
338-
TextDocumentRegistrationOptions(documentSelector: allTypes),
348+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
339349
);
340350
register(
341351
enableFormatter && dynamicRegistrations.typeFormatting,
@@ -356,31 +366,31 @@ class ServerCapabilitiesComputer {
356366
register(
357367
dynamicRegistrations.definition,
358368
Method.textDocument_definition,
359-
TextDocumentRegistrationOptions(documentSelector: allTypes),
369+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
360370
);
361371
register(
362372
dynamicRegistrations.implementation,
363373
Method.textDocument_implementation,
364-
TextDocumentRegistrationOptions(documentSelector: allTypes),
374+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
365375
);
366376
register(
367377
dynamicRegistrations.codeActions,
368378
Method.textDocument_codeAction,
369379
CodeActionRegistrationOptions(
370-
documentSelector: allTypes,
380+
documentSelector: fullySupportedTypes,
371381
codeActionKinds: DartCodeActionKind.serverSupportedKinds,
372382
),
373383
);
374384
register(
375385
dynamicRegistrations.rename,
376386
Method.textDocument_rename,
377387
RenameRegistrationOptions(
378-
documentSelector: allTypes, prepareProvider: true),
388+
documentSelector: fullySupportedTypes, prepareProvider: true),
379389
);
380390
register(
381391
dynamicRegistrations.folding,
382392
Method.textDocument_foldingRange,
383-
TextDocumentRegistrationOptions(documentSelector: allTypes),
393+
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
384394
);
385395
register(
386396
dynamicRegistrations.didChangeConfiguration,

pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ abstract class YamlCompletionGenerator {
2424

2525
/// Return the completion suggestions appropriate for the given [offset] in
2626
/// the file at the given [filePath].
27-
List<CompletionSuggestion> getSuggestions(String filePath, int offset) {
27+
YamlCompletionResults getSuggestions(String filePath, int offset) {
2828
var file = resourceProvider.getFile(filePath);
2929
String content;
3030
try {
3131
content = file.readAsStringSync();
3232
} on FileSystemException {
3333
// If the file doesn't exist or can't be read, then there are no
3434
// suggestions.
35-
return const <CompletionSuggestion>[];
35+
return const YamlCompletionResults.empty();
3636
}
3737
var root = _parseYaml(content);
3838
if (root == null) {
3939
// If the contents can't be parsed, then there are no suggestions.
40-
return const <CompletionSuggestion>[];
40+
return const YamlCompletionResults.empty();
4141
}
4242
var path = _pathToOffset(root, offset);
4343
var completionNode = path.last;
@@ -52,17 +52,16 @@ abstract class YamlCompletionGenerator {
5252
return getSuggestionsForPath(path, offset);
5353
}
5454
// There are no completions at the given location.
55-
return const <CompletionSuggestion>[];
55+
return const YamlCompletionResults.empty();
5656
}
5757

5858
/// Given a [path] to the node in which completions are being requested and
5959
/// the offset of the cursor, return the completions appropriate at that
6060
/// location.
61-
List<CompletionSuggestion> getSuggestionsForPath(
62-
List<YamlNode> path, int offset) {
61+
YamlCompletionResults getSuggestionsForPath(List<YamlNode> path, int offset) {
6362
var producer = _producerForPath(path);
6463
if (producer == null) {
65-
return const <CompletionSuggestion>[];
64+
return const YamlCompletionResults.empty();
6665
}
6766
var invalidSuggestions = _siblingsOnPath(path);
6867
var suggestions = <CompletionSuggestion>[];
@@ -71,7 +70,12 @@ abstract class YamlCompletionGenerator {
7170
suggestions.add(suggestion);
7271
}
7372
}
74-
return suggestions;
73+
final node = path.isNotEmpty ? path.last : null;
74+
final replaceNode = node is YamlScalar && node.containsOffset(offset);
75+
final replacementOffset = replaceNode ? node.span.start.offset : offset;
76+
final replacementLength = replaceNode ? node.span.length : 0;
77+
return YamlCompletionResults(
78+
suggestions, replacementOffset, replacementLength);
7579
}
7680

7781
/// Return the result of parsing the file [content] into a YAML node.
@@ -164,6 +168,20 @@ abstract class YamlCompletionGenerator {
164168
}
165169
}
166170

171+
class YamlCompletionResults {
172+
final List<CompletionSuggestion> suggestions;
173+
final int replacementOffset;
174+
final int replacementLength;
175+
176+
const YamlCompletionResults(
177+
this.suggestions, this.replacementOffset, this.replacementLength);
178+
179+
const YamlCompletionResults.empty()
180+
: suggestions = const [],
181+
replacementOffset = 0,
182+
replacementLength = 0;
183+
}
184+
167185
extension on YamlMap {
168186
/// Return the node representing the key that corresponds to the value
169187
/// represented by the [value] node.

0 commit comments

Comments
 (0)