blob: 2a2039af4d62bb061cb20a8f6371545ef614214b [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
/// Wraps the client (editor) capabilities to improve performance.
///
/// Sets transferred as arrays in JSON will be converted to Sets for faster
/// lookups and default values and nulls will be handled here.
class LspClientCapabilities {
/// If the client does not provide capabilities.completion.completionItemKind.valueSet
/// then we must never send a kind that's not in this list.
static final Set<CompletionItemKind> defaultSupportedCompletionKinds = {
CompletionItemKind.Text,
CompletionItemKind.Method,
CompletionItemKind.Function,
CompletionItemKind.Constructor,
CompletionItemKind.Field,
CompletionItemKind.Variable,
CompletionItemKind.Class,
CompletionItemKind.Interface,
CompletionItemKind.Module,
CompletionItemKind.Property,
CompletionItemKind.Unit,
CompletionItemKind.Value,
CompletionItemKind.Enum,
CompletionItemKind.Keyword,
CompletionItemKind.Snippet,
CompletionItemKind.Color,
CompletionItemKind.File,
CompletionItemKind.Reference,
};
/// If the client does not provide capabilities.documentSymbol.symbolKind.valueSet
/// then we must never send a kind that's not in this list.
static final Set<SymbolKind> defaultSupportedSymbolKinds = {
SymbolKind.File,
SymbolKind.Module,
SymbolKind.Namespace,
SymbolKind.Package,
SymbolKind.Class,
SymbolKind.Method,
SymbolKind.Property,
SymbolKind.Field,
SymbolKind.Constructor,
SymbolKind.Enum,
SymbolKind.Interface,
SymbolKind.Function,
SymbolKind.Variable,
SymbolKind.Constant,
SymbolKind.Str,
SymbolKind.Number,
SymbolKind.Boolean,
SymbolKind.Array,
};
final ClientCapabilities raw;
final bool documentChanges;
final bool configuration;
final bool createResourceOperations;
final bool completionDeprecatedFlag;
final bool applyEdit;
final bool workDoneProgress;
final bool completionSnippets;
final bool renameValidation;
final bool literalCodeActions;
final bool insertReplaceCompletionRanges;
final bool definitionLocationLink;
final bool hierarchicalSymbols;
final Set<CodeActionKind> codeActionKinds;
final Set<CompletionItemTag> completionItemTags;
final Set<DiagnosticTag> diagnosticTags;
final Set<MarkupKind> completionDocumentationFormats;
final Set<MarkupKind> signatureHelpDocumentationFormats;
final Set<MarkupKind> hoverContentFormats;
final Set<SymbolKind> documentSymbolKinds;
final Set<SymbolKind> workspaceSymbolKinds;
final Set<CompletionItemKind> completionItemKinds;
final Set<InsertTextMode> completionInsertTextModes;
final bool experimentalSnippetTextEdit;
LspClientCapabilities(this.raw)
: applyEdit = raw?.workspace?.applyEdit ?? false,
codeActionKinds = _listToSet(raw?.textDocument?.codeAction
?.codeActionLiteralSupport?.codeActionKind?.valueSet),
completionDeprecatedFlag =
raw.textDocument?.completion?.completionItem?.deprecatedSupport ??
false,
completionDocumentationFormats = _completionDocumentationFormats(raw),
completionInsertTextModes = _listToSet(raw.textDocument?.completion
?.completionItem?.insertTextModeSupport?.valueSet),
completionItemKinds = _listToSet(
raw?.textDocument?.completion?.completionItemKind?.valueSet,
defaults: defaultSupportedCompletionKinds),
completionSnippets =
raw.textDocument?.completion?.completionItem?.snippetSupport ??
false,
configuration = raw?.workspace?.configuration ?? false,
createResourceOperations = raw
?.workspace?.workspaceEdit?.resourceOperations
?.contains(ResourceOperationKind.Create) ??
false,
definitionLocationLink =
raw?.textDocument?.definition?.linkSupport ?? false,
completionItemTags = _listToSet(raw
?.textDocument?.completion?.completionItem?.tagSupport?.valueSet),
diagnosticTags = _listToSet(
raw?.textDocument?.publishDiagnostics?.tagSupport?.valueSet),
documentChanges =
raw?.workspace?.workspaceEdit?.documentChanges ?? false,
documentSymbolKinds = _listToSet(
raw?.textDocument?.documentSymbol?.symbolKind?.valueSet,
defaults: defaultSupportedSymbolKinds),
hierarchicalSymbols = raw?.textDocument?.documentSymbol
?.hierarchicalDocumentSymbolSupport ??
false,
hoverContentFormats = _hoverContentFormats(raw),
insertReplaceCompletionRanges = raw?.textDocument?.completion
?.completionItem?.insertReplaceSupport ??
false,
literalCodeActions =
raw?.textDocument?.codeAction?.codeActionLiteralSupport != null,
renameValidation = raw.textDocument?.rename?.prepareSupport ?? false,
signatureHelpDocumentationFormats = _sigHelpDocumentationFormats(raw),
workDoneProgress = raw.window?.workDoneProgress ?? false,
workspaceSymbolKinds = _listToSet(
raw?.workspace?.symbol?.symbolKind?.valueSet,
defaults: defaultSupportedSymbolKinds),
experimentalSnippetTextEdit =
raw.experimental is Map<String, dynamic> &&
raw.experimental['snippetTextEdit'] == true;
static Set<MarkupKind> _completionDocumentationFormats(
ClientCapabilities raw) {
// For formats, null is valid (which means only raw strings are supported,
// not [MarkupContent]), so use null as default.
return _listToSet(
raw?.textDocument?.completion?.completionItem?.documentationFormat,
defaults: null);
}
static Set<MarkupKind> _hoverContentFormats(ClientCapabilities raw) {
// For formats, null is valid (which means only raw strings are supported,
// not [MarkupContent]), so use null as default.
return _listToSet(raw?.textDocument?.hover?.contentFormat, defaults: null);
}
/// Converts a list to a `Set`, returning [defaults] if the list is null.
///
/// If [defaults] is not supplied, will return an empty set.
static Set<T> _listToSet<T>(List<T> items, {Set<T> defaults = const {}}) {
return items != null ? {...items} : defaults;
}
static Set<MarkupKind> _sigHelpDocumentationFormats(ClientCapabilities raw) {
// For formats, null is valid (which means only raw strings are supported,
// not [MarkupContent]), so use null as default.
return _listToSet(
raw?.textDocument?.signatureHelp?.signatureInformation
?.documentationFormat,
defaults: null);
}
}