Add support for LSP CompletionItemTags

Change-Id: I40b30e8e442913d20bccd53d4b96c2b60fb81190
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154467
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Danny Tuppeny <danny@tuppeny.com>
This commit is contained in:
Danny Tuppeny 2020-07-15 17:12:14 +00:00 committed by commit-bot@chromium.org
parent 084f9faf81
commit cf89c2e2cb
4 changed files with 72 additions and 13 deletions

View file

@ -150,7 +150,7 @@ class CompletionResolveHandler
return success(CompletionItem(
label: item.label,
kind: item.kind,
tags: null, // TODO(dantup): CompletionItemTags (eg. deprecated)
tags: item.tags,
detail: data.displayUri != null && thisFilesChanges.isNotEmpty
? "Auto import from '${data.displayUri}'\n\n${item.detail ?? ''}"
.trim()

View file

@ -224,8 +224,12 @@ lsp.CompletionItem declarationToCompletionItem(
label = declaration.name;
}
final useDeprecated =
final supportsDeprecatedFlag =
completionCapabilities?.completionItem?.deprecatedSupport == true;
final supportedTags =
completionCapabilities?.completionItem?.tagSupport?.valueSet ?? const [];
final supportsDeprecatedTag =
supportedTags.contains(lsp.CompletionItemTag.Deprecated);
final completionKind = declarationKindToCompletionItemKind(
supportedCompletionItemKinds, declaration.kind);
@ -243,10 +247,16 @@ lsp.CompletionItem declarationToCompletionItem(
return lsp.CompletionItem(
label: label,
kind: completionKind,
tags: null, // TODO(dantup): CompletionItemTags
detail: getDeclarationCompletionDetail(
declaration, completionKind, useDeprecated),
deprecated: useDeprecated && declaration.isDeprecated ? true : null,
tags: supportedTags.isNotEmpty
? [
if (supportsDeprecatedTag && declaration.isDeprecated)
lsp.CompletionItemTag.Deprecated
]
: null,
detail: getDeclarationCompletionDetail(declaration, completionKind,
supportsDeprecatedFlag || supportsDeprecatedTag),
deprecated:
supportsDeprecatedFlag && declaration.isDeprecated ? true : null,
// Relevance is a number, highest being best. LSP does text sort so subtract
// from a large number so that a text sort will result in the correct order.
// 555 -> 999455
@ -723,8 +733,12 @@ lsp.CompletionItem toCompletionItem(
}
}
final useDeprecated =
final supportsDeprecatedFlag =
completionCapabilities?.completionItem?.deprecatedSupport == true;
final supportedTags =
completionCapabilities?.completionItem?.tagSupport?.valueSet ?? const [];
final supportsDeprecatedTag =
supportedTags.contains(lsp.CompletionItemTag.Deprecated);
final formats = completionCapabilities?.completionItem?.documentationFormat;
final supportsSnippets =
completionCapabilities?.completionItem?.snippetSupport == true;
@ -751,11 +765,17 @@ lsp.CompletionItem toCompletionItem(
return lsp.CompletionItem(
label: label,
kind: completionKind,
tags: null, // TODO(dantup): CompletionItemTags
detail: getCompletionDetail(suggestion, completionKind, useDeprecated),
tags: supportedTags.isNotEmpty
? [
if (supportsDeprecatedTag && suggestion.isDeprecated)
lsp.CompletionItemTag.Deprecated
]
: null,
detail: getCompletionDetail(suggestion, completionKind,
supportsDeprecatedFlag || supportsDeprecatedTag),
documentation:
asStringOrMarkupContent(formats, cleanDartdoc(suggestion.docComplete)),
deprecated: useDeprecated && suggestion.isDeprecated ? true : null,
deprecated: supportsDeprecatedFlag && suggestion.isDeprecated ? true : null,
// Relevance is a number, highest being best. LSP does text sort so subtract
// from a large number so that a text sort will result in the correct order.
// 555 -> 999455

View file

@ -300,7 +300,7 @@ class CompletionTest extends AbstractLspAnalysisServerTest {
expect(item.detail.toLowerCase(), contains('deprecated'));
}
Future<void> test_isDeprecated_supported() async {
Future<void> test_isDeprecated_supportedFlag() async {
final content = '''
class MyClass {
@deprecated
@ -314,7 +314,7 @@ class CompletionTest extends AbstractLspAnalysisServerTest {
''';
await initialize(
textDocumentCapabilities: withCompletionItemDeprecatedSupport(
textDocumentCapabilities: withCompletionItemDeprecatedFlagSupport(
emptyTextDocumentClientCapabilities));
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
@ -326,6 +326,32 @@ class CompletionTest extends AbstractLspAnalysisServerTest {
expect(item.detail, isNot(contains('deprecated')));
}
Future<void> test_isDeprecated_supportedTag() async {
final content = '''
class MyClass {
@deprecated
String abcdefghij;
}
main() {
MyClass a;
a.abc^
}
''';
await initialize(
textDocumentCapabilities: withCompletionItemTagSupport(
emptyTextDocumentClientCapabilities,
[CompletionItemTag.Deprecated]));
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
final item = res.singleWhere((c) => c.label == 'abcdefghij');
expect(item.tags, contains(CompletionItemTag.Deprecated));
// If the client says it supports the deprecated tag, we should not show
// deprecated in the details.
expect(item.detail, isNot(contains('deprecated')));
}
Future<void> test_namedArg_plainText() async {
final content = '''
class A { const A({int one}); }

View file

@ -227,7 +227,7 @@ mixin ClientCapabilitiesHelperMixin {
});
}
TextDocumentClientCapabilities withCompletionItemDeprecatedSupport(
TextDocumentClientCapabilities withCompletionItemDeprecatedFlagSupport(
TextDocumentClientCapabilities source,
) {
return extendTextDocumentCapabilities(source, {
@ -260,6 +260,19 @@ mixin ClientCapabilitiesHelperMixin {
});
}
TextDocumentClientCapabilities withCompletionItemTagSupport(
TextDocumentClientCapabilities source,
List<CompletionItemTag> tags,
) {
return extendTextDocumentCapabilities(source, {
'completion': {
'completionItem': {
'tagSupport': {'valueSet': tags.map((k) => k.toJson()).toList()}
}
}
});
}
ClientCapabilitiesWorkspace withConfigurationSupport(
ClientCapabilitiesWorkspace source,
) {