From 4525525a9d66c499641fcbcac06f32e53a36a162 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 9 Dec 2020 20:29:30 +0000 Subject: [PATCH] [Analyzer] Handle parsing v3.16 LSP Spec Change-Id: I6afd5c32673ba580cdf6691bdfa521766f65c3b0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/158392 Commit-Queue: Brian Wilkerson Reviewed-by: Brian Wilkerson --- .../lib/lsp_protocol/protocol_generated.dart | 9751 ++++++++++++++++- .../lib/src/lsp/constants.dart | 15 +- .../commands/simple_edit_handler.dart | 2 +- .../custom/handler_diagnostic_server.dart | 2 +- .../handlers/custom/handler_reanalyze.dart | 2 +- .../lsp/handlers/custom/handler_super.dart | 2 +- .../lib/src/lsp/handlers/handler_rename.dart | 10 +- .../handler_text_document_changes.dart | 2 +- .../lib/src/lsp/lsp_analysis_server.dart | 18 +- pkg/analysis_server/lib/src/lsp/mapping.dart | 5 +- .../src/lsp/server_capabilities_computer.dart | 5 +- .../lib/src/lsp/source_edits.dart | 2 +- .../test/lsp/initialization_test.dart | 4 +- .../test/lsp/server_abstract.dart | 32 +- .../test/tool/lsp_spec/json_test.dart | 2 +- .../tool/lsp_spec/generate_all.dart | 2 +- .../tool/lsp_spec/lsp_specification.md | 3330 +++++- .../tool/lsp_spec/markdown.dart | 2 +- .../tool/lsp_spec/typescript.dart | 5 + .../tool/lsp_spec/typescript_parser.dart | 3 + 20 files changed, 12345 insertions(+), 851 deletions(-) diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart index 7b20e05a099..b8c93e52220 100644 --- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart +++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart @@ -26,6 +26,139 @@ import 'package:meta/meta.dart'; const jsonEncoder = JsonEncoder.withIndent(' '); +/// A special text edit with an additional change annotation. +/// @since 3.16.0 - proposed state. +class AnnotatedTextEdit implements TextEdit, ToJsonable { + static const jsonHandler = + LspJsonHandler(AnnotatedTextEdit.canParse, AnnotatedTextEdit.fromJson); + + AnnotatedTextEdit( + {@required this.annotationId, + @required this.range, + @required this.newText}) { + if (annotationId == null) { + throw 'annotationId is required but was not provided'; + } + if (range == null) { + throw 'range is required but was not provided'; + } + if (newText == null) { + throw 'newText is required but was not provided'; + } + } + static AnnotatedTextEdit fromJson(Map json) { + final annotationId = json['annotationId']; + final range = json['range'] != null ? Range.fromJson(json['range']) : null; + final newText = json['newText']; + return AnnotatedTextEdit( + annotationId: annotationId, range: range, newText: newText); + } + + /// The actual annotation identifier. + final String annotationId; + + /// The string to be inserted. For delete operations use an empty string. + final String newText; + + /// The range of the text document to be manipulated. To insert text into a + /// document create a range where start === end. + final Range range; + + Map toJson() { + var __result = {}; + __result['annotationId'] = + annotationId ?? (throw 'annotationId is required but was not set'); + __result['range'] = + range?.toJson() ?? (throw 'range is required but was not set'); + __result['newText'] = + newText ?? (throw 'newText is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('annotationId'); + try { + if (!obj.containsKey('annotationId')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['annotationId'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['annotationId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('range'); + try { + if (!obj.containsKey('range')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['range'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['range'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('newText'); + try { + if (!obj.containsKey('newText')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['newText'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['newText'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type AnnotatedTextEdit'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is AnnotatedTextEdit && other.runtimeType == AnnotatedTextEdit) { + return annotationId == other.annotationId && + range == other.range && + newText == other.newText && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, annotationId.hashCode); + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, newText.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ApplyWorkspaceEditParams implements ToJsonable { static const jsonHandler = LspJsonHandler( ApplyWorkspaceEditParams.canParse, ApplyWorkspaceEditParams.fromJson); @@ -119,7 +252,8 @@ class ApplyWorkspaceEditResponse implements ToJsonable { static const jsonHandler = LspJsonHandler( ApplyWorkspaceEditResponse.canParse, ApplyWorkspaceEditResponse.fromJson); - ApplyWorkspaceEditResponse({@required this.applied, this.failureReason}) { + ApplyWorkspaceEditResponse( + {@required this.applied, this.failureReason, this.failedChange}) { if (applied == null) { throw 'applied is required but was not provided'; } @@ -127,16 +261,25 @@ class ApplyWorkspaceEditResponse implements ToJsonable { static ApplyWorkspaceEditResponse fromJson(Map json) { final applied = json['applied']; final failureReason = json['failureReason']; + final failedChange = json['failedChange']; return ApplyWorkspaceEditResponse( - applied: applied, failureReason: failureReason); + applied: applied, + failureReason: failureReason, + failedChange: failedChange); } /// Indicates whether the edit was applied or not. final bool applied; + /// Depending on the client's failure handling strategy `failedChange` might + /// contain the index of the change that failed. This property is only + /// available if the client signals a `failureHandlingStrategy` in its client + /// capabilities. + final num failedChange; + /// An optional textual description for why the edit was not applied. This may - /// be used may be used by the server for diagnostic logging or to provide a - /// suitable error for a request that triggered the edit. + /// be used by the server for diagnostic logging or to provide a suitable + /// error for a request that triggered the edit. final String failureReason; Map toJson() { @@ -146,6 +289,9 @@ class ApplyWorkspaceEditResponse implements ToJsonable { if (failureReason != null) { __result['failureReason'] = failureReason; } + if (failedChange != null) { + __result['failedChange'] = failedChange; + } return __result; } @@ -177,6 +323,15 @@ class ApplyWorkspaceEditResponse implements ToJsonable { } finally { reporter.pop(); } + reporter.push('failedChange'); + try { + if (obj['failedChange'] != null && !(obj['failedChange'] is num)) { + reporter.reportError('must be of type num'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type ApplyWorkspaceEditResponse'); @@ -190,6 +345,7 @@ class ApplyWorkspaceEditResponse implements ToJsonable { other.runtimeType == ApplyWorkspaceEditResponse) { return applied == other.applied && failureReason == other.failureReason && + failedChange == other.failedChange && true; } return false; @@ -200,6 +356,1121 @@ class ApplyWorkspaceEditResponse implements ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, applied.hashCode); hash = JenkinsSmiHash.combine(hash, failureReason.hashCode); + hash = JenkinsSmiHash.combine(hash, failedChange.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyClientCapabilities.canParse, + CallHierarchyClientCapabilities.fromJson); + + CallHierarchyClientCapabilities({this.dynamicRegistration}); + static CallHierarchyClientCapabilities fromJson(Map json) { + final dynamicRegistration = json['dynamicRegistration']; + return CallHierarchyClientCapabilities( + dynamicRegistration: dynamicRegistration); + } + + /// Whether implementation supports dynamic registration. If this is set to + /// `true` the client supports the new `(TextDocumentRegistrationOptions & + /// StaticRegistrationOptions)` return value for the corresponding server + /// capability as well. + final bool dynamicRegistration; + + Map toJson() { + var __result = {}; + if (dynamicRegistration != null) { + __result['dynamicRegistration'] = dynamicRegistration; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('dynamicRegistration'); + try { + if (obj['dynamicRegistration'] != null && + !(obj['dynamicRegistration'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyClientCapabilities && + other.runtimeType == CallHierarchyClientCapabilities) { + return dynamicRegistration == other.dynamicRegistration && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyIncomingCall implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyIncomingCall.canParse, CallHierarchyIncomingCall.fromJson); + + CallHierarchyIncomingCall({@required this.from, @required this.fromRanges}) { + if (from == null) { + throw 'from is required but was not provided'; + } + if (fromRanges == null) { + throw 'fromRanges is required but was not provided'; + } + } + static CallHierarchyIncomingCall fromJson(Map json) { + final from = + json['from'] != null ? CallHierarchyItem.fromJson(json['from']) : null; + final fromRanges = json['fromRanges'] + ?.map((item) => item != null ? Range.fromJson(item) : null) + ?.cast() + ?.toList(); + return CallHierarchyIncomingCall(from: from, fromRanges: fromRanges); + } + + /// The item that makes the call. + final CallHierarchyItem from; + + /// The ranges at which the calls appear. This is relative to the caller + /// denoted by [`this.from`](#CallHierarchyIncomingCall.from). + final List fromRanges; + + Map toJson() { + var __result = {}; + __result['from'] = + from?.toJson() ?? (throw 'from is required but was not set'); + __result['fromRanges'] = + fromRanges ?? (throw 'fromRanges is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('from'); + try { + if (!obj.containsKey('from')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['from'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(CallHierarchyItem.canParse(obj['from'], reporter))) { + reporter.reportError('must be of type CallHierarchyItem'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('fromRanges'); + try { + if (!obj.containsKey('fromRanges')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['fromRanges'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['fromRanges'] is List && + (obj['fromRanges'] + .every((item) => Range.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyIncomingCall'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyIncomingCall && + other.runtimeType == CallHierarchyIncomingCall) { + return from == other.from && + listEqual( + fromRanges, other.fromRanges, (Range a, Range b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, from.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(fromRanges)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyIncomingCallsParams + implements WorkDoneProgressParams, PartialResultParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyIncomingCallsParams.canParse, + CallHierarchyIncomingCallsParams.fromJson); + + CallHierarchyIncomingCallsParams( + {@required this.item, this.workDoneToken, this.partialResultToken}) { + if (item == null) { + throw 'item is required but was not provided'; + } + } + static CallHierarchyIncomingCallsParams fromJson(Map json) { + final item = + json['item'] != null ? CallHierarchyItem.fromJson(json['item']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return CallHierarchyIncomingCallsParams( + item: item, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + final CallHierarchyItem item; + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['item'] = + item?.toJson() ?? (throw 'item is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('item'); + try { + if (!obj.containsKey('item')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['item'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(CallHierarchyItem.canParse(obj['item'], reporter))) { + reporter.reportError('must be of type CallHierarchyItem'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyIncomingCallsParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyIncomingCallsParams && + other.runtimeType == CallHierarchyIncomingCallsParams) { + return item == other.item && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, item.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyItem implements ToJsonable { + static const jsonHandler = + LspJsonHandler(CallHierarchyItem.canParse, CallHierarchyItem.fromJson); + + CallHierarchyItem( + {@required this.name, + @required this.kind, + this.tags, + this.detail, + @required this.uri, + @required this.range, + @required this.selectionRange, + this.data}) { + if (name == null) { + throw 'name is required but was not provided'; + } + if (kind == null) { + throw 'kind is required but was not provided'; + } + if (uri == null) { + throw 'uri is required but was not provided'; + } + if (range == null) { + throw 'range is required but was not provided'; + } + if (selectionRange == null) { + throw 'selectionRange is required but was not provided'; + } + } + static CallHierarchyItem fromJson(Map json) { + final name = json['name']; + final kind = + json['kind'] != null ? SymbolKind.fromJson(json['kind']) : null; + final tags = json['tags'] + ?.map((item) => item != null ? SymbolTag.fromJson(item) : null) + ?.cast() + ?.toList(); + final detail = json['detail']; + final uri = json['uri']; + final range = json['range'] != null ? Range.fromJson(json['range']) : null; + final selectionRange = json['selectionRange'] != null + ? Range.fromJson(json['selectionRange']) + : null; + final data = json['data']; + return CallHierarchyItem( + name: name, + kind: kind, + tags: tags, + detail: detail, + uri: uri, + range: range, + selectionRange: selectionRange, + data: data); + } + + /// A data entry field that is preserved between a call hierarchy prepare and + /// incoming calls or outgoing calls requests. + final dynamic data; + + /// More detail for this item, e.g. the signature of a function. + final String detail; + + /// The kind of this item. + final SymbolKind kind; + + /// The name of this item. + final String name; + + /// The range enclosing this symbol not including leading/trailing whitespace + /// but everything else, e.g. comments and code. + final Range range; + + /// The range that should be selected and revealed when this symbol is being + /// picked, e.g. the name of a function. Must be contained by the + /// [`range`](#CallHierarchyItem.range). + final Range selectionRange; + + /// Tags for this item. + final List tags; + + /// The resource identifier of this item. + final String uri; + + Map toJson() { + var __result = {}; + __result['name'] = name ?? (throw 'name is required but was not set'); + __result['kind'] = + kind?.toJson() ?? (throw 'kind is required but was not set'); + if (tags != null) { + __result['tags'] = tags; + } + if (detail != null) { + __result['detail'] = detail; + } + __result['uri'] = uri ?? (throw 'uri is required but was not set'); + __result['range'] = + range?.toJson() ?? (throw 'range is required but was not set'); + __result['selectionRange'] = selectionRange?.toJson() ?? + (throw 'selectionRange is required but was not set'); + if (data != null) { + __result['data'] = data; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('name'); + try { + if (!obj.containsKey('name')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['name'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['name'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('kind'); + try { + if (!obj.containsKey('kind')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['kind'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(SymbolKind.canParse(obj['kind'], reporter))) { + reporter.reportError('must be of type SymbolKind'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('tags'); + try { + if (obj['tags'] != null && + !((obj['tags'] is List && + (obj['tags'] + .every((item) => SymbolTag.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('detail'); + try { + if (obj['detail'] != null && !(obj['detail'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('uri'); + try { + if (!obj.containsKey('uri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['uri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['uri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('range'); + try { + if (!obj.containsKey('range')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['range'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['range'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('selectionRange'); + try { + if (!obj.containsKey('selectionRange')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['selectionRange'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['selectionRange'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('data'); + try { + if (obj['data'] != null && !(true)) { + reporter.reportError('must be of type dynamic'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyItem'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyItem && other.runtimeType == CallHierarchyItem) { + return name == other.name && + kind == other.kind && + listEqual(tags, other.tags, (SymbolTag a, SymbolTag b) => a == b) && + detail == other.detail && + uri == other.uri && + range == other.range && + selectionRange == other.selectionRange && + data == other.data && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, name.hashCode); + hash = JenkinsSmiHash.combine(hash, kind.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tags)); + hash = JenkinsSmiHash.combine(hash, detail.hashCode); + hash = JenkinsSmiHash.combine(hash, uri.hashCode); + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, selectionRange.hashCode); + hash = JenkinsSmiHash.combine(hash, data.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyOptions implements WorkDoneProgressOptions, ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyOptions.canParse, CallHierarchyOptions.fromJson); + + CallHierarchyOptions({this.workDoneProgress}); + static CallHierarchyOptions fromJson(Map json) { + if (CallHierarchyRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return CallHierarchyRegistrationOptions.fromJson(json); + } + final workDoneProgress = json['workDoneProgress']; + return CallHierarchyOptions(workDoneProgress: workDoneProgress); + } + + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyOptions && + other.runtimeType == CallHierarchyOptions) { + return workDoneProgress == other.workDoneProgress && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyOutgoingCall implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyOutgoingCall.canParse, CallHierarchyOutgoingCall.fromJson); + + CallHierarchyOutgoingCall({@required this.to, @required this.fromRanges}) { + if (to == null) { + throw 'to is required but was not provided'; + } + if (fromRanges == null) { + throw 'fromRanges is required but was not provided'; + } + } + static CallHierarchyOutgoingCall fromJson(Map json) { + final to = + json['to'] != null ? CallHierarchyItem.fromJson(json['to']) : null; + final fromRanges = json['fromRanges'] + ?.map((item) => item != null ? Range.fromJson(item) : null) + ?.cast() + ?.toList(); + return CallHierarchyOutgoingCall(to: to, fromRanges: fromRanges); + } + + /// The range at which this item is called. This is the range relative to the + /// caller, e.g the item passed to `callHierarchy/outgoingCalls` request. + final List fromRanges; + + /// The item that is called. + final CallHierarchyItem to; + + Map toJson() { + var __result = {}; + __result['to'] = to?.toJson() ?? (throw 'to is required but was not set'); + __result['fromRanges'] = + fromRanges ?? (throw 'fromRanges is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('to'); + try { + if (!obj.containsKey('to')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['to'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(CallHierarchyItem.canParse(obj['to'], reporter))) { + reporter.reportError('must be of type CallHierarchyItem'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('fromRanges'); + try { + if (!obj.containsKey('fromRanges')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['fromRanges'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['fromRanges'] is List && + (obj['fromRanges'] + .every((item) => Range.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyOutgoingCall'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyOutgoingCall && + other.runtimeType == CallHierarchyOutgoingCall) { + return to == other.to && + listEqual( + fromRanges, other.fromRanges, (Range a, Range b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, to.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(fromRanges)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyOutgoingCallsParams + implements WorkDoneProgressParams, PartialResultParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyOutgoingCallsParams.canParse, + CallHierarchyOutgoingCallsParams.fromJson); + + CallHierarchyOutgoingCallsParams( + {@required this.item, this.workDoneToken, this.partialResultToken}) { + if (item == null) { + throw 'item is required but was not provided'; + } + } + static CallHierarchyOutgoingCallsParams fromJson(Map json) { + final item = + json['item'] != null ? CallHierarchyItem.fromJson(json['item']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return CallHierarchyOutgoingCallsParams( + item: item, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + final CallHierarchyItem item; + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['item'] = + item?.toJson() ?? (throw 'item is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('item'); + try { + if (!obj.containsKey('item')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['item'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(CallHierarchyItem.canParse(obj['item'], reporter))) { + reporter.reportError('must be of type CallHierarchyItem'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyOutgoingCallsParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyOutgoingCallsParams && + other.runtimeType == CallHierarchyOutgoingCallsParams) { + return item == other.item && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, item.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyPrepareParams + implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyPrepareParams.canParse, CallHierarchyPrepareParams.fromJson); + + CallHierarchyPrepareParams( + {@required this.textDocument, + @required this.position, + this.workDoneToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + if (position == null) { + throw 'position is required but was not provided'; + } + } + static CallHierarchyPrepareParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final position = + json['position'] != null ? Position.fromJson(json['position']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + return CallHierarchyPrepareParams( + textDocument: textDocument, + position: position, + workDoneToken: workDoneToken); + } + + /// The position inside the text document. + final Position position; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + __result['position'] = + position?.toJson() ?? (throw 'position is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('position'); + try { + if (!obj.containsKey('position')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['position'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Position.canParse(obj['position'], reporter))) { + reporter.reportError('must be of type Position'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyPrepareParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyPrepareParams && + other.runtimeType == CallHierarchyPrepareParams) { + return textDocument == other.textDocument && + position == other.position && + workDoneToken == other.workDoneToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, position.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CallHierarchyRegistrationOptions + implements + TextDocumentRegistrationOptions, + CallHierarchyOptions, + StaticRegistrationOptions, + ToJsonable { + static const jsonHandler = LspJsonHandler( + CallHierarchyRegistrationOptions.canParse, + CallHierarchyRegistrationOptions.fromJson); + + CallHierarchyRegistrationOptions( + {this.documentSelector, this.workDoneProgress, this.id}); + static CallHierarchyRegistrationOptions fromJson(Map json) { + final documentSelector = json['documentSelector'] + ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) + ?.cast() + ?.toList(); + final workDoneProgress = json['workDoneProgress']; + final id = json['id']; + return CallHierarchyRegistrationOptions( + documentSelector: documentSelector, + workDoneProgress: workDoneProgress, + id: id); + } + + /// A document selector to identify the scope of the registration. If set to + /// null the document selector provided on the client side will be used. + final List documentSelector; + + /// The id used to register the request. The id can be used to deregister the + /// request again. See also Registration#id. + final String id; + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + __result['documentSelector'] = documentSelector; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + if (id != null) { + __result['id'] = id; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('documentSelector'); + try { + if (!obj.containsKey('documentSelector')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['documentSelector'] != null && + !((obj['documentSelector'] is List && + (obj['documentSelector'].every( + (item) => DocumentFilter.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('id'); + try { + if (obj['id'] != null && !(obj['id'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CallHierarchyRegistrationOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CallHierarchyRegistrationOptions && + other.runtimeType == CallHierarchyRegistrationOptions) { + return listEqual(documentSelector, other.documentSelector, + (DocumentFilter a, DocumentFilter b) => a == b) && + workDoneProgress == other.workDoneProgress && + id == other.id && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + hash = JenkinsSmiHash.combine(hash, id.hashCode); return JenkinsSmiHash.finish(hash); } @@ -279,12 +1550,131 @@ class CancelParams implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// Additional information that describes document changes. +/// @since 3.16.0 - proposed state +class ChangeAnnotation implements ToJsonable { + static const jsonHandler = + LspJsonHandler(ChangeAnnotation.canParse, ChangeAnnotation.fromJson); + + ChangeAnnotation( + {@required this.label, this.needsConfirmation, this.description}) { + if (label == null) { + throw 'label is required but was not provided'; + } + } + static ChangeAnnotation fromJson(Map json) { + final label = json['label']; + final needsConfirmation = json['needsConfirmation']; + final description = json['description']; + return ChangeAnnotation( + label: label, + needsConfirmation: needsConfirmation, + description: description); + } + + /// A human-readable string which is rendered less prominent in the user + /// interface. + final String description; + + /// A human-readable string describing the actual change. The string is + /// rendered prominent in the user interface. + final String label; + + /// A flag which indicates that user confirmation is needed before applying + /// the change. + final bool needsConfirmation; + + Map toJson() { + var __result = {}; + __result['label'] = label ?? (throw 'label is required but was not set'); + if (needsConfirmation != null) { + __result['needsConfirmation'] = needsConfirmation; + } + if (description != null) { + __result['description'] = description; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('label'); + try { + if (!obj.containsKey('label')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['label'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['label'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('needsConfirmation'); + try { + if (obj['needsConfirmation'] != null && + !(obj['needsConfirmation'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('description'); + try { + if (obj['description'] != null && !(obj['description'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ChangeAnnotation'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ChangeAnnotation && other.runtimeType == ChangeAnnotation) { + return label == other.label && + needsConfirmation == other.needsConfirmation && + description == other.description && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, label.hashCode); + hash = JenkinsSmiHash.combine(hash, needsConfirmation.hashCode); + hash = JenkinsSmiHash.combine(hash, description.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ClientCapabilities implements ToJsonable { static const jsonHandler = LspJsonHandler(ClientCapabilities.canParse, ClientCapabilities.fromJson); ClientCapabilities( - {this.workspace, this.textDocument, this.window, this.experimental}); + {this.workspace, + this.textDocument, + this.window, + this.general, + this.experimental}); static ClientCapabilities fromJson(Map json) { final workspace = json['workspace'] != null ? ClientCapabilitiesWorkspace.fromJson(json['workspace']) @@ -295,17 +1685,25 @@ class ClientCapabilities implements ToJsonable { final window = json['window'] != null ? ClientCapabilitiesWindow.fromJson(json['window']) : null; + final general = json['general'] != null + ? ClientCapabilitiesGeneral.fromJson(json['general']) + : null; final experimental = json['experimental']; return ClientCapabilities( workspace: workspace, textDocument: textDocument, window: window, + general: general, experimental: experimental); } /// Experimental client capabilities. final dynamic experimental; + /// General client capabilities. + /// @since 3.16.0 - proposed state + final ClientCapabilitiesGeneral general; + /// Text document specific client capabilities. final TextDocumentClientCapabilities textDocument; @@ -326,6 +1724,9 @@ class ClientCapabilities implements ToJsonable { if (window != null) { __result['window'] = window.toJson(); } + if (general != null) { + __result['general'] = general.toJson(); + } if (experimental != null) { __result['experimental'] = experimental; } @@ -367,6 +1768,16 @@ class ClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('general'); + try { + if (obj['general'] != null && + !(ClientCapabilitiesGeneral.canParse(obj['general'], reporter))) { + reporter.reportError('must be of type ClientCapabilitiesGeneral'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('experimental'); try { if (obj['experimental'] != null && !(true)) { @@ -390,6 +1801,7 @@ class ClientCapabilities implements ToJsonable { return workspace == other.workspace && textDocument == other.textDocument && window == other.window && + general == other.general && experimental == other.experimental && true; } @@ -402,6 +1814,7 @@ class ClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, workspace.hashCode); hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); hash = JenkinsSmiHash.combine(hash, window.hashCode); + hash = JenkinsSmiHash.combine(hash, general.hashCode); hash = JenkinsSmiHash.combine(hash, experimental.hashCode); return JenkinsSmiHash.finish(hash); } @@ -410,21 +1823,313 @@ class ClientCapabilities implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class ClientCapabilitiesFileOperations implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ClientCapabilitiesFileOperations.canParse, + ClientCapabilitiesFileOperations.fromJson); + + ClientCapabilitiesFileOperations( + {this.dynamicRegistration, + this.didCreate, + this.willCreate, + this.didRename, + this.willRename, + this.didDelete, + this.willDelete}); + static ClientCapabilitiesFileOperations fromJson(Map json) { + final dynamicRegistration = json['dynamicRegistration']; + final didCreate = json['didCreate']; + final willCreate = json['willCreate']; + final didRename = json['didRename']; + final willRename = json['willRename']; + final didDelete = json['didDelete']; + final willDelete = json['willDelete']; + return ClientCapabilitiesFileOperations( + dynamicRegistration: dynamicRegistration, + didCreate: didCreate, + willCreate: willCreate, + didRename: didRename, + willRename: willRename, + didDelete: didDelete, + willDelete: willDelete); + } + + /// The client has support for sending didCreateFiles notifications. + final bool didCreate; + + /// The client has support for sending didDeleteFiles notifications. + final bool didDelete; + + /// The client has support for sending didRenameFiles notifications. + final bool didRename; + + /// Whether the client supports dynamic registration for file + /// requests/notifications. + final bool dynamicRegistration; + + /// The client has support for sending willCreateFiles requests. + final bool willCreate; + + /// The client has support for sending willDeleteFiles requests. + final bool willDelete; + + /// The client has support for sending willRenameFiles requests. + final bool willRename; + + Map toJson() { + var __result = {}; + if (dynamicRegistration != null) { + __result['dynamicRegistration'] = dynamicRegistration; + } + if (didCreate != null) { + __result['didCreate'] = didCreate; + } + if (willCreate != null) { + __result['willCreate'] = willCreate; + } + if (didRename != null) { + __result['didRename'] = didRename; + } + if (willRename != null) { + __result['willRename'] = willRename; + } + if (didDelete != null) { + __result['didDelete'] = didDelete; + } + if (willDelete != null) { + __result['willDelete'] = willDelete; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('dynamicRegistration'); + try { + if (obj['dynamicRegistration'] != null && + !(obj['dynamicRegistration'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('didCreate'); + try { + if (obj['didCreate'] != null && !(obj['didCreate'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willCreate'); + try { + if (obj['willCreate'] != null && !(obj['willCreate'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('didRename'); + try { + if (obj['didRename'] != null && !(obj['didRename'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willRename'); + try { + if (obj['willRename'] != null && !(obj['willRename'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('didDelete'); + try { + if (obj['didDelete'] != null && !(obj['didDelete'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willDelete'); + try { + if (obj['willDelete'] != null && !(obj['willDelete'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ClientCapabilitiesFileOperations'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ClientCapabilitiesFileOperations && + other.runtimeType == ClientCapabilitiesFileOperations) { + return dynamicRegistration == other.dynamicRegistration && + didCreate == other.didCreate && + willCreate == other.willCreate && + didRename == other.didRename && + willRename == other.willRename && + didDelete == other.didDelete && + willDelete == other.willDelete && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); + hash = JenkinsSmiHash.combine(hash, didCreate.hashCode); + hash = JenkinsSmiHash.combine(hash, willCreate.hashCode); + hash = JenkinsSmiHash.combine(hash, didRename.hashCode); + hash = JenkinsSmiHash.combine(hash, willRename.hashCode); + hash = JenkinsSmiHash.combine(hash, didDelete.hashCode); + hash = JenkinsSmiHash.combine(hash, willDelete.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class ClientCapabilitiesGeneral implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ClientCapabilitiesGeneral.canParse, ClientCapabilitiesGeneral.fromJson); + + ClientCapabilitiesGeneral({this.regularExpressions, this.markdown}); + static ClientCapabilitiesGeneral fromJson(Map json) { + final regularExpressions = json['regularExpressions'] != null + ? RegularExpressionsClientCapabilities.fromJson( + json['regularExpressions']) + : null; + final markdown = json['markdown'] != null + ? MarkdownClientCapabilities.fromJson(json['markdown']) + : null; + return ClientCapabilitiesGeneral( + regularExpressions: regularExpressions, markdown: markdown); + } + + /// Client capabilities specific to the client's markdown parser. + /// @since 3.16.0 - proposed state + final MarkdownClientCapabilities markdown; + + /// Client capabilities specific to regular expressions. + /// @since 3.16.0 - proposed state + final RegularExpressionsClientCapabilities regularExpressions; + + Map toJson() { + var __result = {}; + if (regularExpressions != null) { + __result['regularExpressions'] = regularExpressions.toJson(); + } + if (markdown != null) { + __result['markdown'] = markdown.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('regularExpressions'); + try { + if (obj['regularExpressions'] != null && + !(RegularExpressionsClientCapabilities.canParse( + obj['regularExpressions'], reporter))) { + reporter.reportError( + 'must be of type RegularExpressionsClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('markdown'); + try { + if (obj['markdown'] != null && + !(MarkdownClientCapabilities.canParse(obj['markdown'], reporter))) { + reporter.reportError('must be of type MarkdownClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ClientCapabilitiesGeneral'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ClientCapabilitiesGeneral && + other.runtimeType == ClientCapabilitiesGeneral) { + return regularExpressions == other.regularExpressions && + markdown == other.markdown && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, regularExpressions.hashCode); + hash = JenkinsSmiHash.combine(hash, markdown.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ClientCapabilitiesWindow implements ToJsonable { static const jsonHandler = LspJsonHandler( ClientCapabilitiesWindow.canParse, ClientCapabilitiesWindow.fromJson); - ClientCapabilitiesWindow({this.workDoneProgress}); + ClientCapabilitiesWindow( + {this.workDoneProgress, this.showMessage, this.showDocument}); static ClientCapabilitiesWindow fromJson(Map json) { final workDoneProgress = json['workDoneProgress']; - return ClientCapabilitiesWindow(workDoneProgress: workDoneProgress); + final showMessage = json['showMessage'] != null + ? ShowMessageRequestClientCapabilities.fromJson(json['showMessage']) + : null; + final showDocument = json['showDocument'] != null + ? ShowDocumentClientCapabilities.fromJson(json['showDocument']) + : null; + return ClientCapabilitiesWindow( + workDoneProgress: workDoneProgress, + showMessage: showMessage, + showDocument: showDocument); } - /// Whether client supports handling progress notifications. If set, servers + /// Client capabilities for the show document request. + /// @since 3.16.0 - proposed state + final ShowDocumentClientCapabilities showDocument; + + /// Capabilities specific to the showMessage request + /// @since 3.16.0 - proposed state + final ShowMessageRequestClientCapabilities showMessage; + + /// Whether client supports handling progress notifications. If set servers /// are allowed to report in `workDoneProgress` property in the request /// specific server capabilities. - /// - /// Since 3.15.0 + /// @since 3.15.0 final bool workDoneProgress; Map toJson() { @@ -432,6 +2137,12 @@ class ClientCapabilitiesWindow implements ToJsonable { if (workDoneProgress != null) { __result['workDoneProgress'] = workDoneProgress; } + if (showMessage != null) { + __result['showMessage'] = showMessage.toJson(); + } + if (showDocument != null) { + __result['showDocument'] = showDocument.toJson(); + } return __result; } @@ -447,6 +2158,30 @@ class ClientCapabilitiesWindow implements ToJsonable { } finally { reporter.pop(); } + reporter.push('showMessage'); + try { + if (obj['showMessage'] != null && + !(ShowMessageRequestClientCapabilities.canParse( + obj['showMessage'], reporter))) { + reporter.reportError( + 'must be of type ShowMessageRequestClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('showDocument'); + try { + if (obj['showDocument'] != null && + !(ShowDocumentClientCapabilities.canParse( + obj['showDocument'], reporter))) { + reporter + .reportError('must be of type ShowDocumentClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type ClientCapabilitiesWindow'); @@ -458,7 +2193,10 @@ class ClientCapabilitiesWindow implements ToJsonable { bool operator ==(Object other) { if (other is ClientCapabilitiesWindow && other.runtimeType == ClientCapabilitiesWindow) { - return workDoneProgress == other.workDoneProgress && true; + return workDoneProgress == other.workDoneProgress && + showMessage == other.showMessage && + showDocument == other.showDocument && + true; } return false; } @@ -467,6 +2205,8 @@ class ClientCapabilitiesWindow implements ToJsonable { int get hashCode { var hash = 0; hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + hash = JenkinsSmiHash.combine(hash, showMessage.hashCode); + hash = JenkinsSmiHash.combine(hash, showDocument.hashCode); return JenkinsSmiHash.finish(hash); } @@ -487,7 +2227,10 @@ class ClientCapabilitiesWorkspace implements ToJsonable { this.symbol, this.executeCommand, this.workspaceFolders, - this.configuration}); + this.configuration, + this.semanticTokens, + this.codeLens, + this.fileOperations}); static ClientCapabilitiesWorkspace fromJson(Map json) { final applyEdit = json['applyEdit']; final workspaceEdit = json['workspaceEdit'] != null @@ -509,6 +2252,16 @@ class ClientCapabilitiesWorkspace implements ToJsonable { : null; final workspaceFolders = json['workspaceFolders']; final configuration = json['configuration']; + final semanticTokens = json['semanticTokens'] != null + ? SemanticTokensWorkspaceClientCapabilities.fromJson( + json['semanticTokens']) + : null; + final codeLens = json['codeLens'] != null + ? CodeLensWorkspaceClientCapabilities.fromJson(json['codeLens']) + : null; + final fileOperations = json['fileOperations'] != null + ? ClientCapabilitiesFileOperations.fromJson(json['fileOperations']) + : null; return ClientCapabilitiesWorkspace( applyEdit: applyEdit, workspaceEdit: workspaceEdit, @@ -517,16 +2270,22 @@ class ClientCapabilitiesWorkspace implements ToJsonable { symbol: symbol, executeCommand: executeCommand, workspaceFolders: workspaceFolders, - configuration: configuration); + configuration: configuration, + semanticTokens: semanticTokens, + codeLens: codeLens, + fileOperations: fileOperations); } /// The client supports applying batch edits to the workspace by supporting /// the request 'workspace/applyEdit' final bool applyEdit; + /// Capabilities specific to the code lens requests scoped to the workspace. + /// @since 3.16.0 - proposed state + final CodeLensWorkspaceClientCapabilities codeLens; + /// The client supports `workspace/configuration` requests. - /// - /// Since 3.6.0 + /// @since 3.6.0 final bool configuration; /// Capabilities specific to the `workspace/didChangeConfiguration` @@ -540,6 +2299,15 @@ class ClientCapabilitiesWorkspace implements ToJsonable { /// Capabilities specific to the `workspace/executeCommand` request. final ExecuteCommandClientCapabilities executeCommand; + /// The client has support for file requests/notifications. + /// @since 3.16.0 - proposed state + final ClientCapabilitiesFileOperations fileOperations; + + /// Capabilities specific to the semantic token requests scoped to the + /// workspace. + /// @since 3.16.0 - proposed state + final SemanticTokensWorkspaceClientCapabilities semanticTokens; + /// Capabilities specific to the `workspace/symbol` request. final WorkspaceSymbolClientCapabilities symbol; @@ -547,8 +2315,7 @@ class ClientCapabilitiesWorkspace implements ToJsonable { final WorkspaceEditClientCapabilities workspaceEdit; /// The client has support for workspace folders. - /// - /// Since 3.6.0 + /// @since 3.6.0 final bool workspaceFolders; Map toJson() { @@ -577,6 +2344,15 @@ class ClientCapabilitiesWorkspace implements ToJsonable { if (configuration != null) { __result['configuration'] = configuration; } + if (semanticTokens != null) { + __result['semanticTokens'] = semanticTokens.toJson(); + } + if (codeLens != null) { + __result['codeLens'] = codeLens.toJson(); + } + if (fileOperations != null) { + __result['fileOperations'] = fileOperations.toJson(); + } return __result; } @@ -670,6 +2446,42 @@ class ClientCapabilitiesWorkspace implements ToJsonable { } finally { reporter.pop(); } + reporter.push('semanticTokens'); + try { + if (obj['semanticTokens'] != null && + !(SemanticTokensWorkspaceClientCapabilities.canParse( + obj['semanticTokens'], reporter))) { + reporter.reportError( + 'must be of type SemanticTokensWorkspaceClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('codeLens'); + try { + if (obj['codeLens'] != null && + !(CodeLensWorkspaceClientCapabilities.canParse( + obj['codeLens'], reporter))) { + reporter.reportError( + 'must be of type CodeLensWorkspaceClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('fileOperations'); + try { + if (obj['fileOperations'] != null && + !(ClientCapabilitiesFileOperations.canParse( + obj['fileOperations'], reporter))) { + reporter + .reportError('must be of type ClientCapabilitiesFileOperations'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type ClientCapabilitiesWorkspace'); @@ -689,6 +2501,9 @@ class ClientCapabilitiesWorkspace implements ToJsonable { executeCommand == other.executeCommand && workspaceFolders == other.workspaceFolders && configuration == other.configuration && + semanticTokens == other.semanticTokens && + codeLens == other.codeLens && + fileOperations == other.fileOperations && true; } return false; @@ -705,6 +2520,9 @@ class ClientCapabilitiesWorkspace implements ToJsonable { hash = JenkinsSmiHash.combine(hash, executeCommand.hashCode); hash = JenkinsSmiHash.combine(hash, workspaceFolders.hashCode); hash = JenkinsSmiHash.combine(hash, configuration.hashCode); + hash = JenkinsSmiHash.combine(hash, semanticTokens.hashCode); + hash = JenkinsSmiHash.combine(hash, codeLens.hashCode); + hash = JenkinsSmiHash.combine(hash, fileOperations.hashCode); return JenkinsSmiHash.finish(hash); } @@ -712,8 +2530,8 @@ class ClientCapabilitiesWorkspace implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } -/// A code action represents a change that can be performed in code. For -/// example, to fix a problem or to refactor code. +/// A code action represents a change that can be performed in code, e.g. to fix +/// a problem or to refactor code. /// /// A CodeAction must set either `edit` and/or a `command`. If both are /// supplied, the `edit` is applied first, then the `command` is executed. @@ -726,8 +2544,10 @@ class CodeAction implements ToJsonable { this.kind, this.diagnostics, this.isPreferred, + this.disabled, this.edit, - this.command}) { + this.command, + this.data}) { if (title == null) { throw 'title is required but was not provided'; } @@ -741,26 +2561,55 @@ class CodeAction implements ToJsonable { ?.cast() ?.toList(); final isPreferred = json['isPreferred']; + final disabled = json['disabled'] != null + ? CodeActionDisabled.fromJson(json['disabled']) + : null; final edit = json['edit'] != null ? WorkspaceEdit.fromJson(json['edit']) : null; final command = json['command'] != null ? Command.fromJson(json['command']) : null; + final data = json['data']; return CodeAction( title: title, kind: kind, diagnostics: diagnostics, isPreferred: isPreferred, + disabled: disabled, edit: edit, - command: command); + command: command, + data: data); } /// A command this code action executes. If a code action provides an edit and /// a command, first the edit is executed and then the command. final Command command; + /// A data entry field that is preserved on a code action between a + /// `textDocument/codeAction` and a `codeAction/resolve` request. + /// @since 3.16.0 - proposed state + final dynamic data; + /// The diagnostics that this code action resolves. final List diagnostics; + /// Marks that the code action cannot currently be applied. + /// + /// Clients should follow the following guidelines regarding disabled code + /// actions: + /// + /// - Disabled code actions are not shown in automatic lightbulbs code + /// action menus. + /// + /// - Disabled actions are shown as faded out in the code action menu when + /// the user request a more specific type of code action, such as + /// refactorings. + /// + /// - If the user has a keybinding that auto applies a code action and only + /// a disabled code actions are returned, the client should show the user + /// an error message with `reason` in the editor. + /// @since 3.16.0 + final CodeActionDisabled disabled; + /// The workspace edit this code action performs. final WorkspaceEdit edit; @@ -793,12 +2642,18 @@ class CodeAction implements ToJsonable { if (isPreferred != null) { __result['isPreferred'] = isPreferred; } + if (disabled != null) { + __result['disabled'] = disabled.toJson(); + } if (edit != null) { __result['edit'] = edit.toJson(); } if (command != null) { __result['command'] = command.toJson(); } + if (data != null) { + __result['data'] = data; + } return __result; } @@ -852,6 +2707,16 @@ class CodeAction implements ToJsonable { } finally { reporter.pop(); } + reporter.push('disabled'); + try { + if (obj['disabled'] != null && + !(CodeActionDisabled.canParse(obj['disabled'], reporter))) { + reporter.reportError('must be of type CodeActionDisabled'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('edit'); try { if (obj['edit'] != null && @@ -872,6 +2737,15 @@ class CodeAction implements ToJsonable { } finally { reporter.pop(); } + reporter.push('data'); + try { + if (obj['data'] != null && !(true)) { + reporter.reportError('must be of type dynamic'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type CodeAction'); @@ -887,8 +2761,10 @@ class CodeAction implements ToJsonable { listEqual(diagnostics, other.diagnostics, (Diagnostic a, Diagnostic b) => a == b) && isPreferred == other.isPreferred && + disabled == other.disabled && edit == other.edit && command == other.command && + data == other.data && true; } return false; @@ -901,8 +2777,10 @@ class CodeAction implements ToJsonable { hash = JenkinsSmiHash.combine(hash, kind.hashCode); hash = JenkinsSmiHash.combine(hash, lspHashCode(diagnostics)); hash = JenkinsSmiHash.combine(hash, isPreferred.hashCode); + hash = JenkinsSmiHash.combine(hash, disabled.hashCode); hash = JenkinsSmiHash.combine(hash, edit.hashCode); hash = JenkinsSmiHash.combine(hash, command.hashCode); + hash = JenkinsSmiHash.combine(hash, data.hashCode); return JenkinsSmiHash.finish(hash); } @@ -918,7 +2796,11 @@ class CodeActionClientCapabilities implements ToJsonable { CodeActionClientCapabilities( {this.dynamicRegistration, this.codeActionLiteralSupport, - this.isPreferredSupport}); + this.isPreferredSupport, + this.disabledSupport, + this.dataSupport, + this.resolveSupport, + this.honorsChangeAnnotations}); static CodeActionClientCapabilities fromJson(Map json) { final dynamicRegistration = json['dynamicRegistration']; final codeActionLiteralSupport = json['codeActionLiteralSupport'] != null @@ -926,10 +2808,21 @@ class CodeActionClientCapabilities implements ToJsonable { json['codeActionLiteralSupport']) : null; final isPreferredSupport = json['isPreferredSupport']; + final disabledSupport = json['disabledSupport']; + final dataSupport = json['dataSupport']; + final resolveSupport = json['resolveSupport'] != null + ? CodeActionClientCapabilitiesResolveSupport.fromJson( + json['resolveSupport']) + : null; + final honorsChangeAnnotations = json['honorsChangeAnnotations']; return CodeActionClientCapabilities( dynamicRegistration: dynamicRegistration, codeActionLiteralSupport: codeActionLiteralSupport, - isPreferredSupport: isPreferredSupport); + isPreferredSupport: isPreferredSupport, + disabledSupport: disabledSupport, + dataSupport: dataSupport, + resolveSupport: resolveSupport, + honorsChangeAnnotations: honorsChangeAnnotations); } /// The client supports code action literals as a valid response of the @@ -938,12 +2831,34 @@ class CodeActionClientCapabilities implements ToJsonable { final CodeActionClientCapabilitiesCodeActionLiteralSupport codeActionLiteralSupport; + /// Whether code action supports the `data` property which is preserved + /// between a `textDocument/codeAction` and a `codeAction/resolve` request. + /// @since 3.16.0 - proposed state + final bool dataSupport; + + /// Whether code action supports the `disabled` property. + /// @since 3.16.0 - proposed state + final bool disabledSupport; + /// Whether code action supports dynamic registration. final bool dynamicRegistration; - /// Whether code action supports the `isPreferred` property. @since 3.15.0 + /// Whether th client honors the change annotations in text edits and resource + /// operations returned via the `CodeAction#edit` property by for example + /// presenting the workspace edit in the user interface and asking for + /// confirmation. + /// @since 3.16.0 - proposed state + final bool honorsChangeAnnotations; + + /// Whether code action supports the `isPreferred` property. + /// @since 3.15.0 final bool isPreferredSupport; + /// Whether the client supports resolving additional code action properties + /// via a separate `codeAction/resolve` request. + /// @since 3.16.0 - proposed state + final CodeActionClientCapabilitiesResolveSupport resolveSupport; + Map toJson() { var __result = {}; if (dynamicRegistration != null) { @@ -955,6 +2870,18 @@ class CodeActionClientCapabilities implements ToJsonable { if (isPreferredSupport != null) { __result['isPreferredSupport'] = isPreferredSupport; } + if (disabledSupport != null) { + __result['disabledSupport'] = disabledSupport; + } + if (dataSupport != null) { + __result['dataSupport'] = dataSupport; + } + if (resolveSupport != null) { + __result['resolveSupport'] = resolveSupport.toJson(); + } + if (honorsChangeAnnotations != null) { + __result['honorsChangeAnnotations'] = honorsChangeAnnotations; + } return __result; } @@ -992,6 +2919,47 @@ class CodeActionClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('disabledSupport'); + try { + if (obj['disabledSupport'] != null && + !(obj['disabledSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('dataSupport'); + try { + if (obj['dataSupport'] != null && !(obj['dataSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('resolveSupport'); + try { + if (obj['resolveSupport'] != null && + !(CodeActionClientCapabilitiesResolveSupport.canParse( + obj['resolveSupport'], reporter))) { + reporter.reportError( + 'must be of type CodeActionClientCapabilitiesResolveSupport'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('honorsChangeAnnotations'); + try { + if (obj['honorsChangeAnnotations'] != null && + !(obj['honorsChangeAnnotations'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type CodeActionClientCapabilities'); @@ -1006,6 +2974,10 @@ class CodeActionClientCapabilities implements ToJsonable { return dynamicRegistration == other.dynamicRegistration && codeActionLiteralSupport == other.codeActionLiteralSupport && isPreferredSupport == other.isPreferredSupport && + disabledSupport == other.disabledSupport && + dataSupport == other.dataSupport && + resolveSupport == other.resolveSupport && + honorsChangeAnnotations == other.honorsChangeAnnotations && true; } return false; @@ -1017,6 +2989,10 @@ class CodeActionClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); hash = JenkinsSmiHash.combine(hash, codeActionLiteralSupport.hashCode); hash = JenkinsSmiHash.combine(hash, isPreferredSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, disabledSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, dataSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, resolveSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, honorsChangeAnnotations.hashCode); return JenkinsSmiHash.finish(hash); } @@ -1188,6 +3164,83 @@ class CodeActionClientCapabilitiesCodeActionLiteralSupport String toString() => jsonEncoder.convert(toJson()); } +class CodeActionClientCapabilitiesResolveSupport implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CodeActionClientCapabilitiesResolveSupport.canParse, + CodeActionClientCapabilitiesResolveSupport.fromJson); + + CodeActionClientCapabilitiesResolveSupport({@required this.properties}) { + if (properties == null) { + throw 'properties is required but was not provided'; + } + } + static CodeActionClientCapabilitiesResolveSupport fromJson( + Map json) { + final properties = + json['properties']?.map((item) => item)?.cast()?.toList(); + return CodeActionClientCapabilitiesResolveSupport(properties: properties); + } + + /// The properties that a client can resolve lazily. + final List properties; + + Map toJson() { + var __result = {}; + __result['properties'] = + properties ?? (throw 'properties is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('properties'); + try { + if (!obj.containsKey('properties')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['properties'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['properties'] is List && + (obj['properties'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type CodeActionClientCapabilitiesResolveSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CodeActionClientCapabilitiesResolveSupport && + other.runtimeType == CodeActionClientCapabilitiesResolveSupport) { + return listEqual( + properties, other.properties, (String a, String b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(properties)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// Contains additional diagnostic information about the context in which a code /// action is run. class CodeActionContext implements ToJsonable { @@ -1222,7 +3275,7 @@ class CodeActionContext implements ToJsonable { /// Requested kind of actions to return. /// /// Actions not of this kind are filtered out by the client before being - /// shown, so servers can omit computing them. + /// shown. So servers can omit computing them. final List only; Map toJson() { @@ -1299,6 +3352,77 @@ class CodeActionContext implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class CodeActionDisabled implements ToJsonable { + static const jsonHandler = + LspJsonHandler(CodeActionDisabled.canParse, CodeActionDisabled.fromJson); + + CodeActionDisabled({@required this.reason}) { + if (reason == null) { + throw 'reason is required but was not provided'; + } + } + static CodeActionDisabled fromJson(Map json) { + final reason = json['reason']; + return CodeActionDisabled(reason: reason); + } + + /// Human readable description of why the code action is currently disabled. + /// + /// This is displayed in the code actions UI. + final String reason; + + Map toJson() { + var __result = {}; + __result['reason'] = reason ?? (throw 'reason is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('reason'); + try { + if (!obj.containsKey('reason')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['reason'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['reason'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CodeActionDisabled'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CodeActionDisabled && + other.runtimeType == CodeActionDisabled) { + return reason == other.reason && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, reason.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// A set of predefined code action kinds. class CodeActionKind { const CodeActionKind(this._value); @@ -1357,7 +3481,7 @@ class CodeActionKind { /// Source code actions apply to the entire file. static const Source = CodeActionKind('source'); - /// Base kind for an organize imports source action `source.organizeImports`. + /// Base kind for an organize imports source action: `source.organizeImports`. static const SourceOrganizeImports = CodeActionKind('source.organizeImports'); Object toJson() => _value; @@ -1375,7 +3499,8 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { static const jsonHandler = LspJsonHandler(CodeActionOptions.canParse, CodeActionOptions.fromJson); - CodeActionOptions({this.codeActionKinds, this.workDoneProgress}); + CodeActionOptions( + {this.codeActionKinds, this.resolveProvider, this.workDoneProgress}); static CodeActionOptions fromJson(Map json) { if (CodeActionRegistrationOptions.canParse(json, nullLspJsonReporter)) { return CodeActionRegistrationOptions.fromJson(json); @@ -1384,9 +3509,12 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null) ?.cast() ?.toList(); + final resolveProvider = json['resolveProvider']; final workDoneProgress = json['workDoneProgress']; return CodeActionOptions( - codeActionKinds: codeActionKinds, workDoneProgress: workDoneProgress); + codeActionKinds: codeActionKinds, + resolveProvider: resolveProvider, + workDoneProgress: workDoneProgress); } /// CodeActionKinds that this server may return. @@ -1394,6 +3522,11 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { /// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or /// the server may list out every specific kind they provide. final List codeActionKinds; + + /// The server provides support to resolve additional information for a code + /// action. + /// @since 3.16.0 + final bool resolveProvider; final bool workDoneProgress; Map toJson() { @@ -1401,6 +3534,9 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { if (codeActionKinds != null) { __result['codeActionKinds'] = codeActionKinds; } + if (resolveProvider != null) { + __result['resolveProvider'] = resolveProvider; + } if (workDoneProgress != null) { __result['workDoneProgress'] = workDoneProgress; } @@ -1421,6 +3557,16 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { } finally { reporter.pop(); } + reporter.push('resolveProvider'); + try { + if (obj['resolveProvider'] != null && + !(obj['resolveProvider'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('workDoneProgress'); try { if (obj['workDoneProgress'] != null && @@ -1443,6 +3589,7 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { if (other is CodeActionOptions && other.runtimeType == CodeActionOptions) { return listEqual(codeActionKinds, other.codeActionKinds, (CodeActionKind a, CodeActionKind b) => a == b) && + resolveProvider == other.resolveProvider && workDoneProgress == other.workDoneProgress && true; } @@ -1453,6 +3600,7 @@ class CodeActionOptions implements WorkDoneProgressOptions, ToJsonable { int get hashCode { var hash = 0; hash = JenkinsSmiHash.combine(hash, lspHashCode(codeActionKinds)); + hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode); hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); return JenkinsSmiHash.finish(hash); } @@ -1516,8 +3664,8 @@ class CodeActionParams /// Context carrying additional information. final CodeActionContext context; - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The range for which the command was invoked. @@ -1663,7 +3811,10 @@ class CodeActionRegistrationOptions CodeActionRegistrationOptions.fromJson); CodeActionRegistrationOptions( - {this.documentSelector, this.codeActionKinds, this.workDoneProgress}); + {this.documentSelector, + this.codeActionKinds, + this.resolveProvider, + this.workDoneProgress}); static CodeActionRegistrationOptions fromJson(Map json) { final documentSelector = json['documentSelector'] ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) @@ -1673,10 +3824,12 @@ class CodeActionRegistrationOptions ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null) ?.cast() ?.toList(); + final resolveProvider = json['resolveProvider']; final workDoneProgress = json['workDoneProgress']; return CodeActionRegistrationOptions( documentSelector: documentSelector, codeActionKinds: codeActionKinds, + resolveProvider: resolveProvider, workDoneProgress: workDoneProgress); } @@ -1687,8 +3840,13 @@ class CodeActionRegistrationOptions final List codeActionKinds; /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; + + /// The server provides support to resolve additional information for a code + /// action. + /// @since 3.16.0 + final bool resolveProvider; final bool workDoneProgress; Map toJson() { @@ -1697,6 +3855,9 @@ class CodeActionRegistrationOptions if (codeActionKinds != null) { __result['codeActionKinds'] = codeActionKinds; } + if (resolveProvider != null) { + __result['resolveProvider'] = resolveProvider; + } if (workDoneProgress != null) { __result['workDoneProgress'] = workDoneProgress; } @@ -1733,6 +3894,16 @@ class CodeActionRegistrationOptions } finally { reporter.pop(); } + reporter.push('resolveProvider'); + try { + if (obj['resolveProvider'] != null && + !(obj['resolveProvider'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('workDoneProgress'); try { if (obj['workDoneProgress'] != null && @@ -1758,6 +3929,7 @@ class CodeActionRegistrationOptions (DocumentFilter a, DocumentFilter b) => a == b) && listEqual(codeActionKinds, other.codeActionKinds, (CodeActionKind a, CodeActionKind b) => a == b) && + resolveProvider == other.resolveProvider && workDoneProgress == other.workDoneProgress && true; } @@ -1769,6 +3941,7 @@ class CodeActionRegistrationOptions var hash = 0; hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); hash = JenkinsSmiHash.combine(hash, lspHashCode(codeActionKinds)); + hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode); hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); return JenkinsSmiHash.finish(hash); } @@ -1777,11 +3950,81 @@ class CodeActionRegistrationOptions String toString() => jsonEncoder.convert(toJson()); } -/// A CodeLense represents a command that should be shown along with source +/// Structure to capture a description for an error code. +/// @since 3.16.0 - proposed state +class CodeDescription implements ToJsonable { + static const jsonHandler = + LspJsonHandler(CodeDescription.canParse, CodeDescription.fromJson); + + CodeDescription({@required this.href}) { + if (href == null) { + throw 'href is required but was not provided'; + } + } + static CodeDescription fromJson(Map json) { + final href = json['href']; + return CodeDescription(href: href); + } + + /// An URI to open with more information about the diagnostic error. + final String href; + + Map toJson() { + var __result = {}; + __result['href'] = href ?? (throw 'href is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('href'); + try { + if (!obj.containsKey('href')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['href'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['href'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CodeDescription'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CodeDescription && other.runtimeType == CodeDescription) { + return href == other.href && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, href.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// A code lens represents a command that should be shown along with source /// text, like the number of references, a way to run tests, etc. /// -/// A CodeLens is _unresolved_ when no command is associated to it. For -/// performance reasons, the creation of a CodeLens and resolving should be done +/// A code lens is _unresolved_ when no command is associated to it. For +/// performance reasons the creation of a code lens and resolving should be done /// in two stages. class CodeLens implements ToJsonable { static const jsonHandler = @@ -1800,14 +4043,15 @@ class CodeLens implements ToJsonable { return CodeLens(range: range, command: command, data: data); } - /// The command this CodeLens represents. + /// The command this code lens represents. final Command command; - /// A data entry field that is preserved on a CodeLens item between a CodeLens - /// and a CodeLens resolve request. + /// A data entry field that is preserved on a code lens item between a code + /// lens and a code lens resolve request. final dynamic data; - /// The range in which the CodeLens is valid. Should only span a single line. + /// The range in which this code lens is valid. Should only span a single + /// line. final Range range; Map toJson() { @@ -1902,7 +4146,7 @@ class CodeLensClientCapabilities implements ToJsonable { return CodeLensClientCapabilities(dynamicRegistration: dynamicRegistration); } - /// Whether CodeLens supports dynamic registration. + /// Whether code lens supports dynamic registration. final bool dynamicRegistration; Map toJson() { @@ -2070,11 +4314,11 @@ class CodeLensParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; - /// The document to request CodeLens for. + /// The document to request code lens for. final TextDocumentIdentifier textDocument; /// An optional token that a server can use to report work done progress. @@ -2187,7 +4431,7 @@ class CodeLensRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// Code lens has a resolve provider as well. @@ -2277,6 +4521,74 @@ class CodeLensRegistrationOptions String toString() => jsonEncoder.convert(toJson()); } +class CodeLensWorkspaceClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CodeLensWorkspaceClientCapabilities.canParse, + CodeLensWorkspaceClientCapabilities.fromJson); + + CodeLensWorkspaceClientCapabilities({this.refreshSupport}); + static CodeLensWorkspaceClientCapabilities fromJson( + Map json) { + final refreshSupport = json['refreshSupport']; + return CodeLensWorkspaceClientCapabilities(refreshSupport: refreshSupport); + } + + /// Whether the client implementation supports a refresh request sent from the + /// server to the client. + /// + /// Note that this event is global and will force the client to refresh all + /// code lenses currently shown. It should be used with absolute care and is + /// useful for situation where a server for example detect a project wide + /// change that requires such a calculation. + final bool refreshSupport; + + Map toJson() { + var __result = {}; + if (refreshSupport != null) { + __result['refreshSupport'] = refreshSupport; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('refreshSupport'); + try { + if (obj['refreshSupport'] != null && !(obj['refreshSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type CodeLensWorkspaceClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CodeLensWorkspaceClientCapabilities && + other.runtimeType == CodeLensWorkspaceClientCapabilities) { + return refreshSupport == other.refreshSupport && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, refreshSupport.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// Represents a color in RGBA space. class Color implements ToJsonable { static const jsonHandler = LspJsonHandler(Color.canParse, Color.fromJson); @@ -2557,12 +4869,12 @@ class ColorPresentation implements ToJsonable { final List additionalTextEdits; /// The label of this color presentation. It will be shown on the color picker - /// header. By default, this is also the text that is inserted when selecting + /// header. By default this is also the text that is inserted when selecting /// this color presentation. final String label; /// An edit ([TextEdit]) which is applied to a document when selecting this - /// presentation for the color. When `falsy`, the + /// presentation for the color. When `falsy` the /// [label](#ColorPresentation.label) is used. final TextEdit textEdit; @@ -2703,8 +5015,8 @@ class ColorPresentationParams /// The color information to request presentations for. final Color color; - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The range where the color would be inserted. Serves as a context. @@ -3108,7 +5420,10 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { this.documentationFormat, this.deprecatedSupport, this.preselectSupport, - this.tagSupport}); + this.tagSupport, + this.insertReplaceSupport, + this.resolveSupport, + this.insertTextModeSupport}); static CompletionClientCapabilitiesCompletionItem fromJson( Map json) { final snippetSupport = json['snippetSupport']; @@ -3122,13 +5437,25 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { final tagSupport = json['tagSupport'] != null ? CompletionClientCapabilitiesTagSupport.fromJson(json['tagSupport']) : null; + final insertReplaceSupport = json['insertReplaceSupport']; + final resolveSupport = json['resolveSupport'] != null + ? CompletionClientCapabilitiesResolveSupport.fromJson( + json['resolveSupport']) + : null; + final insertTextModeSupport = json['insertTextModeSupport'] != null + ? CompletionClientCapabilitiesInsertTextModeSupport.fromJson( + json['insertTextModeSupport']) + : null; return CompletionClientCapabilitiesCompletionItem( snippetSupport: snippetSupport, commitCharactersSupport: commitCharactersSupport, documentationFormat: documentationFormat, deprecatedSupport: deprecatedSupport, preselectSupport: preselectSupport, - tagSupport: tagSupport); + tagSupport: tagSupport, + insertReplaceSupport: insertReplaceSupport, + resolveSupport: resolveSupport, + insertTextModeSupport: insertTextModeSupport); } /// Client supports commit characters on a completion item. @@ -3141,15 +5468,32 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { /// The order describes the preferred format of the client. final List documentationFormat; + /// Client supports insert replace edit to control different behavior if a + /// completion item is inserted in the text or should replace text. + /// @since 3.16.0 - proposed state + final bool insertReplaceSupport; + + /// The client supports the `insertTextMode` property on a completion item to + /// override the whitespace handling mode as defined by the client (see + /// `insertTextMode`). + /// @since 3.16.0 - proposed state + final CompletionClientCapabilitiesInsertTextModeSupport insertTextModeSupport; + /// Client supports the preselect property on a completion item. final bool preselectSupport; + /// Indicates which properties a client can resolve lazily on a completion + /// item. Before version 3.16.0 only the predefined properties `documentation` + /// and `details` could be resolved lazily. + /// @since 3.16.0 - proposed state + final CompletionClientCapabilitiesResolveSupport resolveSupport; + /// Client supports snippets as insert text. /// /// A snippet can define tab stops and placeholders with `$1`, `$2` and /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the - /// snippet. Placeholders with equal identifiers are linked, so that typing in - /// one will update others as well. + /// snippet. Placeholders with equal identifiers are linked, that is typing in + /// one will update others too. final bool snippetSupport; /// Client supports the tag property on a completion item. Clients supporting @@ -3179,6 +5523,15 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { if (tagSupport != null) { __result['tagSupport'] = tagSupport.toJson(); } + if (insertReplaceSupport != null) { + __result['insertReplaceSupport'] = insertReplaceSupport; + } + if (resolveSupport != null) { + __result['resolveSupport'] = resolveSupport.toJson(); + } + if (insertTextModeSupport != null) { + __result['insertTextModeSupport'] = insertTextModeSupport.toJson(); + } return __result; } @@ -3247,6 +5600,40 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { } finally { reporter.pop(); } + reporter.push('insertReplaceSupport'); + try { + if (obj['insertReplaceSupport'] != null && + !(obj['insertReplaceSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('resolveSupport'); + try { + if (obj['resolveSupport'] != null && + !(CompletionClientCapabilitiesResolveSupport.canParse( + obj['resolveSupport'], reporter))) { + reporter.reportError( + 'must be of type CompletionClientCapabilitiesResolveSupport'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('insertTextModeSupport'); + try { + if (obj['insertTextModeSupport'] != null && + !(CompletionClientCapabilitiesInsertTextModeSupport.canParse( + obj['insertTextModeSupport'], reporter))) { + reporter.reportError( + 'must be of type CompletionClientCapabilitiesInsertTextModeSupport'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError( @@ -3266,6 +5653,9 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { deprecatedSupport == other.deprecatedSupport && preselectSupport == other.preselectSupport && tagSupport == other.tagSupport && + insertReplaceSupport == other.insertReplaceSupport && + resolveSupport == other.resolveSupport && + insertTextModeSupport == other.insertTextModeSupport && true; } return false; @@ -3280,6 +5670,9 @@ class CompletionClientCapabilitiesCompletionItem implements ToJsonable { hash = JenkinsSmiHash.combine(hash, deprecatedSupport.hashCode); hash = JenkinsSmiHash.combine(hash, preselectSupport.hashCode); hash = JenkinsSmiHash.combine(hash, tagSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, insertReplaceSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, resolveSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, insertTextModeSupport.hashCode); return JenkinsSmiHash.finish(hash); } @@ -3363,6 +5756,164 @@ class CompletionClientCapabilitiesCompletionItemKind implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class CompletionClientCapabilitiesInsertTextModeSupport implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CompletionClientCapabilitiesInsertTextModeSupport.canParse, + CompletionClientCapabilitiesInsertTextModeSupport.fromJson); + + CompletionClientCapabilitiesInsertTextModeSupport({@required this.valueSet}) { + if (valueSet == null) { + throw 'valueSet is required but was not provided'; + } + } + static CompletionClientCapabilitiesInsertTextModeSupport fromJson( + Map json) { + final valueSet = json['valueSet'] + ?.map((item) => item != null ? InsertTextMode.fromJson(item) : null) + ?.cast() + ?.toList(); + return CompletionClientCapabilitiesInsertTextModeSupport( + valueSet: valueSet); + } + + final List valueSet; + + Map toJson() { + var __result = {}; + __result['valueSet'] = + valueSet ?? (throw 'valueSet is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('valueSet'); + try { + if (!obj.containsKey('valueSet')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['valueSet'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['valueSet'] is List && + (obj['valueSet'] + .every((item) => InsertTextMode.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type CompletionClientCapabilitiesInsertTextModeSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CompletionClientCapabilitiesInsertTextModeSupport && + other.runtimeType == + CompletionClientCapabilitiesInsertTextModeSupport) { + return listEqual(valueSet, other.valueSet, + (InsertTextMode a, InsertTextMode b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(valueSet)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class CompletionClientCapabilitiesResolveSupport implements ToJsonable { + static const jsonHandler = LspJsonHandler( + CompletionClientCapabilitiesResolveSupport.canParse, + CompletionClientCapabilitiesResolveSupport.fromJson); + + CompletionClientCapabilitiesResolveSupport({@required this.properties}) { + if (properties == null) { + throw 'properties is required but was not provided'; + } + } + static CompletionClientCapabilitiesResolveSupport fromJson( + Map json) { + final properties = + json['properties']?.map((item) => item)?.cast()?.toList(); + return CompletionClientCapabilitiesResolveSupport(properties: properties); + } + + /// The properties that a client can resolve lazily. + final List properties; + + Map toJson() { + var __result = {}; + __result['properties'] = + properties ?? (throw 'properties is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('properties'); + try { + if (!obj.containsKey('properties')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['properties'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['properties'] is List && + (obj['properties'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type CompletionClientCapabilitiesResolveSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CompletionClientCapabilitiesResolveSupport && + other.runtimeType == CompletionClientCapabilitiesResolveSupport) { + return listEqual( + properties, other.properties, (String a, String b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(properties)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class CompletionClientCapabilitiesTagSupport implements ToJsonable { static const jsonHandler = LspJsonHandler( CompletionClientCapabilitiesTagSupport.canParse, @@ -3463,7 +6014,7 @@ class CompletionContext implements ToJsonable { triggerKind: triggerKind, triggerCharacter: triggerCharacter); } - /// The trigger character (single character) that has trigger code complete. + /// The trigger character (a single character) that has trigger code complete. /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` final String triggerCharacter; @@ -3554,6 +6105,7 @@ class CompletionItem implements ToJsonable { this.filterText, this.insertText, this.insertTextFormat, + this.insertTextMode, this.textEdit, this.additionalTextEdits, this.commitCharacters, @@ -3589,6 +6141,9 @@ class CompletionItem implements ToJsonable { final insertTextFormat = json['insertTextFormat'] != null ? InsertTextFormat.fromJson(json['insertTextFormat']) : null; + final insertTextMode = json['insertTextMode'] != null + ? InsertTextMode.fromJson(json['insertTextMode']) + : null; final textEdit = json['textEdit'] != null ? TextEdit.fromJson(json['textEdit']) : null; final additionalTextEdits = json['additionalTextEdits'] @@ -3614,6 +6169,7 @@ class CompletionItem implements ToJsonable { filterText: filterText, insertText: insertText, insertTextFormat: insertTextFormat, + insertTextMode: insertTextMode, textEdit: textEdit, additionalTextEdits: additionalTextEdits, commitCharacters: commitCharacters, @@ -3635,10 +6191,10 @@ class CompletionItem implements ToJsonable { /// described with the additionalTextEdits-property. final Command command; - /// An optional set of characters that when pressed, while this completion is - /// active, will accept it first and then type that character. - /// *Note* that all commit characters should have `length=1` and that - /// superfluous characters will be ignored. + /// An optional set of characters that when pressed while this completion is + /// active will accept it first and then type that character. *Note* that all + /// commit characters should have `length=1` and that superfluous characters + /// will be ignored. final List commitCharacters; /// A data entry field that is preserved on a completion item between a @@ -3664,18 +6220,24 @@ class CompletionItem implements ToJsonable { /// completion. When `falsy` the label is used. /// /// The `insertText` is subject to interpretation by the client side. Some - /// tools might not take the string literally. For example, VS Code when code + /// tools might not take the string literally. For example VS Code when code /// complete is requested in this example `con` and a - /// completion item with an `insertText` of `console` is provided, it will - /// only insert `sole`. Therefore, it is recommended to use `textEdit` instead - /// since it avoids additional client side interpretation. + /// completion item with an `insertText` of `console` is provided it will only + /// insert `sole`. Therefore it is recommended to use `textEdit` instead since + /// it avoids additional client side interpretation. final String insertText; /// The format of the insert text. The format applies to both the `insertText` - /// property and the `newText` property of a provided `textEdit`. If omitted, + /// property and the `newText` property of a provided `textEdit`. If omitted /// defaults to `InsertTextFormat.PlainText`. final InsertTextFormat insertTextFormat; + /// How whitespace and indentation is handled during completion item + /// insertion. If not provided the client's default value depends on the + /// `textDocument.completion.insertTextMode` client capability. + /// @since 3.16.0 - proposed state + final InsertTextMode insertTextMode; + /// The kind of this completion item. Based of the kind an icon is chosen by /// the editor. The standardized set of available values is defined in /// `CompletionItemKind`. @@ -3700,11 +6262,26 @@ class CompletionItem implements ToJsonable { /// @since 3.15.0 final List tags; - /// An edit that is applied to a document when selecting this completion. When - /// an edit is provided, the value of `insertText` is ignored. + /// An edit which is applied to a document when selecting this completion. + /// When an edit is provided the value of `insertText` is ignored. /// /// *Note:* The range of the edit must be a single line range and it must /// contain the position at which completion has been requested. + /// + /// Most editors support two different operations when accepting a completion + /// item. One is to insert a completion text and the other is to replace an + /// existing text with a completion text. Since this can usually not be + /// predetermined by a server it can report both ranges. Clients need to + /// signal support for `InsertReplaceEdits` via the + /// `textDocument.completion.insertReplaceSupport` client capability property. + /// + /// *Note 1:* The text edit's range as well as both ranges from an insert + /// replace edit must be a [single line] and they must contain the position at + /// which completion has been requested. + /// *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range + /// must be a prefix of the edit's replace range, that means it must be + /// contained and starting at the same position. + /// @since 3.16.0 additional type `InsertReplaceEdit` - proposed state final TextEdit textEdit; Map toJson() { @@ -3740,6 +6317,9 @@ class CompletionItem implements ToJsonable { if (insertTextFormat != null) { __result['insertTextFormat'] = insertTextFormat.toJson(); } + if (insertTextMode != null) { + __result['insertTextMode'] = insertTextMode.toJson(); + } if (textEdit != null) { __result['textEdit'] = textEdit.toJson(); } @@ -3875,6 +6455,16 @@ class CompletionItem implements ToJsonable { } finally { reporter.pop(); } + reporter.push('insertTextMode'); + try { + if (obj['insertTextMode'] != null && + !(InsertTextMode.canParse(obj['insertTextMode'], reporter))) { + reporter.reportError('must be of type InsertTextMode'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('textEdit'); try { if (obj['textEdit'] != null && @@ -3950,6 +6540,7 @@ class CompletionItem implements ToJsonable { filterText == other.filterText && insertText == other.insertText && insertTextFormat == other.insertTextFormat && + insertTextMode == other.insertTextMode && textEdit == other.textEdit && listEqual(additionalTextEdits, other.additionalTextEdits, (TextEdit a, TextEdit b) => a == b) && @@ -3976,6 +6567,7 @@ class CompletionItem implements ToJsonable { hash = JenkinsSmiHash.combine(hash, filterText.hashCode); hash = JenkinsSmiHash.combine(hash, insertText.hashCode); hash = JenkinsSmiHash.combine(hash, insertTextFormat.hashCode); + hash = JenkinsSmiHash.combine(hash, insertTextMode.hashCode); hash = JenkinsSmiHash.combine(hash, textEdit.hashCode); hash = JenkinsSmiHash.combine(hash, lspHashCode(additionalTextEdits)); hash = JenkinsSmiHash.combine(hash, lspHashCode(commitCharacters)); @@ -4202,11 +6794,11 @@ class CompletionOptions implements WorkDoneProgressOptions, ToJsonable { /// The list of all possible characters that commit a completion. This field /// can be used if clients don't support individual commit characters per - /// completion item. See `ClientCapabilities.` - /// `textDocument.completion.completionItem.commitCharactersSupport`. + /// completion item. See client capability + /// `completion.completionItem.commitCharactersSupport`. /// /// If a server provides both `allCommitCharacters` and commit characters on - /// an individual completion item, the ones on the completion item win. + /// an individual completion item the ones on the completion item win. /// @since 3.2.0 final List allCommitCharacters; @@ -4215,14 +6807,14 @@ class CompletionOptions implements WorkDoneProgressOptions, ToJsonable { final bool resolveProvider; /// Most tools trigger completion request automatically without explicitly - /// requesting it using a keyboard shortcut (for example Ctrl+Space). - /// Typically they do so when the user starts to type an identifier. For - /// example, if the user types `c` in a JavaScript file, code complete will - /// automatically display `console` along with others as a completion item. - /// Characters that make up identifiers don't need to be listed here. + /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they + /// do so when the user starts to type an identifier. For example if the user + /// types `c` in a JavaScript file code complete will automatically pop up + /// present `console` besides others as a completion item. Characters that + /// make up identifiers don't need to be listed here. /// - /// If code complete should automatically be triggered on characters not being - /// valid inside an identifier (for example `.` in JavaScript), list them in + /// If code complete should automatically be trigger on characters not being + /// valid inside an identifier (for example `.` in JavaScript) list them in /// `triggerCharacters`. final List triggerCharacters; final bool workDoneProgress; @@ -4378,12 +6970,11 @@ class CompletionParams } /// The completion context. This is only available if the client specifies to - /// send this using `ClientCapabilities.textDocument.completion.contextSupport - /// === true` + /// send this using the client capability `completion.contextSupport === true` final CompletionContext context; - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -4553,16 +7144,16 @@ class CompletionRegistrationOptions /// The list of all possible characters that commit a completion. This field /// can be used if clients don't support individual commit characters per - /// completion item. See `ClientCapabilities.` - /// `textDocument.completion.completionItem.commitCharactersSupport`. + /// completion item. See client capability + /// `completion.completionItem.commitCharactersSupport`. /// /// If a server provides both `allCommitCharacters` and commit characters on - /// an individual completion item, the ones on the completion item win. + /// an individual completion item the ones on the completion item win. /// @since 3.2.0 final List allCommitCharacters; /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The server provides support to resolve additional information for a @@ -4570,14 +7161,14 @@ class CompletionRegistrationOptions final bool resolveProvider; /// Most tools trigger completion request automatically without explicitly - /// requesting it using a keyboard shortcut (for example Ctrl+Space). - /// Typically they do so when the user starts to type an identifier. For - /// example, if the user types `c` in a JavaScript file, code complete will - /// automatically display `console` along with others as a completion item. - /// Characters that make up identifiers don't need to be listed here. + /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they + /// do so when the user starts to type an identifier. For example if the user + /// types `c` in a JavaScript file code complete will automatically pop up + /// present `console` besides others as a completion item. Characters that + /// make up identifiers don't need to be listed here. /// - /// If code complete should automatically be triggered on characters not being - /// valid inside an identifier (for example `.` in JavaScript), list them in + /// If code complete should automatically be trigger on characters not being + /// valid inside an identifier (for example `.` in JavaScript) list them in /// `triggerCharacters`. final List triggerCharacters; final bool workDoneProgress; @@ -4722,7 +7313,7 @@ class CompletionTriggerKind { static const Invoked = CompletionTriggerKind._(1); /// Completion was triggered by a trigger character specified by the - /// `triggerCharacters` properties of `CompletionRegistrationOptions`. + /// `triggerCharacters` properties of the `CompletionRegistrationOptions`. static const TriggerCharacter = CompletionTriggerKind._(2); /// Completion was re-triggered as the current completion list is incomplete. @@ -4895,7 +7486,11 @@ class CreateFile implements ToJsonable { static const jsonHandler = LspJsonHandler(CreateFile.canParse, CreateFile.fromJson); - CreateFile({this.kind = 'create', @required this.uri, this.options}) { + CreateFile( + {this.kind = 'create', + @required this.uri, + this.options, + this.annotationId}) { if (kind != 'create') { throw 'kind may only be the literal \'create\''; } @@ -4909,9 +7504,15 @@ class CreateFile implements ToJsonable { final options = json['options'] != null ? CreateFileOptions.fromJson(json['options']) : null; - return CreateFile(kind: kind, uri: uri, options: options); + final annotationId = json['annotationId']; + return CreateFile( + kind: kind, uri: uri, options: options, annotationId: annotationId); } + /// An optional annotation identifer describing the operation. + /// @since 3.16.0 - proposed state + final String annotationId; + /// A create final String kind; @@ -4928,6 +7529,9 @@ class CreateFile implements ToJsonable { if (options != null) { __result['options'] = options.toJson(); } + if (annotationId != null) { + __result['annotationId'] = annotationId; + } return __result; } @@ -4977,6 +7581,15 @@ class CreateFile implements ToJsonable { } finally { reporter.pop(); } + reporter.push('annotationId'); + try { + if (obj['annotationId'] != null && !(obj['annotationId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type CreateFile'); @@ -4990,6 +7603,7 @@ class CreateFile implements ToJsonable { return kind == other.kind && uri == other.uri && options == other.options && + annotationId == other.annotationId && true; } return false; @@ -5001,6 +7615,7 @@ class CreateFile implements ToJsonable { hash = JenkinsSmiHash.combine(hash, kind.hashCode); hash = JenkinsSmiHash.combine(hash, uri.hashCode); hash = JenkinsSmiHash.combine(hash, options.hashCode); + hash = JenkinsSmiHash.combine(hash, annotationId.hashCode); return JenkinsSmiHash.finish(hash); } @@ -5087,6 +7702,84 @@ class CreateFileOptions implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// The parameters sent in notifications/requests for user-initiated creation of +/// files. +/// @since 3.16.0 - proposed state +class CreateFilesParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(CreateFilesParams.canParse, CreateFilesParams.fromJson); + + CreateFilesParams({@required this.files}) { + if (files == null) { + throw 'files is required but was not provided'; + } + } + static CreateFilesParams fromJson(Map json) { + final files = json['files'] + ?.map((item) => item != null ? FileCreate.fromJson(item) : null) + ?.cast() + ?.toList(); + return CreateFilesParams(files: files); + } + + /// An array of all files/folders created in this operation. + final List files; + + Map toJson() { + var __result = {}; + __result['files'] = files ?? (throw 'files is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('files'); + try { + if (!obj.containsKey('files')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['files'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['files'] is List && + (obj['files'] + .every((item) => FileCreate.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type CreateFilesParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is CreateFilesParams && other.runtimeType == CreateFilesParams) { + return listEqual( + files, other.files, (FileCreate a, FileCreate b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(files)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class DeclarationClientCapabilities implements ToJsonable { static const jsonHandler = LspJsonHandler( DeclarationClientCapabilities.canParse, @@ -5101,8 +7794,8 @@ class DeclarationClientCapabilities implements ToJsonable { } /// Whether declaration supports dynamic registration. If this is set to - /// `true`, the client supports the new `DeclarationRegistrationOptions` - /// return value for the corresponding server capability as well. + /// `true` the client supports the new `DeclarationRegistrationOptions` return + /// value for the corresponding server capability as well. final bool dynamicRegistration; /// The client supports additional metadata in the form of declaration links. @@ -5280,8 +7973,8 @@ class DeclarationParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -5425,7 +8118,7 @@ class DeclarationRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -5706,8 +8399,8 @@ class DefinitionParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -5843,7 +8536,7 @@ class DefinitionRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -5920,7 +8613,11 @@ class DeleteFile implements ToJsonable { static const jsonHandler = LspJsonHandler(DeleteFile.canParse, DeleteFile.fromJson); - DeleteFile({this.kind = 'delete', @required this.uri, this.options}) { + DeleteFile( + {this.kind = 'delete', + @required this.uri, + this.options, + this.annotationId}) { if (kind != 'delete') { throw 'kind may only be the literal \'delete\''; } @@ -5934,9 +8631,15 @@ class DeleteFile implements ToJsonable { final options = json['options'] != null ? DeleteFileOptions.fromJson(json['options']) : null; - return DeleteFile(kind: kind, uri: uri, options: options); + final annotationId = json['annotationId']; + return DeleteFile( + kind: kind, uri: uri, options: options, annotationId: annotationId); } + /// An optional annotation identifer describing the operation. + /// @since 3.16.0 - proposed state + final String annotationId; + /// A delete final String kind; @@ -5953,6 +8656,9 @@ class DeleteFile implements ToJsonable { if (options != null) { __result['options'] = options.toJson(); } + if (annotationId != null) { + __result['annotationId'] = annotationId; + } return __result; } @@ -6002,6 +8708,15 @@ class DeleteFile implements ToJsonable { } finally { reporter.pop(); } + reporter.push('annotationId'); + try { + if (obj['annotationId'] != null && !(obj['annotationId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type DeleteFile'); @@ -6015,6 +8730,7 @@ class DeleteFile implements ToJsonable { return kind == other.kind && uri == other.uri && options == other.options && + annotationId == other.annotationId && true; } return false; @@ -6026,6 +8742,7 @@ class DeleteFile implements ToJsonable { hash = JenkinsSmiHash.combine(hash, kind.hashCode); hash = JenkinsSmiHash.combine(hash, uri.hashCode); hash = JenkinsSmiHash.combine(hash, options.hashCode); + hash = JenkinsSmiHash.combine(hash, annotationId.hashCode); return JenkinsSmiHash.finish(hash); } @@ -6113,6 +8830,84 @@ class DeleteFileOptions implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// The parameters sent in notifications/requests for user-initiated deletes of +/// files. +/// @since 3.16.0 - proposed state +class DeleteFilesParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(DeleteFilesParams.canParse, DeleteFilesParams.fromJson); + + DeleteFilesParams({@required this.files}) { + if (files == null) { + throw 'files is required but was not provided'; + } + } + static DeleteFilesParams fromJson(Map json) { + final files = json['files'] + ?.map((item) => item != null ? FileDelete.fromJson(item) : null) + ?.cast() + ?.toList(); + return DeleteFilesParams(files: files); + } + + /// An array of all files/folders deleted in this operation. + final List files; + + Map toJson() { + var __result = {}; + __result['files'] = files ?? (throw 'files is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('files'); + try { + if (!obj.containsKey('files')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['files'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['files'] is List && + (obj['files'] + .every((item) => FileDelete.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type DeleteFilesParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is DeleteFilesParams && other.runtimeType == DeleteFilesParams) { + return listEqual( + files, other.files, (FileDelete a, FileDelete b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(files)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class Diagnostic implements ToJsonable { static const jsonHandler = LspJsonHandler(Diagnostic.canParse, Diagnostic.fromJson); @@ -6121,10 +8916,12 @@ class Diagnostic implements ToJsonable { {@required this.range, this.severity, this.code, + this.codeDescription, this.source, @required this.message, this.tags, - this.relatedInformation}) { + this.relatedInformation, + this.data}) { if (range == null) { throw 'range is required but was not provided'; } @@ -6138,6 +8935,9 @@ class Diagnostic implements ToJsonable { ? DiagnosticSeverity.fromJson(json['severity']) : null; final code = json['code']; + final codeDescription = json['codeDescription'] != null + ? CodeDescription.fromJson(json['codeDescription']) + : null; final source = json['source']; final message = json['message']; final tags = json['tags'] @@ -6149,19 +8949,32 @@ class Diagnostic implements ToJsonable { item != null ? DiagnosticRelatedInformation.fromJson(item) : null) ?.cast() ?.toList(); + final data = json['data']; return Diagnostic( range: range, severity: severity, code: code, + codeDescription: codeDescription, source: source, message: message, tags: tags, - relatedInformation: relatedInformation); + relatedInformation: relatedInformation, + data: data); } /// The diagnostic's code, which might appear in the user interface. final String code; + /// An optional property to describe the error code. + /// @since 3.16.0 - proposed state + final CodeDescription codeDescription; + + /// A data entry field that is preserved between a + /// `textDocument/publishDiagnostics` notification and + /// `textDocument/codeAction` request. + /// @since 3.16.0 - proposed state + final dynamic data; + /// The diagnostic's message. final String message; @@ -6194,6 +9007,9 @@ class Diagnostic implements ToJsonable { if (code != null) { __result['code'] = code; } + if (codeDescription != null) { + __result['codeDescription'] = codeDescription.toJson(); + } if (source != null) { __result['source'] = source; } @@ -6205,6 +9021,9 @@ class Diagnostic implements ToJsonable { if (relatedInformation != null) { __result['relatedInformation'] = relatedInformation; } + if (data != null) { + __result['data'] = data; + } return __result; } @@ -6246,6 +9065,16 @@ class Diagnostic implements ToJsonable { } finally { reporter.pop(); } + reporter.push('codeDescription'); + try { + if (obj['codeDescription'] != null && + !(CodeDescription.canParse(obj['codeDescription'], reporter))) { + reporter.reportError('must be of type CodeDescription'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('source'); try { if (obj['source'] != null && !(obj['source'] is String)) { @@ -6297,6 +9126,15 @@ class Diagnostic implements ToJsonable { } finally { reporter.pop(); } + reporter.push('data'); + try { + if (obj['data'] != null && !(true)) { + reporter.reportError('must be of type dynamic'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type Diagnostic'); @@ -6310,6 +9148,7 @@ class Diagnostic implements ToJsonable { return range == other.range && severity == other.severity && code == other.code && + codeDescription == other.codeDescription && source == other.source && message == other.message && listEqual( @@ -6320,6 +9159,7 @@ class Diagnostic implements ToJsonable { (DiagnosticRelatedInformation a, DiagnosticRelatedInformation b) => a == b) && + data == other.data && true; } return false; @@ -6331,10 +9171,12 @@ class Diagnostic implements ToJsonable { hash = JenkinsSmiHash.combine(hash, range.hashCode); hash = JenkinsSmiHash.combine(hash, severity.hashCode); hash = JenkinsSmiHash.combine(hash, code.hashCode); + hash = JenkinsSmiHash.combine(hash, codeDescription.hashCode); hash = JenkinsSmiHash.combine(hash, source.hashCode); hash = JenkinsSmiHash.combine(hash, message.hashCode); hash = JenkinsSmiHash.combine(hash, lspHashCode(tags)); hash = JenkinsSmiHash.combine(hash, lspHashCode(relatedInformation)); + hash = JenkinsSmiHash.combine(hash, data.hashCode); return JenkinsSmiHash.finish(hash); } @@ -6344,7 +9186,7 @@ class Diagnostic implements ToJsonable { /// Represents a related message and source code location for a diagnostic. This /// should be used to point to code locations that cause or are related to a -/// diagnostics, for example, when duplicating a symbol in a scope. +/// diagnostics, e.g when duplicating a symbol in a scope. class DiagnosticRelatedInformation implements ToJsonable { static const jsonHandler = LspJsonHandler( DiagnosticRelatedInformation.canParse, @@ -6677,18 +9519,18 @@ class DidChangeTextDocumentParams implements ToJsonable { } /// The actual content changes. The content changes describe single state - /// changes to the document. If there are two content changes c1 (at array - /// index 0) and c2 (at array index 1) for a document in state S, then c1 - /// moves the document from S to S' and c2 from S' to S''. So c1 is computed - /// on the state S and c2 is computed on the state S'. + /// changes to the document. So if there are two content changes c1 (at array + /// index 0) and c2 (at array index 1) for a document in state S then c1 moves + /// the document from S to S' and c2 from S' to S''. So c1 is computed on the + /// state S and c2 is computed on the state S'. /// - /// To mirror the content of a document using change events, use the following + /// To mirror the content of a document using change events use the following /// approach: /// - start with the same initial content - /// - apply the 'textDocument/didChange' notifications - /// in the order you receive them. - /// - apply the `TextDocumentContentChangeEvent`s - /// in a single notification in the order you receive them. + /// - apply the 'textDocument/didChange' notifications in the order you + /// receive them. + /// - apply the `TextDocumentContentChangeEvent`s in a single notification + /// in the order you receive them. final List< Either2> contentChanges; @@ -7481,8 +10323,8 @@ class DocumentColorParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The text document. @@ -7603,7 +10445,7 @@ class DocumentColorRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -7714,13 +10556,13 @@ class DocumentFilter implements ToJsonable { /// - `*` to match one or more characters in a path segment /// - `?` to match on one character in a path segment /// - `**` to match any number of path segments, including none - /// - `{}` to group conditions - /// (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) + /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript + /// and JavaScript files) /// - `[]` to declare a range of characters to match in a path segment /// (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) /// - `[!...]` to negate a range of characters to match in a path segment - /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, - /// but not `example.0`) + /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + /// not `example.0`) final String pattern; /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`. @@ -8085,7 +10927,7 @@ class DocumentFormattingRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -8457,8 +11299,8 @@ class DocumentHighlightParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -8600,7 +11442,7 @@ class DocumentHighlightRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -8705,7 +11547,7 @@ class DocumentLink implements ToJsonable { /// The tooltip text when you hover over this link. /// - /// If a tooltip is provided, it will be displayed in a string that includes + /// If a tooltip is provided, is will be displayed in a string that includes /// instructions on how to trigger the link, such as `{0} (ctrl + click)`. The /// specific instructions vary depending on OS, user settings, and /// localization. @@ -9010,8 +11852,8 @@ class DocumentLinkParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The document to provide document links for. @@ -9131,7 +11973,7 @@ class DocumentLinkRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// Document links have a resolve provider as well. @@ -9593,7 +12435,7 @@ class DocumentOnTypeFormattingRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// A character on which formatting should be triggered, like `}`. @@ -10014,7 +12856,7 @@ class DocumentRangeFormattingRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -10090,7 +12932,7 @@ class DocumentRangeFormattingRegistrationOptions /// Represents programming constructs like variables, classes, interfaces etc. /// that appear in a document. Document symbols can be hierarchical and they /// have two ranges: one that encloses its definition and one that points to its -/// most interesting range, for example, the range of an identifier. +/// most interesting range, e.g. the range of an identifier. class DocumentSymbol implements ToJsonable { static const jsonHandler = LspJsonHandler(DocumentSymbol.canParse, DocumentSymbol.fromJson); @@ -10099,6 +12941,7 @@ class DocumentSymbol implements ToJsonable { {@required this.name, this.detail, @required this.kind, + this.tags, this.deprecated, @required this.range, @required this.selectionRange, @@ -10121,6 +12964,10 @@ class DocumentSymbol implements ToJsonable { final detail = json['detail']; final kind = json['kind'] != null ? SymbolKind.fromJson(json['kind']) : null; + final tags = json['tags'] + ?.map((item) => item != null ? SymbolTag.fromJson(item) : null) + ?.cast() + ?.toList(); final deprecated = json['deprecated']; final range = json['range'] != null ? Range.fromJson(json['range']) : null; final selectionRange = json['selectionRange'] != null @@ -10134,6 +12981,7 @@ class DocumentSymbol implements ToJsonable { name: name, detail: detail, kind: kind, + tags: tags, deprecated: deprecated, range: range, selectionRange: selectionRange, @@ -10144,6 +12992,7 @@ class DocumentSymbol implements ToJsonable { final List children; /// Indicates if this symbol is deprecated. + /// @deprecated Use tags instead final bool deprecated; /// More detail for this symbol, e.g the signature of a function. @@ -10159,15 +13008,18 @@ class DocumentSymbol implements ToJsonable { /// The range enclosing this symbol not including leading/trailing whitespace /// but everything else like comments. This information is typically used to - /// determine if the client's cursor is inside the symbol to reveal in the + /// determine if the clients cursor is inside the symbol to reveal in the /// symbol in the UI. final Range range; /// The range that should be selected and revealed when this symbol is being - /// picked, for example, the name of a function. Must be contained by the - /// `range`. + /// picked, e.g. the name of a function. Must be contained by the `range`. final Range selectionRange; + /// Tags for this document symbol. + /// @since 3.16.0 + final List tags; + Map toJson() { var __result = {}; __result['name'] = name ?? (throw 'name is required but was not set'); @@ -10176,6 +13028,9 @@ class DocumentSymbol implements ToJsonable { } __result['kind'] = kind?.toJson() ?? (throw 'kind is required but was not set'); + if (tags != null) { + __result['tags'] = tags; + } if (deprecated != null) { __result['deprecated'] = deprecated; } @@ -10234,6 +13089,18 @@ class DocumentSymbol implements ToJsonable { } finally { reporter.pop(); } + reporter.push('tags'); + try { + if (obj['tags'] != null && + !((obj['tags'] is List && + (obj['tags'] + .every((item) => SymbolTag.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('deprecated'); try { if (obj['deprecated'] != null && !(obj['deprecated'] is bool)) { @@ -10302,6 +13169,7 @@ class DocumentSymbol implements ToJsonable { return name == other.name && detail == other.detail && kind == other.kind && + listEqual(tags, other.tags, (SymbolTag a, SymbolTag b) => a == b) && deprecated == other.deprecated && range == other.range && selectionRange == other.selectionRange && @@ -10318,6 +13186,7 @@ class DocumentSymbol implements ToJsonable { hash = JenkinsSmiHash.combine(hash, name.hashCode); hash = JenkinsSmiHash.combine(hash, detail.hashCode); hash = JenkinsSmiHash.combine(hash, kind.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tags)); hash = JenkinsSmiHash.combine(hash, deprecated.hashCode); hash = JenkinsSmiHash.combine(hash, range.hashCode); hash = JenkinsSmiHash.combine(hash, selectionRange.hashCode); @@ -10337,7 +13206,9 @@ class DocumentSymbolClientCapabilities implements ToJsonable { DocumentSymbolClientCapabilities( {this.dynamicRegistration, this.symbolKind, - this.hierarchicalDocumentSymbolSupport}); + this.hierarchicalDocumentSymbolSupport, + this.tagSupport, + this.labelSupport}); static DocumentSymbolClientCapabilities fromJson(Map json) { final dynamicRegistration = json['dynamicRegistration']; final symbolKind = json['symbolKind'] != null @@ -10346,10 +13217,17 @@ class DocumentSymbolClientCapabilities implements ToJsonable { : null; final hierarchicalDocumentSymbolSupport = json['hierarchicalDocumentSymbolSupport']; + final tagSupport = json['tagSupport'] != null + ? DocumentSymbolClientCapabilitiesTagSupport.fromJson( + json['tagSupport']) + : null; + final labelSupport = json['labelSupport']; return DocumentSymbolClientCapabilities( dynamicRegistration: dynamicRegistration, symbolKind: symbolKind, - hierarchicalDocumentSymbolSupport: hierarchicalDocumentSymbolSupport); + hierarchicalDocumentSymbolSupport: hierarchicalDocumentSymbolSupport, + tagSupport: tagSupport, + labelSupport: labelSupport); } /// Whether document symbol supports dynamic registration. @@ -10358,10 +13236,21 @@ class DocumentSymbolClientCapabilities implements ToJsonable { /// The client supports hierarchical document symbols. final bool hierarchicalDocumentSymbolSupport; + /// The client supports an additional label presented in the UI when + /// registering a document symbol provider. + /// @since 3.16.0 + final bool labelSupport; + /// Specific capabilities for the `SymbolKind` in the /// `textDocument/documentSymbol` request. final DocumentSymbolClientCapabilitiesSymbolKind symbolKind; + /// The client supports tags on `SymbolInformation`. Tags are supported on + /// `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true. + /// Clients supporting tags have to handle unknown tags gracefully. + /// @since 3.16.0 + final DocumentSymbolClientCapabilitiesTagSupport tagSupport; + Map toJson() { var __result = {}; if (dynamicRegistration != null) { @@ -10374,6 +13263,12 @@ class DocumentSymbolClientCapabilities implements ToJsonable { __result['hierarchicalDocumentSymbolSupport'] = hierarchicalDocumentSymbolSupport; } + if (tagSupport != null) { + __result['tagSupport'] = tagSupport.toJson(); + } + if (labelSupport != null) { + __result['labelSupport'] = labelSupport; + } return __result; } @@ -10411,6 +13306,27 @@ class DocumentSymbolClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('tagSupport'); + try { + if (obj['tagSupport'] != null && + !(DocumentSymbolClientCapabilitiesTagSupport.canParse( + obj['tagSupport'], reporter))) { + reporter.reportError( + 'must be of type DocumentSymbolClientCapabilitiesTagSupport'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('labelSupport'); + try { + if (obj['labelSupport'] != null && !(obj['labelSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type DocumentSymbolClientCapabilities'); @@ -10426,6 +13342,8 @@ class DocumentSymbolClientCapabilities implements ToJsonable { symbolKind == other.symbolKind && hierarchicalDocumentSymbolSupport == other.hierarchicalDocumentSymbolSupport && + tagSupport == other.tagSupport && + labelSupport == other.labelSupport && true; } return false; @@ -10438,6 +13356,8 @@ class DocumentSymbolClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, symbolKind.hashCode); hash = JenkinsSmiHash.combine( hash, hierarchicalDocumentSymbolSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, tagSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, labelSupport.hashCode); return JenkinsSmiHash.finish(hash); } @@ -10520,23 +13440,112 @@ class DocumentSymbolClientCapabilitiesSymbolKind implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class DocumentSymbolClientCapabilitiesTagSupport implements ToJsonable { + static const jsonHandler = LspJsonHandler( + DocumentSymbolClientCapabilitiesTagSupport.canParse, + DocumentSymbolClientCapabilitiesTagSupport.fromJson); + + DocumentSymbolClientCapabilitiesTagSupport({@required this.valueSet}) { + if (valueSet == null) { + throw 'valueSet is required but was not provided'; + } + } + static DocumentSymbolClientCapabilitiesTagSupport fromJson( + Map json) { + final valueSet = json['valueSet'] + ?.map((item) => item != null ? SymbolTag.fromJson(item) : null) + ?.cast() + ?.toList(); + return DocumentSymbolClientCapabilitiesTagSupport(valueSet: valueSet); + } + + /// The tags supported by the client. + final List valueSet; + + Map toJson() { + var __result = {}; + __result['valueSet'] = + valueSet ?? (throw 'valueSet is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('valueSet'); + try { + if (!obj.containsKey('valueSet')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['valueSet'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['valueSet'] is List && + (obj['valueSet'] + .every((item) => SymbolTag.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type DocumentSymbolClientCapabilitiesTagSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is DocumentSymbolClientCapabilitiesTagSupport && + other.runtimeType == DocumentSymbolClientCapabilitiesTagSupport) { + return listEqual( + valueSet, other.valueSet, (SymbolTag a, SymbolTag b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(valueSet)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class DocumentSymbolOptions implements WorkDoneProgressOptions, ToJsonable { static const jsonHandler = LspJsonHandler( DocumentSymbolOptions.canParse, DocumentSymbolOptions.fromJson); - DocumentSymbolOptions({this.workDoneProgress}); + DocumentSymbolOptions({this.label, this.workDoneProgress}); static DocumentSymbolOptions fromJson(Map json) { if (DocumentSymbolRegistrationOptions.canParse(json, nullLspJsonReporter)) { return DocumentSymbolRegistrationOptions.fromJson(json); } + final label = json['label']; final workDoneProgress = json['workDoneProgress']; - return DocumentSymbolOptions(workDoneProgress: workDoneProgress); + return DocumentSymbolOptions( + label: label, workDoneProgress: workDoneProgress); } + /// A human-readable string that is shown when multiple outlines trees are + /// shown for the same document. + /// @since 3.16.0 - proposed state + final String label; final bool workDoneProgress; Map toJson() { var __result = {}; + if (label != null) { + __result['label'] = label; + } if (workDoneProgress != null) { __result['workDoneProgress'] = workDoneProgress; } @@ -10545,6 +13554,15 @@ class DocumentSymbolOptions implements WorkDoneProgressOptions, ToJsonable { static bool canParse(Object obj, LspJsonReporter reporter) { if (obj is Map) { + reporter.push('label'); + try { + if (obj['label'] != null && !(obj['label'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('workDoneProgress'); try { if (obj['workDoneProgress'] != null && @@ -10566,7 +13584,9 @@ class DocumentSymbolOptions implements WorkDoneProgressOptions, ToJsonable { bool operator ==(Object other) { if (other is DocumentSymbolOptions && other.runtimeType == DocumentSymbolOptions) { - return workDoneProgress == other.workDoneProgress && true; + return label == other.label && + workDoneProgress == other.workDoneProgress && + true; } return false; } @@ -10574,6 +13594,7 @@ class DocumentSymbolOptions implements WorkDoneProgressOptions, ToJsonable { @override int get hashCode { var hash = 0; + hash = JenkinsSmiHash.combine(hash, label.hashCode); hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); return JenkinsSmiHash.finish(hash); } @@ -10619,8 +13640,8 @@ class DocumentSymbolParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The text document. @@ -10725,25 +13746,36 @@ class DocumentSymbolRegistrationOptions DocumentSymbolRegistrationOptions.fromJson); DocumentSymbolRegistrationOptions( - {this.documentSelector, this.workDoneProgress}); + {this.documentSelector, this.label, this.workDoneProgress}); static DocumentSymbolRegistrationOptions fromJson(Map json) { final documentSelector = json['documentSelector'] ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) ?.cast() ?.toList(); + final label = json['label']; final workDoneProgress = json['workDoneProgress']; return DocumentSymbolRegistrationOptions( - documentSelector: documentSelector, workDoneProgress: workDoneProgress); + documentSelector: documentSelector, + label: label, + workDoneProgress: workDoneProgress); } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; + + /// A human-readable string that is shown when multiple outlines trees are + /// shown for the same document. + /// @since 3.16.0 - proposed state + final String label; final bool workDoneProgress; Map toJson() { var __result = {}; __result['documentSelector'] = documentSelector; + if (label != null) { + __result['label'] = label; + } if (workDoneProgress != null) { __result['workDoneProgress'] = workDoneProgress; } @@ -10768,6 +13800,15 @@ class DocumentSymbolRegistrationOptions } finally { reporter.pop(); } + reporter.push('label'); + try { + if (obj['label'] != null && !(obj['label'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('workDoneProgress'); try { if (obj['workDoneProgress'] != null && @@ -10791,6 +13832,7 @@ class DocumentSymbolRegistrationOptions other.runtimeType == DocumentSymbolRegistrationOptions) { return listEqual(documentSelector, other.documentSelector, (DocumentFilter a, DocumentFilter b) => a == b) && + label == other.label && workDoneProgress == other.workDoneProgress && true; } @@ -10801,6 +13843,7 @@ class DocumentSymbolRegistrationOptions int get hashCode { var hash = 0; hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); + hash = JenkinsSmiHash.combine(hash, label.hashCode); hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); return JenkinsSmiHash.finish(hash); } @@ -10825,14 +13868,31 @@ class ErrorCodes { static const MethodNotFound = ErrorCodes(-32601); static const InvalidParams = ErrorCodes(-32602); static const InternalError = ErrorCodes(-32603); - static const serverErrorStart = ErrorCodes(-32099); - static const serverErrorEnd = ErrorCodes(-32000); + + /// This is the start range of JSON RPC reserved error codes. It doesn't + /// denote a real error code. No LSP error codes should be defined between the + /// start and end range. For backwards compatibility the + /// `ServerNotInitialized` and the `UnknownErrorCode` are left in the range. + /// @since 3.16.0 + static const jsonrpcReservedErrorRangeStart = ErrorCodes(-32099); static const ServerNotInitialized = ErrorCodes(-32002); static const UnknownErrorCode = ErrorCodes(-32001); - /// Defined by the protocol. - static const RequestCancelled = ErrorCodes(-32800); + /// This is the start range of JSON RPC reserved error codes. It doesn't + /// denote a real error code. + static const jsonrpcReservedErrorRangeEnd = ErrorCodes(-32000); + + /// This is the start range of LSP reserved error codes. It doesn't denote a + /// real error code. + /// @since 3.16.0 + static const lspReservedErrorRangeStart = ErrorCodes(-32899); static const ContentModified = ErrorCodes(-32801); + static const RequestCancelled = ErrorCodes(-32800); + + /// This is the end range of LSP reserved error codes. It doesn't denote a + /// real error code. + /// @since 3.16.0 + static const lspReservedErrorRangeEnd = ErrorCodes(-32800); Object toJson() => _value; @@ -11245,9 +14305,9 @@ class FailureHandlingKind { /// succeed or no changes at all are applied to the workspace. static const Transactional = FailureHandlingKind._('transactional'); - /// If the workspace edit contains only textual file changes, they are - /// executed transactionally. If resource changes (create, rename or delete - /// file) are part of the change, the failure handling strategy is abort. + /// If the workspace edit contains only textual file changes they are executed + /// transactional. If resource changes (create, rename or delete file) are + /// part of the change the failure handling strategy is abort. static const TextOnlyTransactional = FailureHandlingKind._('textOnlyTransactional'); @@ -11297,6 +14357,146 @@ class FileChangeType { bool operator ==(Object o) => o is FileChangeType && o._value == _value; } +/// Represents information on a file/folder create. +/// @since 3.16.0 - proposed state +class FileCreate implements ToJsonable { + static const jsonHandler = + LspJsonHandler(FileCreate.canParse, FileCreate.fromJson); + + FileCreate({@required this.uri}) { + if (uri == null) { + throw 'uri is required but was not provided'; + } + } + static FileCreate fromJson(Map json) { + final uri = json['uri']; + return FileCreate(uri: uri); + } + + /// A file:// URI for the location of the file/folder being created. + final String uri; + + Map toJson() { + var __result = {}; + __result['uri'] = uri ?? (throw 'uri is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('uri'); + try { + if (!obj.containsKey('uri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['uri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['uri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileCreate'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileCreate && other.runtimeType == FileCreate) { + return uri == other.uri && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, uri.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// Represents information on a file/folder delete. +/// @since 3.16.0 - proposed state +class FileDelete implements ToJsonable { + static const jsonHandler = + LspJsonHandler(FileDelete.canParse, FileDelete.fromJson); + + FileDelete({@required this.uri}) { + if (uri == null) { + throw 'uri is required but was not provided'; + } + } + static FileDelete fromJson(Map json) { + final uri = json['uri']; + return FileDelete(uri: uri); + } + + /// A file:// URI for the location of the file/folder being deleted. + final String uri; + + Map toJson() { + var __result = {}; + __result['uri'] = uri ?? (throw 'uri is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('uri'); + try { + if (!obj.containsKey('uri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['uri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['uri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileDelete'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileDelete && other.runtimeType == FileDelete) { + return uri == other.uri && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, uri.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// An event describing a file change. class FileEvent implements ToJsonable { static const jsonHandler = @@ -11392,6 +14592,401 @@ class FileEvent implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// A pattern to describe in which file operation requests or notifications the +/// server is interested in. +/// @since 3.16.0 - proposed state +class FileOperationPattern implements ToJsonable { + static const jsonHandler = LspJsonHandler( + FileOperationPattern.canParse, FileOperationPattern.fromJson); + + FileOperationPattern({@required this.glob, this.matches, this.options}) { + if (glob == null) { + throw 'glob is required but was not provided'; + } + } + static FileOperationPattern fromJson(Map json) { + final glob = json['glob']; + final matches = json['matches'] != null + ? FileOperationPatternKind.fromJson(json['matches']) + : null; + final options = json['options'] != null + ? FileOperationPatternOptions.fromJson(json['options']) + : null; + return FileOperationPattern(glob: glob, matches: matches, options: options); + } + + /// The glob pattern to match. Glob patterns can have the following syntax: + /// - `*` to match one or more characters in a path segment + /// - `?` to match on one character in a path segment + /// - `**` to match any number of path segments, including none + /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript + /// and JavaScript files) + /// - `[]` to declare a range of characters to match in a path segment + /// (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + /// - `[!...]` to negate a range of characters to match in a path segment + /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + /// not `example.0`) + final String glob; + + /// Whether to match files or folders with this pattern. + /// + /// Matches both if undefined. + final FileOperationPatternKind matches; + + /// Additional options used during matching. + final FileOperationPatternOptions options; + + Map toJson() { + var __result = {}; + __result['glob'] = glob ?? (throw 'glob is required but was not set'); + if (matches != null) { + __result['matches'] = matches.toJson(); + } + if (options != null) { + __result['options'] = options.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('glob'); + try { + if (!obj.containsKey('glob')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['glob'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['glob'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('matches'); + try { + if (obj['matches'] != null && + !(FileOperationPatternKind.canParse(obj['matches'], reporter))) { + reporter.reportError('must be of type FileOperationPatternKind'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('options'); + try { + if (obj['options'] != null && + !(FileOperationPatternOptions.canParse(obj['options'], reporter))) { + reporter.reportError('must be of type FileOperationPatternOptions'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileOperationPattern'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileOperationPattern && + other.runtimeType == FileOperationPattern) { + return glob == other.glob && + matches == other.matches && + options == other.options && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, glob.hashCode); + hash = JenkinsSmiHash.combine(hash, matches.hashCode); + hash = JenkinsSmiHash.combine(hash, options.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// A pattern kind describing if a glob pattern matches a file a folder or both. +/// @since 3.16.0 - proposed state +class FileOperationPatternKind { + const FileOperationPatternKind(this._value); + const FileOperationPatternKind.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + /// The pattern matches a file only. + static const file = FileOperationPatternKind(r'file'); + + /// The pattern matches a folder only. + static const folder = FileOperationPatternKind(r'folder'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => + o is FileOperationPatternKind && o._value == _value; +} + +/// Matching options for the file operation pattern. +/// @since 3.16.0 - proposed state +class FileOperationPatternOptions implements ToJsonable { + static const jsonHandler = LspJsonHandler( + FileOperationPatternOptions.canParse, + FileOperationPatternOptions.fromJson); + + FileOperationPatternOptions({this.ignoreCase}); + static FileOperationPatternOptions fromJson(Map json) { + final ignoreCase = json['ignoreCase']; + return FileOperationPatternOptions(ignoreCase: ignoreCase); + } + + /// The pattern should be matched ignoring casing. + final bool ignoreCase; + + Map toJson() { + var __result = {}; + if (ignoreCase != null) { + __result['ignoreCase'] = ignoreCase; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('ignoreCase'); + try { + if (obj['ignoreCase'] != null && !(obj['ignoreCase'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileOperationPatternOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileOperationPatternOptions && + other.runtimeType == FileOperationPatternOptions) { + return ignoreCase == other.ignoreCase && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, ignoreCase.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// The options to register for file operations. +/// @since 3.16.0 - proposed state +class FileOperationRegistrationOptions implements ToJsonable { + static const jsonHandler = LspJsonHandler( + FileOperationRegistrationOptions.canParse, + FileOperationRegistrationOptions.fromJson); + + FileOperationRegistrationOptions({@required this.patterns}) { + if (patterns == null) { + throw 'patterns is required but was not provided'; + } + } + static FileOperationRegistrationOptions fromJson(Map json) { + final patterns = json['patterns'] + ?.map( + (item) => item != null ? FileOperationPattern.fromJson(item) : null) + ?.cast() + ?.toList(); + return FileOperationRegistrationOptions(patterns: patterns); + } + + final List patterns; + + Map toJson() { + var __result = {}; + __result['patterns'] = + patterns ?? (throw 'patterns is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('patterns'); + try { + if (!obj.containsKey('patterns')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['patterns'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['patterns'] is List && + (obj['patterns'].every( + (item) => FileOperationPattern.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileOperationRegistrationOptions && + other.runtimeType == FileOperationRegistrationOptions) { + return listEqual(patterns, other.patterns, + (FileOperationPattern a, FileOperationPattern b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(patterns)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// Represents information on a file/folder rename. +/// @since 3.16.0 - proposed state +class FileRename implements ToJsonable { + static const jsonHandler = + LspJsonHandler(FileRename.canParse, FileRename.fromJson); + + FileRename({@required this.oldUri, @required this.newUri}) { + if (oldUri == null) { + throw 'oldUri is required but was not provided'; + } + if (newUri == null) { + throw 'newUri is required but was not provided'; + } + } + static FileRename fromJson(Map json) { + final oldUri = json['oldUri']; + final newUri = json['newUri']; + return FileRename(oldUri: oldUri, newUri: newUri); + } + + /// A file:// URI for the new location of the file/folder being renamed. + final String newUri; + + /// A file:// URI for the original location of the file/folder being renamed. + final String oldUri; + + Map toJson() { + var __result = {}; + __result['oldUri'] = oldUri ?? (throw 'oldUri is required but was not set'); + __result['newUri'] = newUri ?? (throw 'newUri is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('oldUri'); + try { + if (!obj.containsKey('oldUri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['oldUri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['oldUri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('newUri'); + try { + if (!obj.containsKey('newUri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['newUri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['newUri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type FileRename'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is FileRename && other.runtimeType == FileRename) { + return oldUri == other.oldUri && newUri == other.newUri && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, oldUri.hashCode); + hash = JenkinsSmiHash.combine(hash, newUri.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class FileSystemWatcher implements ToJsonable { static const jsonHandler = LspJsonHandler(FileSystemWatcher.canParse, FileSystemWatcher.fromJson); @@ -11418,8 +15013,8 @@ class FileSystemWatcher implements ToJsonable { /// - `[]` to declare a range of characters to match in a path segment /// (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) /// - `[!...]` to negate a range of characters to match in a path segment - /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, - /// but not `example.0`) + /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not + /// `example.0`) final String globPattern; /// The kind of events of interest. If omitted it defaults to WatchKind.Create @@ -11492,7 +15087,9 @@ class FileSystemWatcher implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } -/// Represents a folding range. +/// Represents a folding range. To be valid, start and end line must be bigger +/// than zero and smaller than the number of lines in the document. Clients are +/// free to ignore invalid ranges. class FoldingRange implements ToJsonable { static const jsonHandler = LspJsonHandler(FoldingRange.canParse, FoldingRange.fromJson); @@ -11529,7 +15126,9 @@ class FoldingRange implements ToJsonable { /// defined, defaults to the length of the end line. final num endCharacter; - /// The zero-based line number where the folded range ends. + /// The zero-based end line of the range to fold. The folded area ends with + /// the line's last character. To be valid, the end must be zero or larger and + /// smaller than the number of lines in the document. final num endLine; /// Describes the kind of the folding range such as `comment` or `region`. The @@ -11542,7 +15141,9 @@ class FoldingRange implements ToJsonable { /// defined, defaults to the length of the start line. final num startCharacter; - /// The zero-based line number from where the folded range starts. + /// The zero-based start line of the range to fold. The folded area starts + /// after the line's last character. To be valid, the end must be zero or + /// larger and smaller than the number of lines in the document. final num startLine; Map toJson() { @@ -11679,15 +15280,15 @@ class FoldingRangeClientCapabilities implements ToJsonable { lineFoldingOnly: lineFoldingOnly); } - /// Whether the implementation supports dynamic registration for folding range - /// providers. If this is set to `true`, the client supports the new + /// Whether implementation supports dynamic registration for folding range + /// providers. If this is set to `true` the client supports the new /// `FoldingRangeRegistrationOptions` return value for the corresponding /// server capability as well. final bool dynamicRegistration; /// If set, the client signals that it only supports folding complete lines. - /// If set, the client will ignore specified `startCharacter` and - /// `endCharacter` properties in a FoldingRange. + /// If set, client will ignore specified `startCharacter` and `endCharacter` + /// properties in a FoldingRange. final bool lineFoldingOnly; /// The maximum number of folding ranges that the client prefers to receive @@ -11902,8 +15503,8 @@ class FoldingRangeParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The text document. @@ -12024,7 +15625,7 @@ class FoldingRangeRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -12393,8 +15994,9 @@ class HoverClientCapabilities implements ToJsonable { dynamicRegistration: dynamicRegistration, contentFormat: contentFormat); } - /// Client supports the follow content formats for the content property. The - /// order describes the preferred format of the client. + /// Client supports the follow content formats if the content property refers + /// to a `literal of type MarkupContent`. The order describes the preferred + /// format of the client. final List contentFormat; /// Whether hover supports dynamic registration. @@ -12678,7 +16280,7 @@ class HoverRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -12765,7 +16367,7 @@ class ImplementationClientCapabilities implements ToJsonable { } /// Whether implementation supports dynamic registration. If this is set to - /// `true`, the client supports the new `ImplementationRegistrationOptions` + /// `true` the client supports the new `ImplementationRegistrationOptions` /// return value for the corresponding server capability as well. final bool dynamicRegistration; @@ -12945,8 +16547,8 @@ class ImplementationParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -13091,7 +16693,7 @@ class ImplementationRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -13188,6 +16790,7 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { InitializeParams( {this.processId, this.clientInfo, + this.locale, this.rootPath, this.rootUri, this.initializationOptions, @@ -13204,16 +16807,17 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { final clientInfo = json['clientInfo'] != null ? InitializeParamsClientInfo.fromJson(json['clientInfo']) : null; + final locale = json['locale']; final rootPath = json['rootPath']; final rootUri = json['rootUri']; final initializationOptions = json['initializationOptions']; final capabilities = json['capabilities'] != null ? ClientCapabilities.fromJson(json['capabilities']) : null; - final trace = const {null, 'off', 'messages', 'verbose'} + final trace = const {null, 'off', 'message', 'verbose'} .contains(json['trace']) ? json['trace'] - : throw '''${json['trace']} was not one of (null, 'off', 'messages', 'verbose')'''; + : throw '''${json['trace']} was not one of (null, 'off', 'message', 'verbose')'''; final workspaceFolders = json['workspaceFolders'] ?.map((item) => item != null ? WorkspaceFolder.fromJson(item) : null) ?.cast() @@ -13228,6 +16832,7 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { return InitializeParams( processId: processId, clientInfo: clientInfo, + locale: locale, rootPath: rootPath, rootUri: rootUri, initializationOptions: initializationOptions, @@ -13247,18 +16852,27 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { /// User provided initialization options. final dynamic initializationOptions; - /// The process ID of the parent process that started the server. Is null if + /// The locale the client is currently showing the user interface in. This + /// must not necessarily be the locale of the operating system. + /// + /// Uses IETF language tags as the value's syntax (See + /// https://en.wikipedia.org/wiki/IETF_language_tag) + /// @since 3.16.0 - proposed state + final String locale; + + /// The process Id of the parent process that started the server. Is null if /// the process has not been started by another process. If the parent process - /// is not alive, then the server should exit (see exit notification) its + /// is not alive then the server should exit (see exit notification) its /// process. final num processId; /// The rootPath of the workspace. Is null if no folder is open. - /// @deprecated in favour of rootUri. + /// @deprecated in favour of `rootUri`. final String rootPath; /// The rootUri of the workspace. Is null if no folder is open. If both /// `rootPath` and `rootUri` are set `rootUri` wins. + /// @deprecated in favour of `workspaceFolders` final String rootUri; /// The initial trace setting. If omitted trace is disabled ('off'). @@ -13280,6 +16894,9 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { if (clientInfo != null) { __result['clientInfo'] = clientInfo.toJson(); } + if (locale != null) { + __result['locale'] = locale; + } if (rootPath != null) { __result['rootPath'] = rootPath; } @@ -13327,6 +16944,15 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { } finally { reporter.pop(); } + reporter.push('locale'); + try { + if (obj['locale'] != null && !(obj['locale'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('rootPath'); try { if (obj['rootPath'] != null && !(obj['rootPath'] is String)) { @@ -13379,10 +17005,9 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { try { if (obj['trace'] != null && !((obj['trace'] == 'off' || - obj['trace'] == 'messages' || + obj['trace'] == 'message' || obj['trace'] == 'verbose'))) { - reporter.reportError( - 'must be one of the literals \'off\', \'messages\', \'verbose\''); + reporter.reportError('must be of type String'); return false; } } finally { @@ -13423,6 +17048,7 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { if (other is InitializeParams && other.runtimeType == InitializeParams) { return processId == other.processId && clientInfo == other.clientInfo && + locale == other.locale && rootPath == other.rootPath && rootUri == other.rootUri && initializationOptions == other.initializationOptions && @@ -13441,6 +17067,7 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, processId.hashCode); hash = JenkinsSmiHash.combine(hash, clientInfo.hashCode); + hash = JenkinsSmiHash.combine(hash, locale.hashCode); hash = JenkinsSmiHash.combine(hash, rootPath.hashCode); hash = JenkinsSmiHash.combine(hash, rootUri.hashCode); hash = JenkinsSmiHash.combine(hash, initializationOptions.hashCode); @@ -13762,6 +17389,138 @@ class InitializedParams implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// A special text edit to provide an insert and a replace operation. +/// @since 3.16.0 - proposed state +class InsertReplaceEdit implements ToJsonable { + static const jsonHandler = + LspJsonHandler(InsertReplaceEdit.canParse, InsertReplaceEdit.fromJson); + + InsertReplaceEdit( + {@required this.newText, @required this.insert, @required this.replace}) { + if (newText == null) { + throw 'newText is required but was not provided'; + } + if (insert == null) { + throw 'insert is required but was not provided'; + } + if (replace == null) { + throw 'replace is required but was not provided'; + } + } + static InsertReplaceEdit fromJson(Map json) { + final newText = json['newText']; + final insert = + json['insert'] != null ? Range.fromJson(json['insert']) : null; + final replace = + json['replace'] != null ? Range.fromJson(json['replace']) : null; + return InsertReplaceEdit( + newText: newText, insert: insert, replace: replace); + } + + /// The range if the insert is requested + final Range insert; + + /// The string to be inserted. + final String newText; + + /// The range if the replace is requested. + final Range replace; + + Map toJson() { + var __result = {}; + __result['newText'] = + newText ?? (throw 'newText is required but was not set'); + __result['insert'] = + insert?.toJson() ?? (throw 'insert is required but was not set'); + __result['replace'] = + replace?.toJson() ?? (throw 'replace is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('newText'); + try { + if (!obj.containsKey('newText')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['newText'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['newText'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('insert'); + try { + if (!obj.containsKey('insert')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['insert'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['insert'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('replace'); + try { + if (!obj.containsKey('replace')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['replace'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['replace'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type InsertReplaceEdit'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is InsertReplaceEdit && other.runtimeType == InsertReplaceEdit) { + return newText == other.newText && + insert == other.insert && + replace == other.replace && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, newText.hashCode); + hash = JenkinsSmiHash.combine(hash, insert.hashCode); + hash = JenkinsSmiHash.combine(hash, replace.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// Defines whether the insert text in a completion item should be interpreted /// as plain text or a snippet. class InsertTextFormat { @@ -13801,6 +17560,522 @@ class InsertTextFormat { bool operator ==(Object o) => o is InsertTextFormat && o._value == _value; } +/// How whitespace and indentation is handled during completion item insertion. +/// @since 3.16.0 - proposed state +class InsertTextMode { + const InsertTextMode(this._value); + const InsertTextMode.fromJson(this._value); + + final num _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is num; + } + + /// The insertion or replace strings is taken as it is. If the value is multi + /// line the lines below the cursor will be inserted using the indentation + /// defined in the string value. The client will not apply any kind of + /// adjustments to the string. + static const asIs = InsertTextMode(1); + + /// The editor adjusts leading whitespace of new lines so that they match the + /// indentation up to the cursor of the line for which the item is accepted. + /// + /// Consider a line like this: <2tabs><3tabs>foo. Accepting a multi + /// line completion item is indented using 2 tabs and all following lines + /// inserted will be indented using 2 tabs as well. + static const adjustIndentation = InsertTextMode(2); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is InsertTextMode && o._value == _value; +} + +class LinkedEditingRangeClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + LinkedEditingRangeClientCapabilities.canParse, + LinkedEditingRangeClientCapabilities.fromJson); + + LinkedEditingRangeClientCapabilities({this.dynamicRegistration}); + static LinkedEditingRangeClientCapabilities fromJson( + Map json) { + final dynamicRegistration = json['dynamicRegistration']; + return LinkedEditingRangeClientCapabilities( + dynamicRegistration: dynamicRegistration); + } + + /// Whether implementation supports dynamic registration. If this is set to + /// `true` the client supports the new `(TextDocumentRegistrationOptions & + /// StaticRegistrationOptions)` return value for the corresponding server + /// capability as well. + final bool dynamicRegistration; + + Map toJson() { + var __result = {}; + if (dynamicRegistration != null) { + __result['dynamicRegistration'] = dynamicRegistration; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('dynamicRegistration'); + try { + if (obj['dynamicRegistration'] != null && + !(obj['dynamicRegistration'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type LinkedEditingRangeClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LinkedEditingRangeClientCapabilities && + other.runtimeType == LinkedEditingRangeClientCapabilities) { + return dynamicRegistration == other.dynamicRegistration && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class LinkedEditingRangeOptions implements WorkDoneProgressOptions, ToJsonable { + static const jsonHandler = LspJsonHandler( + LinkedEditingRangeOptions.canParse, LinkedEditingRangeOptions.fromJson); + + LinkedEditingRangeOptions({this.workDoneProgress}); + static LinkedEditingRangeOptions fromJson(Map json) { + if (LinkedEditingRangeRegistrationOptions.canParse( + json, nullLspJsonReporter)) { + return LinkedEditingRangeRegistrationOptions.fromJson(json); + } + final workDoneProgress = json['workDoneProgress']; + return LinkedEditingRangeOptions(workDoneProgress: workDoneProgress); + } + + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type LinkedEditingRangeOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LinkedEditingRangeOptions && + other.runtimeType == LinkedEditingRangeOptions) { + return workDoneProgress == other.workDoneProgress && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class LinkedEditingRangeParams + implements TextDocumentPositionParams, WorkDoneProgressParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + LinkedEditingRangeParams.canParse, LinkedEditingRangeParams.fromJson); + + LinkedEditingRangeParams( + {@required this.textDocument, + @required this.position, + this.workDoneToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + if (position == null) { + throw 'position is required but was not provided'; + } + } + static LinkedEditingRangeParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final position = + json['position'] != null ? Position.fromJson(json['position']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + return LinkedEditingRangeParams( + textDocument: textDocument, + position: position, + workDoneToken: workDoneToken); + } + + /// The position inside the text document. + final Position position; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + __result['position'] = + position?.toJson() ?? (throw 'position is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('position'); + try { + if (!obj.containsKey('position')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['position'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Position.canParse(obj['position'], reporter))) { + reporter.reportError('must be of type Position'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type LinkedEditingRangeParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LinkedEditingRangeParams && + other.runtimeType == LinkedEditingRangeParams) { + return textDocument == other.textDocument && + position == other.position && + workDoneToken == other.workDoneToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, position.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class LinkedEditingRangeRegistrationOptions + implements + TextDocumentRegistrationOptions, + LinkedEditingRangeOptions, + StaticRegistrationOptions, + ToJsonable { + static const jsonHandler = LspJsonHandler( + LinkedEditingRangeRegistrationOptions.canParse, + LinkedEditingRangeRegistrationOptions.fromJson); + + LinkedEditingRangeRegistrationOptions( + {this.documentSelector, this.workDoneProgress, this.id}); + static LinkedEditingRangeRegistrationOptions fromJson( + Map json) { + final documentSelector = json['documentSelector'] + ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) + ?.cast() + ?.toList(); + final workDoneProgress = json['workDoneProgress']; + final id = json['id']; + return LinkedEditingRangeRegistrationOptions( + documentSelector: documentSelector, + workDoneProgress: workDoneProgress, + id: id); + } + + /// A document selector to identify the scope of the registration. If set to + /// null the document selector provided on the client side will be used. + final List documentSelector; + + /// The id used to register the request. The id can be used to deregister the + /// request again. See also Registration#id. + final String id; + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + __result['documentSelector'] = documentSelector; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + if (id != null) { + __result['id'] = id; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('documentSelector'); + try { + if (!obj.containsKey('documentSelector')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['documentSelector'] != null && + !((obj['documentSelector'] is List && + (obj['documentSelector'].every( + (item) => DocumentFilter.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('id'); + try { + if (obj['id'] != null && !(obj['id'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type LinkedEditingRangeRegistrationOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LinkedEditingRangeRegistrationOptions && + other.runtimeType == LinkedEditingRangeRegistrationOptions) { + return listEqual(documentSelector, other.documentSelector, + (DocumentFilter a, DocumentFilter b) => a == b) && + workDoneProgress == other.workDoneProgress && + id == other.id && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + hash = JenkinsSmiHash.combine(hash, id.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class LinkedEditingRanges implements ToJsonable { + static const jsonHandler = LspJsonHandler( + LinkedEditingRanges.canParse, LinkedEditingRanges.fromJson); + + LinkedEditingRanges({@required this.ranges, this.wordPattern}) { + if (ranges == null) { + throw 'ranges is required but was not provided'; + } + } + static LinkedEditingRanges fromJson(Map json) { + final ranges = json['ranges'] + ?.map((item) => item != null ? Range.fromJson(item) : null) + ?.cast() + ?.toList(); + final wordPattern = json['wordPattern']; + return LinkedEditingRanges(ranges: ranges, wordPattern: wordPattern); + } + + /// A list of ranges that can be renamed together. The ranges must have + /// identical length and contain identical text content. The ranges cannot + /// overlap. + final List ranges; + + /// An optional word pattern (regular expression) that describes valid + /// contents for the given ranges. If no pattern is provided, the client + /// configuration's word pattern will be used. + final String wordPattern; + + Map toJson() { + var __result = {}; + __result['ranges'] = ranges ?? (throw 'ranges is required but was not set'); + if (wordPattern != null) { + __result['wordPattern'] = wordPattern; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('ranges'); + try { + if (!obj.containsKey('ranges')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['ranges'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['ranges'] is List && + (obj['ranges'].every((item) => Range.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('wordPattern'); + try { + if (obj['wordPattern'] != null && !(obj['wordPattern'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type LinkedEditingRanges'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LinkedEditingRanges && + other.runtimeType == LinkedEditingRanges) { + return listEqual(ranges, other.ranges, (Range a, Range b) => a == b) && + wordPattern == other.wordPattern && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(ranges)); + hash = JenkinsSmiHash.combine(hash, wordPattern.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class Location implements ToJsonable { static const jsonHandler = LspJsonHandler(Location.canParse, Location.fromJson); @@ -13936,15 +18211,15 @@ class LocationLink implements ToJsonable { /// range at the mouse position. final Range originSelectionRange; - /// The full target range of this link. For example, if the target is a - /// symbol, then target range is the range enclosing this symbol not including + /// The full target range of this link. If the target for example is a symbol + /// then target range is the range enclosing this symbol not including /// leading/trailing whitespace but everything else like comments. This /// information is typically used to highlight the range in the editor. final Range targetRange; /// The range that should be selected and revealed when this link is being - /// followed, for example, the name of a function. Must be contained by the - /// the `targetRange`. See also `DocumentSymbol#range` + /// followed, e.g the name of a function. Must be contained by the the + /// `targetRange`. See also `DocumentSymbol#range` final Range targetSelectionRange; /// The target resource identifier of this link. @@ -14157,15 +18432,190 @@ class LogMessageParams implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } -/// A `MarkupContent` literal represents a string value, which content is +class LogTraceParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(LogTraceParams.canParse, LogTraceParams.fromJson); + + LogTraceParams({@required this.message, this.verbose}) { + if (message == null) { + throw 'message is required but was not provided'; + } + } + static LogTraceParams fromJson(Map json) { + final message = json['message']; + final verbose = json['verbose']; + return LogTraceParams(message: message, verbose: verbose); + } + + /// The message to be logged. + final String message; + + /// Additional information that can be computed if the `trace` configuration + /// is set to `'verbose'` + final String verbose; + + Map toJson() { + var __result = {}; + __result['message'] = + message ?? (throw 'message is required but was not set'); + if (verbose != null) { + __result['verbose'] = verbose; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('message'); + try { + if (!obj.containsKey('message')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['message'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['message'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('verbose'); + try { + if (obj['verbose'] != null && !(obj['verbose'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type LogTraceParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is LogTraceParams && other.runtimeType == LogTraceParams) { + return message == other.message && verbose == other.verbose && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, message.hashCode); + hash = JenkinsSmiHash.combine(hash, verbose.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// Client capabilities specific to the used markdown parser. +/// @since 3.16.0 - proposed state +class MarkdownClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + MarkdownClientCapabilities.canParse, MarkdownClientCapabilities.fromJson); + + MarkdownClientCapabilities({@required this.parser, this.version}) { + if (parser == null) { + throw 'parser is required but was not provided'; + } + } + static MarkdownClientCapabilities fromJson(Map json) { + final parser = json['parser']; + final version = json['version']; + return MarkdownClientCapabilities(parser: parser, version: version); + } + + /// The name of the parser. + final String parser; + + /// The version of the parser. + final String version; + + Map toJson() { + var __result = {}; + __result['parser'] = parser ?? (throw 'parser is required but was not set'); + if (version != null) { + __result['version'] = version; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('parser'); + try { + if (!obj.containsKey('parser')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['parser'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['parser'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('version'); + try { + if (obj['version'] != null && !(obj['version'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type MarkdownClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is MarkdownClientCapabilities && + other.runtimeType == MarkdownClientCapabilities) { + return parser == other.parser && version == other.version && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, parser.hashCode); + hash = JenkinsSmiHash.combine(hash, version.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// A `MarkupContent` literal represents a string value which content is /// interpreted base on its kind flag. Currently the protocol supports /// `plaintext` and `markdown` as markup kinds. /// -/// If the kind is `markdown`, then the value can contain fenced code blocks -/// like in GitHub issues. +/// If the kind is `markdown` then the value can contain fenced code blocks like +/// in GitHub issues. /// -/// An example how such a string is constructed using JavaScript / TypeScript: -/// ```typescript let markdown: MarkdownContent = { +/// Here is an example how such a string can be constructed using JavaScript / +/// TypeScript: ```typescript let markdown: MarkdownContent = { /// /// kind: MarkupKind.Markdown, /// value: [ @@ -14176,8 +18626,8 @@ class LogMessageParams implements ToJsonable { /// '```' /// ].join('\n') }; ``` /// -/// *Please Note* that clients might sanitize the returned Markdown. A client -/// could decide to remove HTML from the Markdown to avoid script execution. +/// *Please Note* that clients might sanitize the return markdown. A client +/// could decide to remove HTML from the markdown to avoid script execution. class MarkupContent implements ToJsonable { static const jsonHandler = LspJsonHandler(MarkupContent.canParse, MarkupContent.fromJson); @@ -14517,12 +18967,21 @@ class Method { /// Constant for the 'exit' method. static const exit = Method(r'exit'); + /// Constant for the '$/logTrace' method. + static const logTrace = Method(r'$/logTrace'); + + /// Constant for the '$/setTrace' method. + static const setTrace = Method(r'$/setTrace'); + /// Constant for the 'window/showMessage' method. static const window_showMessage = Method(r'window/showMessage'); /// Constant for the 'window/showMessageRequest' method. static const window_showMessageRequest = Method(r'window/showMessageRequest'); + /// Constant for the 'window/showDocument' method. + static const window_showDocument = Method(r'window/showDocument'); + /// Constant for the 'window/logMessage' method. static const window_logMessage = Method(r'window/logMessage'); @@ -14572,6 +19031,24 @@ class Method { /// Constant for the 'workspace/applyEdit' method. static const workspace_applyEdit = Method(r'workspace/applyEdit'); + /// Constant for the 'workspace/willCreateFiles' method. + static const workspace_willCreateFiles = Method(r'workspace/willCreateFiles'); + + /// Constant for the 'workspace/didCreateFiles' method. + static const workspace_didCreateFiles = Method(r'workspace/didCreateFiles'); + + /// Constant for the 'workspace/willRenameFiles' method. + static const workspace_willRenameFiles = Method(r'workspace/willRenameFiles'); + + /// Constant for the 'workspace/didRenameFiles' method. + static const workspace_didRenameFiles = Method(r'workspace/didRenameFiles'); + + /// Constant for the 'workspace/willDeleteFiles' method. + static const workspace_willDeleteFiles = Method(r'workspace/willDeleteFiles'); + + /// Constant for the 'workspace/didDeleteFiles' method. + static const workspace_didDeleteFiles = Method(r'workspace/didDeleteFiles'); + /// Constant for the 'textDocument/didOpen' method. static const textDocument_didOpen = Method(r'textDocument/didOpen'); @@ -14636,12 +19113,19 @@ class Method { /// Constant for the 'textDocument/codeAction' method. static const textDocument_codeAction = Method(r'textDocument/codeAction'); + /// Constant for the 'codeAction/resolve' method. + static const codeAction_resolve = Method(r'codeAction/resolve'); + /// Constant for the 'textDocument/codeLens' method. static const textDocument_codeLens = Method(r'textDocument/codeLens'); /// Constant for the 'codeLens/resolve' method. static const codeLens_resolve = Method(r'codeLens/resolve'); + /// Constant for the 'workspace/codeLens/refresh' method. + static const workspace_codeLens_refresh = + Method(r'workspace/codeLens/refresh'); + /// Constant for the 'textDocument/documentLink' method. static const textDocument_documentLink = Method(r'textDocument/documentLink'); @@ -14681,6 +19165,41 @@ class Method { static const textDocument_selectionRange = Method(r'textDocument/selectionRange'); + /// Constant for the 'textDocument/prepareCallHierarchy' method. + static const textDocument_prepareCallHierarchy = + Method(r'textDocument/prepareCallHierarchy'); + + /// Constant for the 'callHierarchy/incomingCalls' method. + static const callHierarchy_incomingCalls = + Method(r'callHierarchy/incomingCalls'); + + /// Constant for the 'callHierarchy/outgoingCalls' method. + static const callHierarchy_outgoingCalls = + Method(r'callHierarchy/outgoingCalls'); + + /// Constant for the 'textDocument/semanticTokens/full' method. + static const textDocument_semanticTokens_full = + Method(r'textDocument/semanticTokens/full'); + + /// Constant for the 'textDocument/semanticTokens/full/delta' method. + static const textDocument_semanticTokens_full_delta = + Method(r'textDocument/semanticTokens/full/delta'); + + /// Constant for the 'textDocument/semanticTokens/range' method. + static const textDocument_semanticTokens_range = + Method(r'textDocument/semanticTokens/range'); + + /// Constant for the 'workspace/semanticTokens/refresh' method. + static const workspace_semanticTokens_refresh = + Method(r'workspace/semanticTokens/refresh'); + + /// Constant for the 'textDocument/linkedEditingRange' method. + static const textDocument_linkedEditingRange = + Method(r'textDocument/linkedEditingRange'); + + /// Constant for the 'textDocument/moniker' method. + static const textDocument_moniker = Method(r'textDocument/moniker'); + Object toJson() => _value; @override @@ -14692,6 +19211,571 @@ class Method { bool operator ==(Object o) => o is Method && o._value == _value; } +/// Moniker definition to match LSIF 0.5 moniker definition. +class Moniker implements ToJsonable { + static const jsonHandler = LspJsonHandler(Moniker.canParse, Moniker.fromJson); + + Moniker( + {@required this.scheme, + @required this.identifier, + @required this.unique, + this.kind}) { + if (scheme == null) { + throw 'scheme is required but was not provided'; + } + if (identifier == null) { + throw 'identifier is required but was not provided'; + } + if (unique == null) { + throw 'unique is required but was not provided'; + } + } + static Moniker fromJson(Map json) { + final scheme = json['scheme']; + final identifier = json['identifier']; + final unique = json['unique'] != null + ? UniquenessLevel.fromJson(json['unique']) + : null; + final kind = + json['kind'] != null ? MonikerKind.fromJson(json['kind']) : null; + return Moniker( + scheme: scheme, identifier: identifier, unique: unique, kind: kind); + } + + /// The identifier of the moniker. The value is opaque in LSIF however schema + /// owners are allowed to define the structure if they want. + final String identifier; + + /// The moniker kind if known. + final MonikerKind kind; + + /// The scheme of the moniker. For example tsc or .Net + final String scheme; + + /// The scope in which the moniker is unique + final UniquenessLevel unique; + + Map toJson() { + var __result = {}; + __result['scheme'] = scheme ?? (throw 'scheme is required but was not set'); + __result['identifier'] = + identifier ?? (throw 'identifier is required but was not set'); + __result['unique'] = + unique?.toJson() ?? (throw 'unique is required but was not set'); + if (kind != null) { + __result['kind'] = kind.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('scheme'); + try { + if (!obj.containsKey('scheme')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['scheme'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['scheme'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('identifier'); + try { + if (!obj.containsKey('identifier')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['identifier'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['identifier'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('unique'); + try { + if (!obj.containsKey('unique')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['unique'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(UniquenessLevel.canParse(obj['unique'], reporter))) { + reporter.reportError('must be of type UniquenessLevel'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('kind'); + try { + if (obj['kind'] != null && + !(MonikerKind.canParse(obj['kind'], reporter))) { + reporter.reportError('must be of type MonikerKind'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type Moniker'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is Moniker && other.runtimeType == Moniker) { + return scheme == other.scheme && + identifier == other.identifier && + unique == other.unique && + kind == other.kind && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, scheme.hashCode); + hash = JenkinsSmiHash.combine(hash, identifier.hashCode); + hash = JenkinsSmiHash.combine(hash, unique.hashCode); + hash = JenkinsSmiHash.combine(hash, kind.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class MonikerClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + MonikerClientCapabilities.canParse, MonikerClientCapabilities.fromJson); + + MonikerClientCapabilities({this.dynamicRegistration}); + static MonikerClientCapabilities fromJson(Map json) { + final dynamicRegistration = json['dynamicRegistration']; + return MonikerClientCapabilities(dynamicRegistration: dynamicRegistration); + } + + /// Whether implementation supports dynamic registration. If this is set to + /// `true` the client supports the new `(TextDocumentRegistrationOptions & + /// StaticRegistrationOptions)` return value for the corresponding server + /// capability as well. + final bool dynamicRegistration; + + Map toJson() { + var __result = {}; + if (dynamicRegistration != null) { + __result['dynamicRegistration'] = dynamicRegistration; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('dynamicRegistration'); + try { + if (obj['dynamicRegistration'] != null && + !(obj['dynamicRegistration'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type MonikerClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is MonikerClientCapabilities && + other.runtimeType == MonikerClientCapabilities) { + return dynamicRegistration == other.dynamicRegistration && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// The moniker kind. +class MonikerKind { + const MonikerKind(this._value); + const MonikerKind.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + /// The moniker represent a symbol that is imported into a project + static const import = MonikerKind(r'import'); + + /// The moniker represents a symbol that is exported from a project + static const export = MonikerKind(r'export'); + + /// The moniker represents a symbol that is local to a project (e.g. a local + /// variable of a function, a class not visible outside the project, ...) + static const local = MonikerKind(r'local'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is MonikerKind && o._value == _value; +} + +class MonikerOptions implements WorkDoneProgressOptions, ToJsonable { + static const jsonHandler = + LspJsonHandler(MonikerOptions.canParse, MonikerOptions.fromJson); + + MonikerOptions({this.workDoneProgress}); + static MonikerOptions fromJson(Map json) { + if (MonikerRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return MonikerRegistrationOptions.fromJson(json); + } + final workDoneProgress = json['workDoneProgress']; + return MonikerOptions(workDoneProgress: workDoneProgress); + } + + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type MonikerOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is MonikerOptions && other.runtimeType == MonikerOptions) { + return workDoneProgress == other.workDoneProgress && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class MonikerParams + implements + TextDocumentPositionParams, + WorkDoneProgressParams, + PartialResultParams, + ToJsonable { + static const jsonHandler = + LspJsonHandler(MonikerParams.canParse, MonikerParams.fromJson); + + MonikerParams( + {@required this.textDocument, + @required this.position, + this.workDoneToken, + this.partialResultToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + if (position == null) { + throw 'position is required but was not provided'; + } + } + static MonikerParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final position = + json['position'] != null ? Position.fromJson(json['position']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return MonikerParams( + textDocument: textDocument, + position: position, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// The position inside the text document. + final Position position; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + __result['position'] = + position?.toJson() ?? (throw 'position is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('position'); + try { + if (!obj.containsKey('position')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['position'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Position.canParse(obj['position'], reporter))) { + reporter.reportError('must be of type Position'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type MonikerParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is MonikerParams && other.runtimeType == MonikerParams) { + return textDocument == other.textDocument && + position == other.position && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, position.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class MonikerRegistrationOptions + implements TextDocumentRegistrationOptions, MonikerOptions, ToJsonable { + static const jsonHandler = LspJsonHandler( + MonikerRegistrationOptions.canParse, MonikerRegistrationOptions.fromJson); + + MonikerRegistrationOptions({this.documentSelector, this.workDoneProgress}); + static MonikerRegistrationOptions fromJson(Map json) { + final documentSelector = json['documentSelector'] + ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) + ?.cast() + ?.toList(); + final workDoneProgress = json['workDoneProgress']; + return MonikerRegistrationOptions( + documentSelector: documentSelector, workDoneProgress: workDoneProgress); + } + + /// A document selector to identify the scope of the registration. If set to + /// null the document selector provided on the client side will be used. + final List documentSelector; + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + __result['documentSelector'] = documentSelector; + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('documentSelector'); + try { + if (!obj.containsKey('documentSelector')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['documentSelector'] != null && + !((obj['documentSelector'] is List && + (obj['documentSelector'].every( + (item) => DocumentFilter.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type MonikerRegistrationOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is MonikerRegistrationOptions && + other.runtimeType == MonikerRegistrationOptions) { + return listEqual(documentSelector, other.documentSelector, + (DocumentFilter a, DocumentFilter b) => a == b) && + workDoneProgress == other.workDoneProgress && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class NotificationMessage implements Message, IncomingMessage, ToJsonable { static const jsonHandler = LspJsonHandler( NotificationMessage.canParse, NotificationMessage.fromJson); @@ -14811,6 +19895,106 @@ class NotificationMessage implements Message, IncomingMessage, ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class OptionalVersionedTextDocumentIdentifier + implements TextDocumentIdentifier, ToJsonable { + static const jsonHandler = LspJsonHandler( + OptionalVersionedTextDocumentIdentifier.canParse, + OptionalVersionedTextDocumentIdentifier.fromJson); + + OptionalVersionedTextDocumentIdentifier({this.version, @required this.uri}) { + if (uri == null) { + throw 'uri is required but was not provided'; + } + } + static OptionalVersionedTextDocumentIdentifier fromJson( + Map json) { + final version = json['version']; + final uri = json['uri']; + return OptionalVersionedTextDocumentIdentifier(version: version, uri: uri); + } + + /// The text document's URI. + final String uri; + + /// The version number of this document. If an optional versioned text + /// document identifier is sent from the server to the client and the file is + /// not open in the editor (the server has not received an open notification + /// before) the server can send `null` to indicate that the version is known + /// and the content on disk is the master (as specified with document content + /// ownership). + /// + /// The version number of a document will increase after each change, + /// including undo/redo. The number doesn't need to be consecutive. + final num version; + + Map toJson() { + var __result = {}; + __result['version'] = version; + __result['uri'] = uri ?? (throw 'uri is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('version'); + try { + if (!obj.containsKey('version')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['version'] != null && !(obj['version'] is num)) { + reporter.reportError('must be of type num'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('uri'); + try { + if (!obj.containsKey('uri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['uri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['uri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type OptionalVersionedTextDocumentIdentifier'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is OptionalVersionedTextDocumentIdentifier && + other.runtimeType == OptionalVersionedTextDocumentIdentifier) { + return version == other.version && uri == other.uri && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, version.hashCode); + hash = JenkinsSmiHash.combine(hash, uri.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + /// Represents a parameter of a callable-signature. A parameter can have a label /// and a doc-comment. class ParameterInformation implements ToJsonable { @@ -14976,6 +20160,24 @@ class PartialResultParams implements ToJsonable { if (SelectionRangeParams.canParse(json, nullLspJsonReporter)) { return SelectionRangeParams.fromJson(json); } + if (CallHierarchyIncomingCallsParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyIncomingCallsParams.fromJson(json); + } + if (CallHierarchyOutgoingCallsParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyOutgoingCallsParams.fromJson(json); + } + if (SemanticTokensParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensParams.fromJson(json); + } + if (SemanticTokensDeltaParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensDeltaParams.fromJson(json); + } + if (SemanticTokensRangeParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensRangeParams.fromJson(json); + } + if (MonikerParams.canParse(json, nullLspJsonReporter)) { + return MonikerParams.fromJson(json); + } final partialResultToken = json['partialResultToken'] is num ? Either2.t1(json['partialResultToken']) : (json['partialResultToken'] is String @@ -14986,8 +20188,8 @@ class PartialResultParams implements ToJsonable { return PartialResultParams(partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; Map toJson() { @@ -15240,6 +20442,32 @@ class PrepareRenameParams implements TextDocumentPositionParams, ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class PrepareSupportDefaultBehavior { + const PrepareSupportDefaultBehavior(this._value); + const PrepareSupportDefaultBehavior.fromJson(this._value); + + final num _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is num; + } + + /// The client's default behavior is to select the identifier according the to + /// language's syntax rule. + static const Identifier = PrepareSupportDefaultBehavior(1); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => + o is PrepareSupportDefaultBehavior && o._value == _value; +} + class ProgressParams implements ToJsonable { static const jsonHandler = LspJsonHandler(ProgressParams.canParse, ProgressParams.fromJson); @@ -15344,7 +20572,11 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { PublishDiagnosticsClientCapabilities.fromJson); PublishDiagnosticsClientCapabilities( - {this.relatedInformation, this.tagSupport, this.versionSupport}); + {this.relatedInformation, + this.tagSupport, + this.versionSupport, + this.codeDescriptionSupport, + this.dataSupport}); static PublishDiagnosticsClientCapabilities fromJson( Map json) { final relatedInformation = json['relatedInformation']; @@ -15353,12 +20585,26 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { json['tagSupport']) : null; final versionSupport = json['versionSupport']; + final codeDescriptionSupport = json['codeDescriptionSupport']; + final dataSupport = json['dataSupport']; return PublishDiagnosticsClientCapabilities( relatedInformation: relatedInformation, tagSupport: tagSupport, - versionSupport: versionSupport); + versionSupport: versionSupport, + codeDescriptionSupport: codeDescriptionSupport, + dataSupport: dataSupport); } + /// Client supports a codeDescription property + /// @since 3.16.0 - proposed state + final bool codeDescriptionSupport; + + /// Whether code action supports the `data` property which is preserved + /// between a `textDocument/publishDiagnostics` and `textDocument/codeAction` + /// request. + /// @since 3.16.0 - proposed state + final bool dataSupport; + /// Whether the clients accepts diagnostics with related information. final bool relatedInformation; @@ -15383,6 +20629,12 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { if (versionSupport != null) { __result['versionSupport'] = versionSupport; } + if (codeDescriptionSupport != null) { + __result['codeDescriptionSupport'] = codeDescriptionSupport; + } + if (dataSupport != null) { + __result['dataSupport'] = dataSupport; + } return __result; } @@ -15419,6 +20671,25 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('codeDescriptionSupport'); + try { + if (obj['codeDescriptionSupport'] != null && + !(obj['codeDescriptionSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('dataSupport'); + try { + if (obj['dataSupport'] != null && !(obj['dataSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter @@ -15434,6 +20705,8 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { return relatedInformation == other.relatedInformation && tagSupport == other.tagSupport && versionSupport == other.versionSupport && + codeDescriptionSupport == other.codeDescriptionSupport && + dataSupport == other.dataSupport && true; } return false; @@ -15445,6 +20718,8 @@ class PublishDiagnosticsClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, relatedInformation.hashCode); hash = JenkinsSmiHash.combine(hash, tagSupport.hashCode); hash = JenkinsSmiHash.combine(hash, versionSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, codeDescriptionSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, dataSupport.hashCode); return JenkinsSmiHash.finish(hash); } @@ -15562,8 +20837,9 @@ class PublishDiagnosticsParams implements ToJsonable { /// The URI for which diagnostic information is reported. final String uri; - /// The version number of the document the diagnostics are published for. - /// Optional. @since 3.15.0 + /// Optional the version number of the document the diagnostics are published + /// for. + /// @since 3.15.0 final num version; Map toJson() { @@ -16097,8 +21373,8 @@ class ReferenceParams final ReferenceContext context; - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -16255,7 +21531,7 @@ class ReferenceRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; final bool workDoneProgress; @@ -16521,27 +21797,144 @@ class RegistrationParams implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// Client capabilities specific to regular expressions. +class RegularExpressionsClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + RegularExpressionsClientCapabilities.canParse, + RegularExpressionsClientCapabilities.fromJson); + + RegularExpressionsClientCapabilities({@required this.engine, this.version}) { + if (engine == null) { + throw 'engine is required but was not provided'; + } + } + static RegularExpressionsClientCapabilities fromJson( + Map json) { + final engine = json['engine']; + final version = json['version']; + return RegularExpressionsClientCapabilities( + engine: engine, version: version); + } + + /// The engine's name. + final String engine; + + /// The engine's version. + final String version; + + Map toJson() { + var __result = {}; + __result['engine'] = engine ?? (throw 'engine is required but was not set'); + if (version != null) { + __result['version'] = version; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('engine'); + try { + if (!obj.containsKey('engine')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['engine'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['engine'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('version'); + try { + if (obj['version'] != null && !(obj['version'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type RegularExpressionsClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is RegularExpressionsClientCapabilities && + other.runtimeType == RegularExpressionsClientCapabilities) { + return engine == other.engine && version == other.version && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, engine.hashCode); + hash = JenkinsSmiHash.combine(hash, version.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class RenameClientCapabilities implements ToJsonable { static const jsonHandler = LspJsonHandler( RenameClientCapabilities.canParse, RenameClientCapabilities.fromJson); - RenameClientCapabilities({this.dynamicRegistration, this.prepareSupport}); + RenameClientCapabilities( + {this.dynamicRegistration, + this.prepareSupport, + this.prepareSupportDefaultBehavior, + this.honorsChangeAnnotations}); static RenameClientCapabilities fromJson(Map json) { final dynamicRegistration = json['dynamicRegistration']; final prepareSupport = json['prepareSupport']; + final prepareSupportDefaultBehavior = + json['prepareSupportDefaultBehavior'] != null + ? PrepareSupportDefaultBehavior.fromJson( + json['prepareSupportDefaultBehavior']) + : null; + final honorsChangeAnnotations = json['honorsChangeAnnotations']; return RenameClientCapabilities( dynamicRegistration: dynamicRegistration, - prepareSupport: prepareSupport); + prepareSupport: prepareSupport, + prepareSupportDefaultBehavior: prepareSupportDefaultBehavior, + honorsChangeAnnotations: honorsChangeAnnotations); } /// Whether rename supports dynamic registration. final bool dynamicRegistration; + /// Whether th client honors the change annotations in text edits and resource + /// operations returned via the rename request's workspace edit by for example + /// presenting the workspace edit in the user interface and asking for + /// confirmation. + /// @since 3.16.0 - proposed state + final bool honorsChangeAnnotations; + /// Client supports testing for validity of rename operations before /// execution. /// @since version 3.12.0 final bool prepareSupport; + /// Client supports the default behavior result (`{ defaultBehavior: boolean + /// }`). + /// + /// The value indicates the default behavior used by the client. + /// @since version 3.16.0 + final PrepareSupportDefaultBehavior prepareSupportDefaultBehavior; + Map toJson() { var __result = {}; if (dynamicRegistration != null) { @@ -16550,6 +21943,13 @@ class RenameClientCapabilities implements ToJsonable { if (prepareSupport != null) { __result['prepareSupport'] = prepareSupport; } + if (prepareSupportDefaultBehavior != null) { + __result['prepareSupportDefaultBehavior'] = + prepareSupportDefaultBehavior.toJson(); + } + if (honorsChangeAnnotations != null) { + __result['honorsChangeAnnotations'] = honorsChangeAnnotations; + } return __result; } @@ -16574,6 +21974,27 @@ class RenameClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('prepareSupportDefaultBehavior'); + try { + if (obj['prepareSupportDefaultBehavior'] != null && + !(PrepareSupportDefaultBehavior.canParse( + obj['prepareSupportDefaultBehavior'], reporter))) { + reporter.reportError('must be of type PrepareSupportDefaultBehavior'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('honorsChangeAnnotations'); + try { + if (obj['honorsChangeAnnotations'] != null && + !(obj['honorsChangeAnnotations'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type RenameClientCapabilities'); @@ -16587,6 +22008,9 @@ class RenameClientCapabilities implements ToJsonable { other.runtimeType == RenameClientCapabilities) { return dynamicRegistration == other.dynamicRegistration && prepareSupport == other.prepareSupport && + prepareSupportDefaultBehavior == + other.prepareSupportDefaultBehavior && + honorsChangeAnnotations == other.honorsChangeAnnotations && true; } return false; @@ -16597,6 +22021,8 @@ class RenameClientCapabilities implements ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); hash = JenkinsSmiHash.combine(hash, prepareSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, prepareSupportDefaultBehavior.hashCode); + hash = JenkinsSmiHash.combine(hash, honorsChangeAnnotations.hashCode); return JenkinsSmiHash.finish(hash); } @@ -16613,7 +22039,8 @@ class RenameFile implements ToJsonable { {this.kind = 'rename', @required this.oldUri, @required this.newUri, - this.options}) { + this.options, + this.annotationId}) { if (kind != 'rename') { throw 'kind may only be the literal \'rename\''; } @@ -16631,10 +22058,19 @@ class RenameFile implements ToJsonable { final options = json['options'] != null ? RenameFileOptions.fromJson(json['options']) : null; + final annotationId = json['annotationId']; return RenameFile( - kind: kind, oldUri: oldUri, newUri: newUri, options: options); + kind: kind, + oldUri: oldUri, + newUri: newUri, + options: options, + annotationId: annotationId); } + /// An optional annotation identifer describing the operation. + /// @since 3.16.0 - proposed state + final String annotationId; + /// A rename final String kind; @@ -16655,6 +22091,9 @@ class RenameFile implements ToJsonable { if (options != null) { __result['options'] = options.toJson(); } + if (annotationId != null) { + __result['annotationId'] = annotationId; + } return __result; } @@ -16721,6 +22160,15 @@ class RenameFile implements ToJsonable { } finally { reporter.pop(); } + reporter.push('annotationId'); + try { + if (obj['annotationId'] != null && !(obj['annotationId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type RenameFile'); @@ -16735,6 +22183,7 @@ class RenameFile implements ToJsonable { oldUri == other.oldUri && newUri == other.newUri && options == other.options && + annotationId == other.annotationId && true; } return false; @@ -16747,6 +22196,7 @@ class RenameFile implements ToJsonable { hash = JenkinsSmiHash.combine(hash, oldUri.hashCode); hash = JenkinsSmiHash.combine(hash, newUri.hashCode); hash = JenkinsSmiHash.combine(hash, options.hashCode); + hash = JenkinsSmiHash.combine(hash, annotationId.hashCode); return JenkinsSmiHash.finish(hash); } @@ -16833,6 +22283,85 @@ class RenameFileOptions implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// The parameters sent in notifications/requests for user-initiated renames of +/// files. +/// @since 3.16.0 - proposed state +class RenameFilesParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(RenameFilesParams.canParse, RenameFilesParams.fromJson); + + RenameFilesParams({@required this.files}) { + if (files == null) { + throw 'files is required but was not provided'; + } + } + static RenameFilesParams fromJson(Map json) { + final files = json['files'] + ?.map((item) => item != null ? FileRename.fromJson(item) : null) + ?.cast() + ?.toList(); + return RenameFilesParams(files: files); + } + + /// An array of all files/folders renamed in this operation. When a folder is + /// renamed, only the folder will be included, and not its children. + final List files; + + Map toJson() { + var __result = {}; + __result['files'] = files ?? (throw 'files is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('files'); + try { + if (!obj.containsKey('files')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['files'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['files'] is List && + (obj['files'] + .every((item) => FileRename.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type RenameFilesParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is RenameFilesParams && other.runtimeType == RenameFilesParams) { + return listEqual( + files, other.files, (FileRename a, FileRename b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(files)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class RenameOptions implements WorkDoneProgressOptions, ToJsonable { static const jsonHandler = LspJsonHandler(RenameOptions.canParse, RenameOptions.fromJson); @@ -17100,7 +22629,7 @@ class RenameRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// Renames should be checked and tested before being executed. @@ -17791,7 +23320,7 @@ class SelectionRangeClientCapabilities implements ToJsonable { } /// Whether implementation supports dynamic registration for selection range - /// providers. If set to `true`, the client supports the new + /// providers. If this is set to `true` the client supports the new /// `SelectionRangeRegistrationOptions` return value for the corresponding /// server capability as well. final bool dynamicRegistration; @@ -17951,8 +23480,8 @@ class SelectionRangeParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The positions inside the text document. @@ -18100,7 +23629,7 @@ class SelectionRangeRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -18190,6 +23719,2108 @@ class SelectionRangeRegistrationOptions String toString() => jsonEncoder.convert(toJson()); } +class SemanticTokenModifiers { + const SemanticTokenModifiers(this._value); + const SemanticTokenModifiers.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + static const declaration = SemanticTokenModifiers(r'declaration'); + static const definition = SemanticTokenModifiers(r'definition'); + static const readonly = SemanticTokenModifiers(r'readonly'); + static const static = SemanticTokenModifiers(r'static'); + static const deprecated = SemanticTokenModifiers(r'deprecated'); + static const abstract = SemanticTokenModifiers(r'abstract'); + static const async = SemanticTokenModifiers(r'async'); + static const modification = SemanticTokenModifiers(r'modification'); + static const documentation = SemanticTokenModifiers(r'documentation'); + static const defaultLibrary = SemanticTokenModifiers(r'defaultLibrary'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => + o is SemanticTokenModifiers && o._value == _value; +} + +class SemanticTokenTypes { + const SemanticTokenTypes(this._value); + const SemanticTokenTypes.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + static const namespace = SemanticTokenTypes(r'namespace'); + + /// Represents a generic type. Acts as a fallback for types which can't be + /// mapped to a specific type like class or enum. + static const type = SemanticTokenTypes(r'type'); + static const class_ = SemanticTokenTypes(r'class'); + static const enum_ = SemanticTokenTypes(r'enum'); + static const interface = SemanticTokenTypes(r'interface'); + static const struct = SemanticTokenTypes(r'struct'); + static const typeParameter = SemanticTokenTypes(r'typeParameter'); + static const parameter = SemanticTokenTypes(r'parameter'); + static const variable = SemanticTokenTypes(r'variable'); + static const property = SemanticTokenTypes(r'property'); + static const enumMember = SemanticTokenTypes(r'enumMember'); + static const event = SemanticTokenTypes(r'event'); + static const function = SemanticTokenTypes(r'function'); + static const method = SemanticTokenTypes(r'method'); + static const macro = SemanticTokenTypes(r'macro'); + static const keyword = SemanticTokenTypes(r'keyword'); + static const modifier = SemanticTokenTypes(r'modifier'); + static const comment = SemanticTokenTypes(r'comment'); + static const string = SemanticTokenTypes(r'string'); + static const number = SemanticTokenTypes(r'number'); + static const regexp = SemanticTokenTypes(r'regexp'); + static const operator = SemanticTokenTypes(r'operator'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is SemanticTokenTypes && o._value == _value; +} + +class SemanticTokens implements ToJsonable { + static const jsonHandler = + LspJsonHandler(SemanticTokens.canParse, SemanticTokens.fromJson); + + SemanticTokens({this.resultId, @required this.data}) { + if (data == null) { + throw 'data is required but was not provided'; + } + } + static SemanticTokens fromJson(Map json) { + final resultId = json['resultId']; + final data = json['data']?.map((item) => item)?.cast()?.toList(); + return SemanticTokens(resultId: resultId, data: data); + } + + /// The actual tokens. + final List data; + + /// An optional result id. If provided and clients support delta updating the + /// client will include the result id in the next semantic token request. A + /// server can then instead of computing all semantic tokens again simply send + /// a delta. + final String resultId; + + Map toJson() { + var __result = {}; + if (resultId != null) { + __result['resultId'] = resultId; + } + __result['data'] = data ?? (throw 'data is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('resultId'); + try { + if (obj['resultId'] != null && !(obj['resultId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('data'); + try { + if (!obj.containsKey('data')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['data'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['data'] is List && + (obj['data'].every((item) => item is num))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokens'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokens && other.runtimeType == SemanticTokens) { + return resultId == other.resultId && + listEqual(data, other.data, (num a, num b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, resultId.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(data)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensClientCapabilities.canParse, + SemanticTokensClientCapabilities.fromJson); + + SemanticTokensClientCapabilities( + {this.dynamicRegistration, + @required this.requests, + @required this.tokenTypes, + @required this.tokenModifiers, + @required this.formats, + this.overlappingTokenSupport, + this.multilineTokenSupport}) { + if (requests == null) { + throw 'requests is required but was not provided'; + } + if (tokenTypes == null) { + throw 'tokenTypes is required but was not provided'; + } + if (tokenModifiers == null) { + throw 'tokenModifiers is required but was not provided'; + } + if (formats == null) { + throw 'formats is required but was not provided'; + } + } + static SemanticTokensClientCapabilities fromJson(Map json) { + final dynamicRegistration = json['dynamicRegistration']; + final requests = json['requests'] != null + ? SemanticTokensClientCapabilitiesRequests.fromJson(json['requests']) + : null; + final tokenTypes = + json['tokenTypes']?.map((item) => item)?.cast()?.toList(); + final tokenModifiers = + json['tokenModifiers']?.map((item) => item)?.cast()?.toList(); + final formats = json['formats'] + ?.map((item) => item != null ? TokenFormat.fromJson(item) : null) + ?.cast() + ?.toList(); + final overlappingTokenSupport = json['overlappingTokenSupport']; + final multilineTokenSupport = json['multilineTokenSupport']; + return SemanticTokensClientCapabilities( + dynamicRegistration: dynamicRegistration, + requests: requests, + tokenTypes: tokenTypes, + tokenModifiers: tokenModifiers, + formats: formats, + overlappingTokenSupport: overlappingTokenSupport, + multilineTokenSupport: multilineTokenSupport); + } + + /// Whether implementation supports dynamic registration. If this is set to + /// `true` the client supports the new `(TextDocumentRegistrationOptions & + /// StaticRegistrationOptions)` return value for the corresponding server + /// capability as well. + final bool dynamicRegistration; + + /// The formats the clients supports. + final List formats; + + /// Whether the client supports tokens that can span multiple lines. + final bool multilineTokenSupport; + + /// Whether the client supports tokens that can overlap each other. + final bool overlappingTokenSupport; + + /// Which requests the client supports and might send to the server. + final SemanticTokensClientCapabilitiesRequests requests; + + /// The token modifiers that the client supports. + final List tokenModifiers; + + /// The token types that the client supports. + final List tokenTypes; + + Map toJson() { + var __result = {}; + if (dynamicRegistration != null) { + __result['dynamicRegistration'] = dynamicRegistration; + } + __result['requests'] = + requests?.toJson() ?? (throw 'requests is required but was not set'); + __result['tokenTypes'] = + tokenTypes ?? (throw 'tokenTypes is required but was not set'); + __result['tokenModifiers'] = + tokenModifiers ?? (throw 'tokenModifiers is required but was not set'); + __result['formats'] = + formats ?? (throw 'formats is required but was not set'); + if (overlappingTokenSupport != null) { + __result['overlappingTokenSupport'] = overlappingTokenSupport; + } + if (multilineTokenSupport != null) { + __result['multilineTokenSupport'] = multilineTokenSupport; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('dynamicRegistration'); + try { + if (obj['dynamicRegistration'] != null && + !(obj['dynamicRegistration'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('requests'); + try { + if (!obj.containsKey('requests')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['requests'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(SemanticTokensClientCapabilitiesRequests.canParse( + obj['requests'], reporter))) { + reporter.reportError( + 'must be of type SemanticTokensClientCapabilitiesRequests'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('tokenTypes'); + try { + if (!obj.containsKey('tokenTypes')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['tokenTypes'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['tokenTypes'] is List && + (obj['tokenTypes'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('tokenModifiers'); + try { + if (!obj.containsKey('tokenModifiers')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['tokenModifiers'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['tokenModifiers'] is List && + (obj['tokenModifiers'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('formats'); + try { + if (!obj.containsKey('formats')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['formats'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['formats'] is List && + (obj['formats'] + .every((item) => TokenFormat.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('overlappingTokenSupport'); + try { + if (obj['overlappingTokenSupport'] != null && + !(obj['overlappingTokenSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('multilineTokenSupport'); + try { + if (obj['multilineTokenSupport'] != null && + !(obj['multilineTokenSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensClientCapabilities && + other.runtimeType == SemanticTokensClientCapabilities) { + return dynamicRegistration == other.dynamicRegistration && + requests == other.requests && + listEqual( + tokenTypes, other.tokenTypes, (String a, String b) => a == b) && + listEqual(tokenModifiers, other.tokenModifiers, + (String a, String b) => a == b) && + listEqual(formats, other.formats, + (TokenFormat a, TokenFormat b) => a == b) && + overlappingTokenSupport == other.overlappingTokenSupport && + multilineTokenSupport == other.multilineTokenSupport && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); + hash = JenkinsSmiHash.combine(hash, requests.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tokenTypes)); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tokenModifiers)); + hash = JenkinsSmiHash.combine(hash, lspHashCode(formats)); + hash = JenkinsSmiHash.combine(hash, overlappingTokenSupport.hashCode); + hash = JenkinsSmiHash.combine(hash, multilineTokenSupport.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensClientCapabilitiesFull implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensClientCapabilitiesFull.canParse, + SemanticTokensClientCapabilitiesFull.fromJson); + + SemanticTokensClientCapabilitiesFull({this.delta}); + static SemanticTokensClientCapabilitiesFull fromJson( + Map json) { + final delta = json['delta']; + return SemanticTokensClientCapabilitiesFull(delta: delta); + } + + /// The client will send the `textDocument/semanticTokens/full/delta` request + /// if the server provides a corresponding handler. + final bool delta; + + Map toJson() { + var __result = {}; + if (delta != null) { + __result['delta'] = delta; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('delta'); + try { + if (obj['delta'] != null && !(obj['delta'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type SemanticTokensClientCapabilitiesFull'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensClientCapabilitiesFull && + other.runtimeType == SemanticTokensClientCapabilitiesFull) { + return delta == other.delta && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, delta.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensClientCapabilitiesRange implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensClientCapabilitiesRange.canParse, + SemanticTokensClientCapabilitiesRange.fromJson); + + static SemanticTokensClientCapabilitiesRange fromJson( + Map json) { + return SemanticTokensClientCapabilitiesRange(); + } + + Map toJson() { + var __result = {}; + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + return true; + } else { + reporter + .reportError('must be of type SemanticTokensClientCapabilitiesRange'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensClientCapabilitiesRange && + other.runtimeType == SemanticTokensClientCapabilitiesRange) { + return true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensClientCapabilitiesRequests implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensClientCapabilitiesRequests.canParse, + SemanticTokensClientCapabilitiesRequests.fromJson); + + SemanticTokensClientCapabilitiesRequests({this.range, this.full}); + static SemanticTokensClientCapabilitiesRequests fromJson( + Map json) { + final range = json['range'] is bool + ? Either2.t1(json['range']) + : (SemanticTokensClientCapabilitiesRange.canParse( + json['range'], nullLspJsonReporter) + ? Either2.t2( + json['range'] != null + ? SemanticTokensClientCapabilitiesRange.fromJson( + json['range']) + : null) + : (json['range'] == null + ? null + : (throw '''${json['range']} was not one of (bool, SemanticTokensClientCapabilitiesRange)'''))); + final full = json['full'] is bool + ? Either2.t1(json['full']) + : (SemanticTokensClientCapabilitiesFull.canParse( + json['full'], nullLspJsonReporter) + ? Either2.t2( + json['full'] != null + ? SemanticTokensClientCapabilitiesFull.fromJson( + json['full']) + : null) + : (json['full'] == null + ? null + : (throw '''${json['full']} was not one of (bool, SemanticTokensClientCapabilitiesFull)'''))); + return SemanticTokensClientCapabilitiesRequests(range: range, full: full); + } + + /// The client will send the `textDocument/semanticTokens/full` request if the + /// server provides a corresponding handler. + final Either2 full; + + /// The client will send the `textDocument/semanticTokens/range` request if + /// the server provides a corresponding handler. + final Either2 range; + + Map toJson() { + var __result = {}; + if (range != null) { + __result['range'] = range; + } + if (full != null) { + __result['full'] = full; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('range'); + try { + if (obj['range'] != null && + !((obj['range'] is bool || + SemanticTokensClientCapabilitiesRange.canParse( + obj['range'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('full'); + try { + if (obj['full'] != null && + !((obj['full'] is bool || + SemanticTokensClientCapabilitiesFull.canParse( + obj['full'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type SemanticTokensClientCapabilitiesRequests'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensClientCapabilitiesRequests && + other.runtimeType == SemanticTokensClientCapabilitiesRequests) { + return range == other.range && full == other.full && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, full.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensDelta implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensDelta.canParse, SemanticTokensDelta.fromJson); + + SemanticTokensDelta({this.resultId, @required this.edits}) { + if (edits == null) { + throw 'edits is required but was not provided'; + } + } + static SemanticTokensDelta fromJson(Map json) { + final resultId = json['resultId']; + final edits = json['edits'] + ?.map((item) => item != null ? SemanticTokensEdit.fromJson(item) : null) + ?.cast() + ?.toList(); + return SemanticTokensDelta(resultId: resultId, edits: edits); + } + + /// The semantic token edits to transform a previous result into a new result. + final List edits; + final String resultId; + + Map toJson() { + var __result = {}; + if (resultId != null) { + __result['resultId'] = resultId; + } + __result['edits'] = edits ?? (throw 'edits is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('resultId'); + try { + if (obj['resultId'] != null && !(obj['resultId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('edits'); + try { + if (!obj.containsKey('edits')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['edits'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['edits'] is List && + (obj['edits'].every( + (item) => SemanticTokensEdit.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensDelta'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensDelta && + other.runtimeType == SemanticTokensDelta) { + return resultId == other.resultId && + listEqual(edits, other.edits, + (SemanticTokensEdit a, SemanticTokensEdit b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, resultId.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(edits)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensDeltaParams + implements WorkDoneProgressParams, PartialResultParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensDeltaParams.canParse, SemanticTokensDeltaParams.fromJson); + + SemanticTokensDeltaParams( + {@required this.textDocument, + @required this.previousResultId, + this.workDoneToken, + this.partialResultToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + if (previousResultId == null) { + throw 'previousResultId is required but was not provided'; + } + } + static SemanticTokensDeltaParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final previousResultId = json['previousResultId']; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return SemanticTokensDeltaParams( + textDocument: textDocument, + previousResultId: previousResultId, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// The result id of a previous response. The result Id can either point to a + /// full response or a delta response depending on what was received last. + final String previousResultId; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + __result['previousResultId'] = previousResultId ?? + (throw 'previousResultId is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('previousResultId'); + try { + if (!obj.containsKey('previousResultId')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['previousResultId'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['previousResultId'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensDeltaParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensDeltaParams && + other.runtimeType == SemanticTokensDeltaParams) { + return textDocument == other.textDocument && + previousResultId == other.previousResultId && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, previousResultId.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensDeltaPartialResult implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensDeltaPartialResult.canParse, + SemanticTokensDeltaPartialResult.fromJson); + + SemanticTokensDeltaPartialResult({@required this.edits}) { + if (edits == null) { + throw 'edits is required but was not provided'; + } + } + static SemanticTokensDeltaPartialResult fromJson(Map json) { + final edits = json['edits'] + ?.map((item) => item != null ? SemanticTokensEdit.fromJson(item) : null) + ?.cast() + ?.toList(); + return SemanticTokensDeltaPartialResult(edits: edits); + } + + final List edits; + + Map toJson() { + var __result = {}; + __result['edits'] = edits ?? (throw 'edits is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('edits'); + try { + if (!obj.containsKey('edits')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['edits'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['edits'] is List && + (obj['edits'].every( + (item) => SemanticTokensEdit.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensDeltaPartialResult'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensDeltaPartialResult && + other.runtimeType == SemanticTokensDeltaPartialResult) { + return listEqual(edits, other.edits, + (SemanticTokensEdit a, SemanticTokensEdit b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(edits)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensEdit implements ToJsonable { + static const jsonHandler = + LspJsonHandler(SemanticTokensEdit.canParse, SemanticTokensEdit.fromJson); + + SemanticTokensEdit( + {@required this.start, @required this.deleteCount, this.data}) { + if (start == null) { + throw 'start is required but was not provided'; + } + if (deleteCount == null) { + throw 'deleteCount is required but was not provided'; + } + } + static SemanticTokensEdit fromJson(Map json) { + final start = json['start']; + final deleteCount = json['deleteCount']; + final data = json['data']?.map((item) => item)?.cast()?.toList(); + return SemanticTokensEdit( + start: start, deleteCount: deleteCount, data: data); + } + + /// The elements to insert. + final List data; + + /// The count of elements to remove. + final num deleteCount; + + /// The start offset of the edit. + final num start; + + Map toJson() { + var __result = {}; + __result['start'] = start ?? (throw 'start is required but was not set'); + __result['deleteCount'] = + deleteCount ?? (throw 'deleteCount is required but was not set'); + if (data != null) { + __result['data'] = data; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('start'); + try { + if (!obj.containsKey('start')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['start'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['start'] is num)) { + reporter.reportError('must be of type num'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('deleteCount'); + try { + if (!obj.containsKey('deleteCount')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['deleteCount'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['deleteCount'] is num)) { + reporter.reportError('must be of type num'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('data'); + try { + if (obj['data'] != null && + !((obj['data'] is List && + (obj['data'].every((item) => item is num))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensEdit'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensEdit && + other.runtimeType == SemanticTokensEdit) { + return start == other.start && + deleteCount == other.deleteCount && + listEqual(data, other.data, (num a, num b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, start.hashCode); + hash = JenkinsSmiHash.combine(hash, deleteCount.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(data)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensLegend implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensLegend.canParse, SemanticTokensLegend.fromJson); + + SemanticTokensLegend( + {@required this.tokenTypes, @required this.tokenModifiers}) { + if (tokenTypes == null) { + throw 'tokenTypes is required but was not provided'; + } + if (tokenModifiers == null) { + throw 'tokenModifiers is required but was not provided'; + } + } + static SemanticTokensLegend fromJson(Map json) { + final tokenTypes = + json['tokenTypes']?.map((item) => item)?.cast()?.toList(); + final tokenModifiers = + json['tokenModifiers']?.map((item) => item)?.cast()?.toList(); + return SemanticTokensLegend( + tokenTypes: tokenTypes, tokenModifiers: tokenModifiers); + } + + /// The token modifiers a server uses. + final List tokenModifiers; + + /// The token types a server uses. + final List tokenTypes; + + Map toJson() { + var __result = {}; + __result['tokenTypes'] = + tokenTypes ?? (throw 'tokenTypes is required but was not set'); + __result['tokenModifiers'] = + tokenModifiers ?? (throw 'tokenModifiers is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('tokenTypes'); + try { + if (!obj.containsKey('tokenTypes')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['tokenTypes'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['tokenTypes'] is List && + (obj['tokenTypes'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('tokenModifiers'); + try { + if (!obj.containsKey('tokenModifiers')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['tokenModifiers'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['tokenModifiers'] is List && + (obj['tokenModifiers'].every((item) => item is String))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensLegend'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensLegend && + other.runtimeType == SemanticTokensLegend) { + return listEqual( + tokenTypes, other.tokenTypes, (String a, String b) => a == b) && + listEqual(tokenModifiers, other.tokenModifiers, + (String a, String b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(tokenTypes)); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tokenModifiers)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensOptions implements WorkDoneProgressOptions, ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensOptions.canParse, SemanticTokensOptions.fromJson); + + SemanticTokensOptions( + {@required this.legend, this.range, this.full, this.workDoneProgress}) { + if (legend == null) { + throw 'legend is required but was not provided'; + } + } + static SemanticTokensOptions fromJson(Map json) { + if (SemanticTokensRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return SemanticTokensRegistrationOptions.fromJson(json); + } + final legend = json['legend'] != null + ? SemanticTokensLegend.fromJson(json['legend']) + : null; + final range = json['range'] is bool + ? Either2.t1(json['range']) + : (SemanticTokensOptionsRange.canParse( + json['range'], nullLspJsonReporter) + ? Either2.t2(json['range'] != null + ? SemanticTokensOptionsRange.fromJson(json['range']) + : null) + : (json['range'] == null + ? null + : (throw '''${json['range']} was not one of (bool, SemanticTokensOptionsRange)'''))); + final full = json['full'] is bool + ? Either2.t1(json['full']) + : (SemanticTokensOptionsFull.canParse(json['full'], nullLspJsonReporter) + ? Either2.t2(json['full'] != null + ? SemanticTokensOptionsFull.fromJson(json['full']) + : null) + : (json['full'] == null + ? null + : (throw '''${json['full']} was not one of (bool, SemanticTokensOptionsFull)'''))); + final workDoneProgress = json['workDoneProgress']; + return SemanticTokensOptions( + legend: legend, + range: range, + full: full, + workDoneProgress: workDoneProgress); + } + + /// Server supports providing semantic tokens for a full document. + final Either2 full; + + /// The legend used by the server + final SemanticTokensLegend legend; + + /// Server supports providing semantic tokens for a specific range of a + /// document. + final Either2 range; + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + __result['legend'] = + legend?.toJson() ?? (throw 'legend is required but was not set'); + if (range != null) { + __result['range'] = range; + } + if (full != null) { + __result['full'] = full; + } + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('legend'); + try { + if (!obj.containsKey('legend')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['legend'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(SemanticTokensLegend.canParse(obj['legend'], reporter))) { + reporter.reportError('must be of type SemanticTokensLegend'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('range'); + try { + if (obj['range'] != null && + !((obj['range'] is bool || + SemanticTokensOptionsRange.canParse(obj['range'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('full'); + try { + if (obj['full'] != null && + !((obj['full'] is bool || + SemanticTokensOptionsFull.canParse(obj['full'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensOptions && + other.runtimeType == SemanticTokensOptions) { + return legend == other.legend && + range == other.range && + full == other.full && + workDoneProgress == other.workDoneProgress && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, legend.hashCode); + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, full.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensOptionsFull implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensOptionsFull.canParse, SemanticTokensOptionsFull.fromJson); + + SemanticTokensOptionsFull({this.delta}); + static SemanticTokensOptionsFull fromJson(Map json) { + final delta = json['delta']; + return SemanticTokensOptionsFull(delta: delta); + } + + /// The server supports deltas for full documents. + final bool delta; + + Map toJson() { + var __result = {}; + if (delta != null) { + __result['delta'] = delta; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('delta'); + try { + if (obj['delta'] != null && !(obj['delta'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensOptionsFull'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensOptionsFull && + other.runtimeType == SemanticTokensOptionsFull) { + return delta == other.delta && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, delta.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensOptionsRange implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensOptionsRange.canParse, SemanticTokensOptionsRange.fromJson); + + static SemanticTokensOptionsRange fromJson(Map json) { + return SemanticTokensOptionsRange(); + } + + Map toJson() { + var __result = {}; + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + return true; + } else { + reporter.reportError('must be of type SemanticTokensOptionsRange'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensOptionsRange && + other.runtimeType == SemanticTokensOptionsRange) { + return true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensParams + implements WorkDoneProgressParams, PartialResultParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensParams.canParse, SemanticTokensParams.fromJson); + + SemanticTokensParams( + {@required this.textDocument, + this.workDoneToken, + this.partialResultToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + } + static SemanticTokensParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return SemanticTokensParams( + textDocument: textDocument, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensParams && + other.runtimeType == SemanticTokensParams) { + return textDocument == other.textDocument && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensPartialResult implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensPartialResult.canParse, + SemanticTokensPartialResult.fromJson); + + SemanticTokensPartialResult({@required this.data}) { + if (data == null) { + throw 'data is required but was not provided'; + } + } + static SemanticTokensPartialResult fromJson(Map json) { + final data = json['data']?.map((item) => item)?.cast()?.toList(); + return SemanticTokensPartialResult(data: data); + } + + final List data; + + Map toJson() { + var __result = {}; + __result['data'] = data ?? (throw 'data is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('data'); + try { + if (!obj.containsKey('data')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['data'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['data'] is List && + (obj['data'].every((item) => item is num))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensPartialResult'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensPartialResult && + other.runtimeType == SemanticTokensPartialResult) { + return listEqual(data, other.data, (num a, num b) => a == b) && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(data)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensRangeParams + implements WorkDoneProgressParams, PartialResultParams, ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensRangeParams.canParse, SemanticTokensRangeParams.fromJson); + + SemanticTokensRangeParams( + {@required this.textDocument, + @required this.range, + this.workDoneToken, + this.partialResultToken}) { + if (textDocument == null) { + throw 'textDocument is required but was not provided'; + } + if (range == null) { + throw 'range is required but was not provided'; + } + } + static SemanticTokensRangeParams fromJson(Map json) { + final textDocument = json['textDocument'] != null + ? TextDocumentIdentifier.fromJson(json['textDocument']) + : null; + final range = json['range'] != null ? Range.fromJson(json['range']) : null; + final workDoneToken = json['workDoneToken'] is num + ? Either2.t1(json['workDoneToken']) + : (json['workDoneToken'] is String + ? Either2.t2(json['workDoneToken']) + : (json['workDoneToken'] == null + ? null + : (throw '''${json['workDoneToken']} was not one of (num, String)'''))); + final partialResultToken = json['partialResultToken'] is num + ? Either2.t1(json['partialResultToken']) + : (json['partialResultToken'] is String + ? Either2.t2(json['partialResultToken']) + : (json['partialResultToken'] == null + ? null + : (throw '''${json['partialResultToken']} was not one of (num, String)'''))); + return SemanticTokensRangeParams( + textDocument: textDocument, + range: range, + workDoneToken: workDoneToken, + partialResultToken: partialResultToken); + } + + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. + final Either2 partialResultToken; + + /// The range the semantic tokens are requested for. + final Range range; + + /// The text document. + final TextDocumentIdentifier textDocument; + + /// An optional token that a server can use to report work done progress. + final Either2 workDoneToken; + + Map toJson() { + var __result = {}; + __result['textDocument'] = textDocument?.toJson() ?? + (throw 'textDocument is required but was not set'); + __result['range'] = + range?.toJson() ?? (throw 'range is required but was not set'); + if (workDoneToken != null) { + __result['workDoneToken'] = workDoneToken; + } + if (partialResultToken != null) { + __result['partialResultToken'] = partialResultToken; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('textDocument'); + try { + if (!obj.containsKey('textDocument')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['textDocument'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(TextDocumentIdentifier.canParse(obj['textDocument'], reporter))) { + reporter.reportError('must be of type TextDocumentIdentifier'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('range'); + try { + if (!obj.containsKey('range')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['range'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(Range.canParse(obj['range'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneToken'); + try { + if (obj['workDoneToken'] != null && + !((obj['workDoneToken'] is num || + obj['workDoneToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('partialResultToken'); + try { + if (obj['partialResultToken'] != null && + !((obj['partialResultToken'] is num || + obj['partialResultToken'] is String))) { + reporter.reportError('must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensRangeParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensRangeParams && + other.runtimeType == SemanticTokensRangeParams) { + return textDocument == other.textDocument && + range == other.range && + workDoneToken == other.workDoneToken && + partialResultToken == other.partialResultToken && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, textDocument.hashCode); + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneToken.hashCode); + hash = JenkinsSmiHash.combine(hash, partialResultToken.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensRegistrationOptions + implements + TextDocumentRegistrationOptions, + SemanticTokensOptions, + StaticRegistrationOptions, + ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensRegistrationOptions.canParse, + SemanticTokensRegistrationOptions.fromJson); + + SemanticTokensRegistrationOptions( + {this.documentSelector, + @required this.legend, + this.range, + this.full, + this.workDoneProgress, + this.id}) { + if (legend == null) { + throw 'legend is required but was not provided'; + } + } + static SemanticTokensRegistrationOptions fromJson(Map json) { + final documentSelector = json['documentSelector'] + ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) + ?.cast() + ?.toList(); + final legend = json['legend'] != null + ? SemanticTokensLegend.fromJson(json['legend']) + : null; + final range = json['range'] is bool + ? Either2.t1(json['range']) + : (SemanticTokensOptionsRange.canParse( + json['range'], nullLspJsonReporter) + ? Either2.t2(json['range'] != null + ? SemanticTokensOptionsRange.fromJson(json['range']) + : null) + : (json['range'] == null + ? null + : (throw '''${json['range']} was not one of (bool, SemanticTokensOptionsRange)'''))); + final full = json['full'] is bool + ? Either2.t1(json['full']) + : (SemanticTokensOptionsFull.canParse(json['full'], nullLspJsonReporter) + ? Either2.t2(json['full'] != null + ? SemanticTokensOptionsFull.fromJson(json['full']) + : null) + : (json['full'] == null + ? null + : (throw '''${json['full']} was not one of (bool, SemanticTokensOptionsFull)'''))); + final workDoneProgress = json['workDoneProgress']; + final id = json['id']; + return SemanticTokensRegistrationOptions( + documentSelector: documentSelector, + legend: legend, + range: range, + full: full, + workDoneProgress: workDoneProgress, + id: id); + } + + /// A document selector to identify the scope of the registration. If set to + /// null the document selector provided on the client side will be used. + final List documentSelector; + + /// Server supports providing semantic tokens for a full document. + final Either2 full; + + /// The id used to register the request. The id can be used to deregister the + /// request again. See also Registration#id. + final String id; + + /// The legend used by the server + final SemanticTokensLegend legend; + + /// Server supports providing semantic tokens for a specific range of a + /// document. + final Either2 range; + final bool workDoneProgress; + + Map toJson() { + var __result = {}; + __result['documentSelector'] = documentSelector; + __result['legend'] = + legend?.toJson() ?? (throw 'legend is required but was not set'); + if (range != null) { + __result['range'] = range; + } + if (full != null) { + __result['full'] = full; + } + if (workDoneProgress != null) { + __result['workDoneProgress'] = workDoneProgress; + } + if (id != null) { + __result['id'] = id; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('documentSelector'); + try { + if (!obj.containsKey('documentSelector')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['documentSelector'] != null && + !((obj['documentSelector'] is List && + (obj['documentSelector'].every( + (item) => DocumentFilter.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('legend'); + try { + if (!obj.containsKey('legend')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['legend'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(SemanticTokensLegend.canParse(obj['legend'], reporter))) { + reporter.reportError('must be of type SemanticTokensLegend'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('range'); + try { + if (obj['range'] != null && + !((obj['range'] is bool || + SemanticTokensOptionsRange.canParse(obj['range'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('full'); + try { + if (obj['full'] != null && + !((obj['full'] is bool || + SemanticTokensOptionsFull.canParse(obj['full'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('workDoneProgress'); + try { + if (obj['workDoneProgress'] != null && + !(obj['workDoneProgress'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('id'); + try { + if (obj['id'] != null && !(obj['id'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SemanticTokensRegistrationOptions'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensRegistrationOptions && + other.runtimeType == SemanticTokensRegistrationOptions) { + return listEqual(documentSelector, other.documentSelector, + (DocumentFilter a, DocumentFilter b) => a == b) && + legend == other.legend && + range == other.range && + full == other.full && + workDoneProgress == other.workDoneProgress && + id == other.id && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(documentSelector)); + hash = JenkinsSmiHash.combine(hash, legend.hashCode); + hash = JenkinsSmiHash.combine(hash, range.hashCode); + hash = JenkinsSmiHash.combine(hash, full.hashCode); + hash = JenkinsSmiHash.combine(hash, workDoneProgress.hashCode); + hash = JenkinsSmiHash.combine(hash, id.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SemanticTokensWorkspaceClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + SemanticTokensWorkspaceClientCapabilities.canParse, + SemanticTokensWorkspaceClientCapabilities.fromJson); + + SemanticTokensWorkspaceClientCapabilities({this.refreshSupport}); + static SemanticTokensWorkspaceClientCapabilities fromJson( + Map json) { + final refreshSupport = json['refreshSupport']; + return SemanticTokensWorkspaceClientCapabilities( + refreshSupport: refreshSupport); + } + + /// Whether the client implementation supports a refresh request sent from the + /// server to the client. + /// + /// Note that this event is global and will force the client to refresh all + /// semantic tokens currently shown. It should be used with absolute care and + /// is useful for situation where a server for example detect a project wide + /// change that requires such a calculation. + final bool refreshSupport; + + Map toJson() { + var __result = {}; + if (refreshSupport != null) { + __result['refreshSupport'] = refreshSupport; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('refreshSupport'); + try { + if (obj['refreshSupport'] != null && !(obj['refreshSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type SemanticTokensWorkspaceClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SemanticTokensWorkspaceClientCapabilities && + other.runtimeType == SemanticTokensWorkspaceClientCapabilities) { + return refreshSupport == other.refreshSupport && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, refreshSupport.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ServerCapabilities implements ToJsonable { static const jsonHandler = LspJsonHandler(ServerCapabilities.canParse, ServerCapabilities.fromJson); @@ -18217,21 +25848,29 @@ class ServerCapabilities implements ToJsonable { this.foldingRangeProvider, this.executeCommandProvider, this.selectionRangeProvider, + this.linkedEditingRangeProvider, + this.callHierarchyProvider, + this.semanticTokensProvider, + this.monikerProvider, this.workspaceSymbolProvider, this.workspace, this.experimental}); static ServerCapabilities fromJson(Map json) { final textDocumentSync = TextDocumentSyncOptions.canParse( json['textDocumentSync'], nullLspJsonReporter) - ? Either2.t1( + ? Either2.t1( json['textDocumentSync'] != null ? TextDocumentSyncOptions.fromJson(json['textDocumentSync']) : null) - : (json['textDocumentSync'] is num - ? Either2.t2(json['textDocumentSync']) + : (TextDocumentSyncKind.canParse( + json['textDocumentSync'], nullLspJsonReporter) + ? Either2.t2( + json['textDocumentSync'] != null + ? TextDocumentSyncKind.fromJson(json['textDocumentSync']) + : null) : (json['textDocumentSync'] == null ? null - : (throw '''${json['textDocumentSync']} was not one of (TextDocumentSyncOptions, num)'''))); + : (throw '''${json['textDocumentSync']} was not one of (TextDocumentSyncOptions, TextDocumentSyncKind)'''))); final completionProvider = json['completionProvider'] != null ? CompletionOptions.fromJson(json['completionProvider']) : null; @@ -18468,6 +26107,77 @@ class ServerCapabilities implements ToJsonable { : (json['selectionRangeProvider'] == null ? null : (throw '''${json['selectionRangeProvider']} was not one of (bool, SelectionRangeOptions, SelectionRangeRegistrationOptions)''')))); + final linkedEditingRangeProvider = json['linkedEditingRangeProvider'] + is bool + ? Either3.t1( + json['linkedEditingRangeProvider']) + : (LinkedEditingRangeOptions.canParse(json['linkedEditingRangeProvider'], nullLspJsonReporter) + ? Either3.t2( + json['linkedEditingRangeProvider'] != null + ? LinkedEditingRangeOptions.fromJson( + json['linkedEditingRangeProvider']) + : null) + : (LinkedEditingRangeRegistrationOptions.canParse(json['linkedEditingRangeProvider'], nullLspJsonReporter) + ? Either3.t3( + json['linkedEditingRangeProvider'] != null + ? LinkedEditingRangeRegistrationOptions.fromJson( + json['linkedEditingRangeProvider']) + : null) + : (json['linkedEditingRangeProvider'] == null + ? null + : (throw '''${json['linkedEditingRangeProvider']} was not one of (bool, LinkedEditingRangeOptions, LinkedEditingRangeRegistrationOptions)''')))); + final callHierarchyProvider = json['callHierarchyProvider'] is bool + ? Either3.t1( + json['callHierarchyProvider']) + : (CallHierarchyOptions.canParse( + json['callHierarchyProvider'], nullLspJsonReporter) + ? Either3.t2(json['callHierarchyProvider'] != null + ? CallHierarchyOptions.fromJson(json['callHierarchyProvider']) + : null) + : (CallHierarchyRegistrationOptions.canParse( + json['callHierarchyProvider'], nullLspJsonReporter) + ? Either3.t3( + json['callHierarchyProvider'] != null + ? CallHierarchyRegistrationOptions.fromJson( + json['callHierarchyProvider']) + : null) + : (json['callHierarchyProvider'] == null + ? null + : (throw '''${json['callHierarchyProvider']} was not one of (bool, CallHierarchyOptions, CallHierarchyRegistrationOptions)''')))); + final semanticTokensProvider = SemanticTokensOptions.canParse( + json['semanticTokensProvider'], nullLspJsonReporter) + ? Either2.t1( + json['semanticTokensProvider'] != null + ? SemanticTokensOptions.fromJson(json['semanticTokensProvider']) + : null) + : (SemanticTokensRegistrationOptions.canParse( + json['semanticTokensProvider'], nullLspJsonReporter) + ? Either2.t2( + json['semanticTokensProvider'] != null + ? SemanticTokensRegistrationOptions.fromJson( + json['semanticTokensProvider']) + : null) + : (json['semanticTokensProvider'] == null + ? null + : (throw '''${json['semanticTokensProvider']} was not one of (SemanticTokensOptions, SemanticTokensRegistrationOptions)'''))); + final monikerProvider = json['monikerProvider'] is bool + ? Either3.t1( + json['monikerProvider']) + : (MonikerOptions.canParse(json['monikerProvider'], nullLspJsonReporter) + ? Either3.t2( + json['monikerProvider'] != null + ? MonikerOptions.fromJson(json['monikerProvider']) + : null) + : (MonikerRegistrationOptions.canParse( + json['monikerProvider'], nullLspJsonReporter) + ? Either3.t3( + json['monikerProvider'] != null + ? MonikerRegistrationOptions.fromJson( + json['monikerProvider']) + : null) + : (json['monikerProvider'] == null + ? null + : (throw '''${json['monikerProvider']} was not one of (bool, MonikerOptions, MonikerRegistrationOptions)''')))); final workspaceSymbolProvider = json['workspaceSymbolProvider'] is bool ? Either2.t1( json['workspaceSymbolProvider']) @@ -18508,17 +26218,26 @@ class ServerCapabilities implements ToJsonable { foldingRangeProvider: foldingRangeProvider, executeCommandProvider: executeCommandProvider, selectionRangeProvider: selectionRangeProvider, + linkedEditingRangeProvider: linkedEditingRangeProvider, + callHierarchyProvider: callHierarchyProvider, + semanticTokensProvider: semanticTokensProvider, + monikerProvider: monikerProvider, workspaceSymbolProvider: workspaceSymbolProvider, workspace: workspace, experimental: experimental); } + /// The server provides call hierarchy support. + /// @since 3.16.0 + final Either3 + callHierarchyProvider; + /// The server provides code actions. The `CodeActionOptions` return type is /// only valid if the client signals code action literal support via the /// property `textDocument.codeAction.codeActionLiteralSupport`. final Either2 codeActionProvider; - /// The server provides CodeLens. + /// The server provides code lens. final CodeLensOptions codeLensProvider; /// The server provides color provider support. @@ -18575,6 +26294,16 @@ class ServerCapabilities implements ToJsonable { final Either3 implementationProvider; + /// The server provides linked editing range support. + /// @since 3.16.0 - proposed state + final Either3 linkedEditingRangeProvider; + + /// Whether server provides moniker support. + /// @since 3.16.0 - proposed state + final Either3 + monikerProvider; + /// The server provides find references support. final Either2 referencesProvider; @@ -18588,14 +26317,19 @@ class ServerCapabilities implements ToJsonable { final Either3 selectionRangeProvider; + /// The server provides semantic tokens support. + /// @since 3.16.0 + final Either2 + semanticTokensProvider; + /// The server provides signature help support. final SignatureHelpOptions signatureHelpProvider; /// Defines how text documents are synced. Is either a detailed structure - /// defining each notification or for backwards compatibility, the - /// TextDocumentSyncKind number. If omitted, it defaults to + /// defining each notification or for backwards compatibility the + /// TextDocumentSyncKind number. If omitted it defaults to /// `TextDocumentSyncKind.None`. - final Either2 textDocumentSync; + final Either2 textDocumentSync; /// The server provides goto type definition support. /// @since 3.6.0 @@ -18678,6 +26412,18 @@ class ServerCapabilities implements ToJsonable { if (selectionRangeProvider != null) { __result['selectionRangeProvider'] = selectionRangeProvider; } + if (linkedEditingRangeProvider != null) { + __result['linkedEditingRangeProvider'] = linkedEditingRangeProvider; + } + if (callHierarchyProvider != null) { + __result['callHierarchyProvider'] = callHierarchyProvider; + } + if (semanticTokensProvider != null) { + __result['semanticTokensProvider'] = semanticTokensProvider; + } + if (monikerProvider != null) { + __result['monikerProvider'] = monikerProvider; + } if (workspaceSymbolProvider != null) { __result['workspaceSymbolProvider'] = workspaceSymbolProvider; } @@ -18697,9 +26443,10 @@ class ServerCapabilities implements ToJsonable { if (obj['textDocumentSync'] != null && !((TextDocumentSyncOptions.canParse( obj['textDocumentSync'], reporter) || - obj['textDocumentSync'] is num))) { + TextDocumentSyncKind.canParse( + obj['textDocumentSync'], reporter)))) { reporter.reportError( - 'must be of type Either2'); + 'must be of type Either2'); return false; } } finally { @@ -18973,6 +26720,64 @@ class ServerCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('linkedEditingRangeProvider'); + try { + if (obj['linkedEditingRangeProvider'] != null && + !((obj['linkedEditingRangeProvider'] is bool || + LinkedEditingRangeOptions.canParse( + obj['linkedEditingRangeProvider'], reporter) || + LinkedEditingRangeRegistrationOptions.canParse( + obj['linkedEditingRangeProvider'], reporter)))) { + reporter.reportError( + 'must be of type Either3'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('callHierarchyProvider'); + try { + if (obj['callHierarchyProvider'] != null && + !((obj['callHierarchyProvider'] is bool || + CallHierarchyOptions.canParse( + obj['callHierarchyProvider'], reporter) || + CallHierarchyRegistrationOptions.canParse( + obj['callHierarchyProvider'], reporter)))) { + reporter.reportError( + 'must be of type Either3'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('semanticTokensProvider'); + try { + if (obj['semanticTokensProvider'] != null && + !((SemanticTokensOptions.canParse( + obj['semanticTokensProvider'], reporter) || + SemanticTokensRegistrationOptions.canParse( + obj['semanticTokensProvider'], reporter)))) { + reporter.reportError( + 'must be of type Either2'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('monikerProvider'); + try { + if (obj['monikerProvider'] != null && + !((obj['monikerProvider'] is bool || + MonikerOptions.canParse(obj['monikerProvider'], reporter) || + MonikerRegistrationOptions.canParse( + obj['monikerProvider'], reporter)))) { + reporter.reportError( + 'must be of type Either3'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('workspaceSymbolProvider'); try { if (obj['workspaceSymbolProvider'] != null && @@ -19041,6 +26846,10 @@ class ServerCapabilities implements ToJsonable { foldingRangeProvider == other.foldingRangeProvider && executeCommandProvider == other.executeCommandProvider && selectionRangeProvider == other.selectionRangeProvider && + linkedEditingRangeProvider == other.linkedEditingRangeProvider && + callHierarchyProvider == other.callHierarchyProvider && + semanticTokensProvider == other.semanticTokensProvider && + monikerProvider == other.monikerProvider && workspaceSymbolProvider == other.workspaceSymbolProvider && workspace == other.workspace && experimental == other.experimental && @@ -19076,6 +26885,10 @@ class ServerCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, foldingRangeProvider.hashCode); hash = JenkinsSmiHash.combine(hash, executeCommandProvider.hashCode); hash = JenkinsSmiHash.combine(hash, selectionRangeProvider.hashCode); + hash = JenkinsSmiHash.combine(hash, linkedEditingRangeProvider.hashCode); + hash = JenkinsSmiHash.combine(hash, callHierarchyProvider.hashCode); + hash = JenkinsSmiHash.combine(hash, semanticTokensProvider.hashCode); + hash = JenkinsSmiHash.combine(hash, monikerProvider.hashCode); hash = JenkinsSmiHash.combine(hash, workspaceSymbolProvider.hashCode); hash = JenkinsSmiHash.combine(hash, workspace.hashCode); hash = JenkinsSmiHash.combine(hash, experimental.hashCode); @@ -19086,19 +26899,220 @@ class ServerCapabilities implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class ServerCapabilitiesFileOperations implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ServerCapabilitiesFileOperations.canParse, + ServerCapabilitiesFileOperations.fromJson); + + ServerCapabilitiesFileOperations( + {this.didCreate, + this.willCreate, + this.didRename, + this.willRename, + this.didDelete, + this.willDelete}); + static ServerCapabilitiesFileOperations fromJson(Map json) { + final didCreate = json['didCreate'] != null + ? FileOperationRegistrationOptions.fromJson(json['didCreate']) + : null; + final willCreate = json['willCreate'] != null + ? FileOperationRegistrationOptions.fromJson(json['willCreate']) + : null; + final didRename = json['didRename'] != null + ? FileOperationRegistrationOptions.fromJson(json['didRename']) + : null; + final willRename = json['willRename'] != null + ? FileOperationRegistrationOptions.fromJson(json['willRename']) + : null; + final didDelete = json['didDelete'] != null + ? FileOperationRegistrationOptions.fromJson(json['didDelete']) + : null; + final willDelete = json['willDelete'] != null + ? FileOperationRegistrationOptions.fromJson(json['willDelete']) + : null; + return ServerCapabilitiesFileOperations( + didCreate: didCreate, + willCreate: willCreate, + didRename: didRename, + willRename: willRename, + didDelete: didDelete, + willDelete: willDelete); + } + + /// The server is interested in receiving didCreateFiles notifications. + final FileOperationRegistrationOptions didCreate; + + /// The server is interested in receiving didDeleteFiles file notifications. + final FileOperationRegistrationOptions didDelete; + + /// The server is interested in receiving didRenameFiles notifications. + final FileOperationRegistrationOptions didRename; + + /// The server is interested in receiving willCreateFiles requests. + final FileOperationRegistrationOptions willCreate; + + /// The server is interested in receiving willDeleteFiles file requests. + final FileOperationRegistrationOptions willDelete; + + /// The server is interested in receiving willRenameFiles requests. + final FileOperationRegistrationOptions willRename; + + Map toJson() { + var __result = {}; + if (didCreate != null) { + __result['didCreate'] = didCreate.toJson(); + } + if (willCreate != null) { + __result['willCreate'] = willCreate.toJson(); + } + if (didRename != null) { + __result['didRename'] = didRename.toJson(); + } + if (willRename != null) { + __result['willRename'] = willRename.toJson(); + } + if (didDelete != null) { + __result['didDelete'] = didDelete.toJson(); + } + if (willDelete != null) { + __result['willDelete'] = willDelete.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('didCreate'); + try { + if (obj['didCreate'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['didCreate'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willCreate'); + try { + if (obj['willCreate'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['willCreate'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('didRename'); + try { + if (obj['didRename'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['didRename'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willRename'); + try { + if (obj['willRename'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['willRename'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('didDelete'); + try { + if (obj['didDelete'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['didDelete'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('willDelete'); + try { + if (obj['willDelete'] != null && + !(FileOperationRegistrationOptions.canParse( + obj['willDelete'], reporter))) { + reporter + .reportError('must be of type FileOperationRegistrationOptions'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ServerCapabilitiesFileOperations'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ServerCapabilitiesFileOperations && + other.runtimeType == ServerCapabilitiesFileOperations) { + return didCreate == other.didCreate && + willCreate == other.willCreate && + didRename == other.didRename && + willRename == other.willRename && + didDelete == other.didDelete && + willDelete == other.willDelete && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, didCreate.hashCode); + hash = JenkinsSmiHash.combine(hash, willCreate.hashCode); + hash = JenkinsSmiHash.combine(hash, didRename.hashCode); + hash = JenkinsSmiHash.combine(hash, willRename.hashCode); + hash = JenkinsSmiHash.combine(hash, didDelete.hashCode); + hash = JenkinsSmiHash.combine(hash, willDelete.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ServerCapabilitiesWorkspace implements ToJsonable { static const jsonHandler = LspJsonHandler( ServerCapabilitiesWorkspace.canParse, ServerCapabilitiesWorkspace.fromJson); - ServerCapabilitiesWorkspace({this.workspaceFolders}); + ServerCapabilitiesWorkspace({this.workspaceFolders, this.fileOperations}); static ServerCapabilitiesWorkspace fromJson(Map json) { final workspaceFolders = json['workspaceFolders'] != null ? WorkspaceFoldersServerCapabilities.fromJson(json['workspaceFolders']) : null; - return ServerCapabilitiesWorkspace(workspaceFolders: workspaceFolders); + final fileOperations = json['fileOperations'] != null + ? ServerCapabilitiesFileOperations.fromJson(json['fileOperations']) + : null; + return ServerCapabilitiesWorkspace( + workspaceFolders: workspaceFolders, fileOperations: fileOperations); } + /// The server is interested in file notifications/requests. + /// @since 3.16.0 - proposed state + final ServerCapabilitiesFileOperations fileOperations; + /// The server supports workspace folder. /// @since 3.6.0 final WorkspaceFoldersServerCapabilities workspaceFolders; @@ -19108,6 +27122,9 @@ class ServerCapabilitiesWorkspace implements ToJsonable { if (workspaceFolders != null) { __result['workspaceFolders'] = workspaceFolders.toJson(); } + if (fileOperations != null) { + __result['fileOperations'] = fileOperations.toJson(); + } return __result; } @@ -19125,6 +27142,18 @@ class ServerCapabilitiesWorkspace implements ToJsonable { } finally { reporter.pop(); } + reporter.push('fileOperations'); + try { + if (obj['fileOperations'] != null && + !(ServerCapabilitiesFileOperations.canParse( + obj['fileOperations'], reporter))) { + reporter + .reportError('must be of type ServerCapabilitiesFileOperations'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type ServerCapabilitiesWorkspace'); @@ -19136,7 +27165,9 @@ class ServerCapabilitiesWorkspace implements ToJsonable { bool operator ==(Object other) { if (other is ServerCapabilitiesWorkspace && other.runtimeType == ServerCapabilitiesWorkspace) { - return workspaceFolders == other.workspaceFolders && true; + return workspaceFolders == other.workspaceFolders && + fileOperations == other.fileOperations && + true; } return false; } @@ -19145,6 +27176,363 @@ class ServerCapabilitiesWorkspace implements ToJsonable { int get hashCode { var hash = 0; hash = JenkinsSmiHash.combine(hash, workspaceFolders.hashCode); + hash = JenkinsSmiHash.combine(hash, fileOperations.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class SetTraceParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(SetTraceParams.canParse, SetTraceParams.fromJson); + + SetTraceParams({@required this.value}) { + if (value == null) { + throw 'value is required but was not provided'; + } + } + static SetTraceParams fromJson(Map json) { + final value = const {'off', 'message', 'verbose'}.contains(json['value']) + ? json['value'] + : throw '''${json['value']} was not one of ('off', 'message', 'verbose')'''; + return SetTraceParams(value: value); + } + + /// The new value that should be assigned to the trace setting. + final String value; + + Map toJson() { + var __result = {}; + __result['value'] = value ?? (throw 'value is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('value'); + try { + if (!obj.containsKey('value')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['value'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['value'] == 'off' || + obj['value'] == 'message' || + obj['value'] == 'verbose'))) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type SetTraceParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is SetTraceParams && other.runtimeType == SetTraceParams) { + return value == other.value && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, value.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// Client capabilities for the show document request. +/// @since 3.16.0 - proposed state +class ShowDocumentClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ShowDocumentClientCapabilities.canParse, + ShowDocumentClientCapabilities.fromJson); + + ShowDocumentClientCapabilities({@required this.support}) { + if (support == null) { + throw 'support is required but was not provided'; + } + } + static ShowDocumentClientCapabilities fromJson(Map json) { + final support = json['support']; + return ShowDocumentClientCapabilities(support: support); + } + + /// The client has support for the show document request. + final bool support; + + Map toJson() { + var __result = {}; + __result['support'] = + support ?? (throw 'support is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('support'); + try { + if (!obj.containsKey('support')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['support'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['support'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ShowDocumentClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ShowDocumentClientCapabilities && + other.runtimeType == ShowDocumentClientCapabilities) { + return support == other.support && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, support.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// Params to show a document. +/// @since 3.16.0 - proposed state +class ShowDocumentParams implements ToJsonable { + static const jsonHandler = + LspJsonHandler(ShowDocumentParams.canParse, ShowDocumentParams.fromJson); + + ShowDocumentParams( + {@required this.uri, this.external, this.takeFocus, this.selection}) { + if (uri == null) { + throw 'uri is required but was not provided'; + } + } + static ShowDocumentParams fromJson(Map json) { + final uri = json['uri']; + final external = json['external']; + final takeFocus = json['takeFocus']; + final selection = + json['selection'] != null ? Range.fromJson(json['selection']) : null; + return ShowDocumentParams( + uri: uri, + external: external, + takeFocus: takeFocus, + selection: selection); + } + + /// Indicates to show the resource in an external program. To show for example + /// `https://code.visualstudio.com/` in the default WEB browser set `external` + /// to `true`. + final bool external; + + /// An optional selection range if the document is a text document. Clients + /// might ignore the property if an external program is started or the file is + /// not a text file. + final Range selection; + + /// An optional property to indicate whether the editor showing the document + /// should take focus or not. Clients might ignore this property if an + /// external program is started. + final bool takeFocus; + + /// The document uri to show. + final String uri; + + Map toJson() { + var __result = {}; + __result['uri'] = uri ?? (throw 'uri is required but was not set'); + if (external != null) { + __result['external'] = external; + } + if (takeFocus != null) { + __result['takeFocus'] = takeFocus; + } + if (selection != null) { + __result['selection'] = selection.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('uri'); + try { + if (!obj.containsKey('uri')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['uri'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['uri'] is String)) { + reporter.reportError('must be of type String'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('external'); + try { + if (obj['external'] != null && !(obj['external'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('takeFocus'); + try { + if (obj['takeFocus'] != null && !(obj['takeFocus'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('selection'); + try { + if (obj['selection'] != null && + !(Range.canParse(obj['selection'], reporter))) { + reporter.reportError('must be of type Range'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ShowDocumentParams'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ShowDocumentParams && + other.runtimeType == ShowDocumentParams) { + return uri == other.uri && + external == other.external && + takeFocus == other.takeFocus && + selection == other.selection && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, uri.hashCode); + hash = JenkinsSmiHash.combine(hash, external.hashCode); + hash = JenkinsSmiHash.combine(hash, takeFocus.hashCode); + hash = JenkinsSmiHash.combine(hash, selection.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +/// The result of an show document request. +/// @since 3.16.0 - proposed state +class ShowDocumentResult implements ToJsonable { + static const jsonHandler = + LspJsonHandler(ShowDocumentResult.canParse, ShowDocumentResult.fromJson); + + ShowDocumentResult({@required this.success}) { + if (success == null) { + throw 'success is required but was not provided'; + } + } + static ShowDocumentResult fromJson(Map json) { + final success = json['success']; + return ShowDocumentResult(success: success); + } + + /// A boolean indicating if the show was successful. + final bool success; + + Map toJson() { + var __result = {}; + __result['success'] = + success ?? (throw 'success is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('success'); + try { + if (!obj.containsKey('success')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['success'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['success'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError('must be of type ShowDocumentResult'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ShowDocumentResult && + other.runtimeType == ShowDocumentResult) { + return success == other.success && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, success.hashCode); return JenkinsSmiHash.finish(hash); } @@ -19249,6 +27637,145 @@ class ShowMessageParams implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +/// Show message request client capabilities +class ShowMessageRequestClientCapabilities implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ShowMessageRequestClientCapabilities.canParse, + ShowMessageRequestClientCapabilities.fromJson); + + ShowMessageRequestClientCapabilities({this.messageActionItem}); + static ShowMessageRequestClientCapabilities fromJson( + Map json) { + final messageActionItem = json['messageActionItem'] != null + ? ShowMessageRequestClientCapabilitiesMessageActionItem.fromJson( + json['messageActionItem']) + : null; + return ShowMessageRequestClientCapabilities( + messageActionItem: messageActionItem); + } + + /// Capabilities specific to the `MessageActionItem` type. + final ShowMessageRequestClientCapabilitiesMessageActionItem messageActionItem; + + Map toJson() { + var __result = {}; + if (messageActionItem != null) { + __result['messageActionItem'] = messageActionItem.toJson(); + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('messageActionItem'); + try { + if (obj['messageActionItem'] != null && + !(ShowMessageRequestClientCapabilitiesMessageActionItem.canParse( + obj['messageActionItem'], reporter))) { + reporter.reportError( + 'must be of type ShowMessageRequestClientCapabilitiesMessageActionItem'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter + .reportError('must be of type ShowMessageRequestClientCapabilities'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ShowMessageRequestClientCapabilities && + other.runtimeType == ShowMessageRequestClientCapabilities) { + return messageActionItem == other.messageActionItem && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, messageActionItem.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class ShowMessageRequestClientCapabilitiesMessageActionItem + implements ToJsonable { + static const jsonHandler = LspJsonHandler( + ShowMessageRequestClientCapabilitiesMessageActionItem.canParse, + ShowMessageRequestClientCapabilitiesMessageActionItem.fromJson); + + ShowMessageRequestClientCapabilitiesMessageActionItem( + {this.additionalPropertiesSupport}); + static ShowMessageRequestClientCapabilitiesMessageActionItem fromJson( + Map json) { + final additionalPropertiesSupport = json['additionalPropertiesSupport']; + return ShowMessageRequestClientCapabilitiesMessageActionItem( + additionalPropertiesSupport: additionalPropertiesSupport); + } + + /// Whether the client supports additional attributes which are preserved and + /// sent back to the server in the request's response. + final bool additionalPropertiesSupport; + + Map toJson() { + var __result = {}; + if (additionalPropertiesSupport != null) { + __result['additionalPropertiesSupport'] = additionalPropertiesSupport; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('additionalPropertiesSupport'); + try { + if (obj['additionalPropertiesSupport'] != null && + !(obj['additionalPropertiesSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type ShowMessageRequestClientCapabilitiesMessageActionItem'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is ShowMessageRequestClientCapabilitiesMessageActionItem && + other.runtimeType == + ShowMessageRequestClientCapabilitiesMessageActionItem) { + return additionalPropertiesSupport == other.additionalPropertiesSupport && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, additionalPropertiesSupport.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class ShowMessageRequestParams implements ToJsonable { static const jsonHandler = LspJsonHandler( ShowMessageRequestParams.canParse, ShowMessageRequestParams.fromJson); @@ -19703,7 +28230,9 @@ class SignatureHelpClientCapabilitiesSignatureInformation SignatureHelpClientCapabilitiesSignatureInformation.fromJson); SignatureHelpClientCapabilitiesSignatureInformation( - {this.documentationFormat, this.parameterInformation}); + {this.documentationFormat, + this.parameterInformation, + this.activeParameterSupport}); static SignatureHelpClientCapabilitiesSignatureInformation fromJson( Map json) { final documentationFormat = json['documentationFormat'] @@ -19714,11 +28243,18 @@ class SignatureHelpClientCapabilitiesSignatureInformation ? SignatureHelpClientCapabilitiesParameterInformation.fromJson( json['parameterInformation']) : null; + final activeParameterSupport = json['activeParameterSupport']; return SignatureHelpClientCapabilitiesSignatureInformation( documentationFormat: documentationFormat, - parameterInformation: parameterInformation); + parameterInformation: parameterInformation, + activeParameterSupport: activeParameterSupport); } + /// The client supports the `activeParameter` property on + /// `SignatureInformation` literal. + /// @since 3.16.0 - proposed state + final bool activeParameterSupport; + /// Client supports the follow content formats for the documentation property. /// The order describes the preferred format of the client. final List documentationFormat; @@ -19735,6 +28271,9 @@ class SignatureHelpClientCapabilitiesSignatureInformation if (parameterInformation != null) { __result['parameterInformation'] = parameterInformation.toJson(); } + if (activeParameterSupport != null) { + __result['activeParameterSupport'] = activeParameterSupport; + } return __result; } @@ -19764,6 +28303,16 @@ class SignatureHelpClientCapabilitiesSignatureInformation } finally { reporter.pop(); } + reporter.push('activeParameterSupport'); + try { + if (obj['activeParameterSupport'] != null && + !(obj['activeParameterSupport'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError( @@ -19780,6 +28329,7 @@ class SignatureHelpClientCapabilitiesSignatureInformation return listEqual(documentationFormat, other.documentationFormat, (MarkupKind a, MarkupKind b) => a == b) && parameterInformation == other.parameterInformation && + activeParameterSupport == other.activeParameterSupport && true; } return false; @@ -19790,6 +28340,7 @@ class SignatureHelpClientCapabilitiesSignatureInformation var hash = 0; hash = JenkinsSmiHash.combine(hash, lspHashCode(documentationFormat)); hash = JenkinsSmiHash.combine(hash, parameterInformation.hashCode); + hash = JenkinsSmiHash.combine(hash, activeParameterSupport.hashCode); return JenkinsSmiHash.finish(hash); } @@ -19847,8 +28398,8 @@ class SignatureHelpContext implements ToJsonable { /// Character that caused signature help to be triggered. /// - /// This is undefined when `triggerKind !== - /// SignatureHelpTriggerKind.TriggerCharacter`. + /// This is undefined when triggerKind !== + /// SignatureHelpTriggerKind.TriggerCharacter final String triggerCharacter; /// Action that caused signature help to be triggered. @@ -20123,7 +28674,7 @@ class SignatureHelpParams /// The signature help context. This is only available if the client specifies /// to send this using the client capability - /// `textDocument.signatureHelp.contextSupport === true`. + /// `textDocument.signatureHelp.contextSupport === true` /// @since 3.15.0 final SignatureHelpContext context; @@ -20278,7 +28829,7 @@ class SignatureHelpRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// List of characters that re-trigger signature help. @@ -20436,7 +28987,10 @@ class SignatureInformation implements ToJsonable { SignatureInformation.canParse, SignatureInformation.fromJson); SignatureInformation( - {@required this.label, this.documentation, this.parameters}) { + {@required this.label, + this.documentation, + this.parameters, + this.activeParameter}) { if (label == null) { throw 'label is required but was not provided'; } @@ -20457,10 +29011,20 @@ class SignatureInformation implements ToJsonable { (item) => item != null ? ParameterInformation.fromJson(item) : null) ?.cast() ?.toList(); + final activeParameter = json['activeParameter']; return SignatureInformation( - label: label, documentation: documentation, parameters: parameters); + label: label, + documentation: documentation, + parameters: parameters, + activeParameter: activeParameter); } + /// The index of the active parameter. + /// + /// If provided, this is used in place of `SignatureHelp.activeParameter`. + /// @since 3.16.0 - proposed state + final num activeParameter; + /// The human-readable doc-comment of this signature. Will be shown in the UI /// but can be omitted. final Either2 documentation; @@ -20480,6 +29044,9 @@ class SignatureInformation implements ToJsonable { if (parameters != null) { __result['parameters'] = parameters; } + if (activeParameter != null) { + __result['activeParameter'] = activeParameter; + } return __result; } @@ -20526,6 +29093,16 @@ class SignatureInformation implements ToJsonable { } finally { reporter.pop(); } + reporter.push('activeParameter'); + try { + if (obj['activeParameter'] != null && + !(obj['activeParameter'] is num)) { + reporter.reportError('must be of type num'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type SignatureInformation'); @@ -20541,6 +29118,7 @@ class SignatureInformation implements ToJsonable { documentation == other.documentation && listEqual(parameters, other.parameters, (ParameterInformation a, ParameterInformation b) => a == b) && + activeParameter == other.activeParameter && true; } return false; @@ -20552,6 +29130,7 @@ class SignatureInformation implements ToJsonable { hash = JenkinsSmiHash.combine(hash, label.hashCode); hash = JenkinsSmiHash.combine(hash, documentation.hashCode); hash = JenkinsSmiHash.combine(hash, lspHashCode(parameters)); + hash = JenkinsSmiHash.combine(hash, activeParameter.hashCode); return JenkinsSmiHash.finish(hash); } @@ -20584,6 +29163,16 @@ class StaticRegistrationOptions implements ToJsonable { if (SelectionRangeRegistrationOptions.canParse(json, nullLspJsonReporter)) { return SelectionRangeRegistrationOptions.fromJson(json); } + if (CallHierarchyRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return CallHierarchyRegistrationOptions.fromJson(json); + } + if (SemanticTokensRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return SemanticTokensRegistrationOptions.fromJson(json); + } + if (LinkedEditingRangeRegistrationOptions.canParse( + json, nullLspJsonReporter)) { + return LinkedEditingRangeRegistrationOptions.fromJson(json); + } final id = json['id']; return StaticRegistrationOptions(id: id); } @@ -20647,6 +29236,7 @@ class SymbolInformation implements ToJsonable { SymbolInformation( {@required this.name, @required this.kind, + this.tags, this.deprecated, @required this.location, this.containerName}) { @@ -20664,6 +29254,10 @@ class SymbolInformation implements ToJsonable { final name = json['name']; final kind = json['kind'] != null ? SymbolKind.fromJson(json['kind']) : null; + final tags = json['tags'] + ?.map((item) => item != null ? SymbolTag.fromJson(item) : null) + ?.cast() + ?.toList(); final deprecated = json['deprecated']; final location = json['location'] != null ? Location.fromJson(json['location']) : null; @@ -20671,6 +29265,7 @@ class SymbolInformation implements ToJsonable { return SymbolInformation( name: name, kind: kind, + tags: tags, deprecated: deprecated, location: location, containerName: containerName); @@ -20683,6 +29278,7 @@ class SymbolInformation implements ToJsonable { final String containerName; /// Indicates if this symbol is deprecated. + /// @deprecated Use tags instead final bool deprecated; /// The kind of this symbol. @@ -20702,11 +29298,18 @@ class SymbolInformation implements ToJsonable { /// The name of this symbol. final String name; + /// Tags for this completion item. + /// @since 3.16.0 + final List tags; + Map toJson() { var __result = {}; __result['name'] = name ?? (throw 'name is required but was not set'); __result['kind'] = kind?.toJson() ?? (throw 'kind is required but was not set'); + if (tags != null) { + __result['tags'] = tags; + } if (deprecated != null) { __result['deprecated'] = deprecated; } @@ -20754,6 +29357,18 @@ class SymbolInformation implements ToJsonable { } finally { reporter.pop(); } + reporter.push('tags'); + try { + if (obj['tags'] != null && + !((obj['tags'] is List && + (obj['tags'] + .every((item) => SymbolTag.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } reporter.push('deprecated'); try { if (obj['deprecated'] != null && !(obj['deprecated'] is bool)) { @@ -20801,6 +29416,7 @@ class SymbolInformation implements ToJsonable { if (other is SymbolInformation && other.runtimeType == SymbolInformation) { return name == other.name && kind == other.kind && + listEqual(tags, other.tags, (SymbolTag a, SymbolTag b) => a == b) && deprecated == other.deprecated && location == other.location && containerName == other.containerName && @@ -20814,6 +29430,7 @@ class SymbolInformation implements ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, name.hashCode); hash = JenkinsSmiHash.combine(hash, kind.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(tags)); hash = JenkinsSmiHash.combine(hash, deprecated.hashCode); hash = JenkinsSmiHash.combine(hash, location.hashCode); hash = JenkinsSmiHash.combine(hash, containerName.hashCode); @@ -20873,6 +29490,32 @@ class SymbolKind { bool operator ==(Object o) => o is SymbolKind && o._value == _value; } +/// Symbol tags are extra annotations that tweak the rendering of a symbol. +/// @since 3.16 +class SymbolTag { + const SymbolTag(this._value); + const SymbolTag.fromJson(this._value); + + final num _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is num; + } + + /// Render a symbol as obsolete, usually using a strike-out. + static const Deprecated = SymbolTag(1); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is SymbolTag && o._value == _value; +} + /// Describe options to be used when registering for text document change /// events. class TextDocumentChangeRegistrationOptions @@ -20901,7 +29544,7 @@ class TextDocumentChangeRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// How documents are synced to the server. See TextDocumentSyncKind.Full and @@ -21011,7 +29654,11 @@ class TextDocumentClientCapabilities implements ToJsonable { this.rename, this.publishDiagnostics, this.foldingRange, - this.selectionRange}); + this.selectionRange, + this.linkedEditingRange, + this.callHierarchy, + this.semanticTokens, + this.moniker}); static TextDocumentClientCapabilities fromJson(Map json) { final synchronization = json['synchronization'] != null ? TextDocumentSyncClientCapabilities.fromJson(json['synchronization']) @@ -21083,6 +29730,19 @@ class TextDocumentClientCapabilities implements ToJsonable { final selectionRange = json['selectionRange'] != null ? SelectionRangeClientCapabilities.fromJson(json['selectionRange']) : null; + final linkedEditingRange = json['linkedEditingRange'] != null + ? LinkedEditingRangeClientCapabilities.fromJson( + json['linkedEditingRange']) + : null; + final callHierarchy = json['callHierarchy'] != null + ? CallHierarchyClientCapabilities.fromJson(json['callHierarchy']) + : null; + final semanticTokens = json['semanticTokens'] != null + ? SemanticTokensClientCapabilities.fromJson(json['semanticTokens']) + : null; + final moniker = json['moniker'] != null + ? MonikerClientCapabilities.fromJson(json['moniker']) + : null; return TextDocumentClientCapabilities( synchronization: synchronization, completion: completion, @@ -21105,9 +29765,17 @@ class TextDocumentClientCapabilities implements ToJsonable { rename: rename, publishDiagnostics: publishDiagnostics, foldingRange: foldingRange, - selectionRange: selectionRange); + selectionRange: selectionRange, + linkedEditingRange: linkedEditingRange, + callHierarchy: callHierarchy, + semanticTokens: semanticTokens, + moniker: moniker); } + /// Capabilities specific to the various call hierarchy requests. + /// @since 3.16.0 + final CallHierarchyClientCapabilities callHierarchy; + /// Capabilities specific to the `textDocument/codeAction` request. final CodeActionClientCapabilities codeAction; @@ -21152,6 +29820,14 @@ class TextDocumentClientCapabilities implements ToJsonable { /// @since 3.6.0 final ImplementationClientCapabilities implementation; + /// Capabilities specific to the `textDocument/linkedEditingRange` request. + /// @since 3.16.0 + final LinkedEditingRangeClientCapabilities linkedEditingRange; + + /// Capabilities specific to the `textDocument/moniker` request. + /// @since 3.16.0 + final MonikerClientCapabilities moniker; + /// request. Capabilities specific to the `textDocument/onTypeFormatting` /// request. final DocumentOnTypeFormattingClientCapabilities onTypeFormatting; @@ -21173,6 +29849,10 @@ class TextDocumentClientCapabilities implements ToJsonable { /// @since 3.15.0 final SelectionRangeClientCapabilities selectionRange; + /// Capabilities specific to the various semantic token requests. + /// @since 3.16.0 + final SemanticTokensClientCapabilities semanticTokens; + /// Capabilities specific to the `textDocument/signatureHelp` request. final SignatureHelpClientCapabilities signatureHelp; final TextDocumentSyncClientCapabilities synchronization; @@ -21249,6 +29929,18 @@ class TextDocumentClientCapabilities implements ToJsonable { if (selectionRange != null) { __result['selectionRange'] = selectionRange.toJson(); } + if (linkedEditingRange != null) { + __result['linkedEditingRange'] = linkedEditingRange.toJson(); + } + if (callHierarchy != null) { + __result['callHierarchy'] = callHierarchy.toJson(); + } + if (semanticTokens != null) { + __result['semanticTokens'] = semanticTokens.toJson(); + } + if (moniker != null) { + __result['moniker'] = moniker.toJson(); + } return __result; } @@ -21507,6 +30199,52 @@ class TextDocumentClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('linkedEditingRange'); + try { + if (obj['linkedEditingRange'] != null && + !(LinkedEditingRangeClientCapabilities.canParse( + obj['linkedEditingRange'], reporter))) { + reporter.reportError( + 'must be of type LinkedEditingRangeClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('callHierarchy'); + try { + if (obj['callHierarchy'] != null && + !(CallHierarchyClientCapabilities.canParse( + obj['callHierarchy'], reporter))) { + reporter + .reportError('must be of type CallHierarchyClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('semanticTokens'); + try { + if (obj['semanticTokens'] != null && + !(SemanticTokensClientCapabilities.canParse( + obj['semanticTokens'], reporter))) { + reporter + .reportError('must be of type SemanticTokensClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('moniker'); + try { + if (obj['moniker'] != null && + !(MonikerClientCapabilities.canParse(obj['moniker'], reporter))) { + reporter.reportError('must be of type MonikerClientCapabilities'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type TextDocumentClientCapabilities'); @@ -21540,6 +30278,10 @@ class TextDocumentClientCapabilities implements ToJsonable { publishDiagnostics == other.publishDiagnostics && foldingRange == other.foldingRange && selectionRange == other.selectionRange && + linkedEditingRange == other.linkedEditingRange && + callHierarchy == other.callHierarchy && + semanticTokens == other.semanticTokens && + moniker == other.moniker && true; } return false; @@ -21570,6 +30312,10 @@ class TextDocumentClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, publishDiagnostics.hashCode); hash = JenkinsSmiHash.combine(hash, foldingRange.hashCode); hash = JenkinsSmiHash.combine(hash, selectionRange.hashCode); + hash = JenkinsSmiHash.combine(hash, linkedEditingRange.hashCode); + hash = JenkinsSmiHash.combine(hash, callHierarchy.hashCode); + hash = JenkinsSmiHash.combine(hash, semanticTokens.hashCode); + hash = JenkinsSmiHash.combine(hash, moniker.hashCode); return JenkinsSmiHash.finish(hash); } @@ -21781,20 +30527,28 @@ class TextDocumentEdit implements ToJsonable { } static TextDocumentEdit fromJson(Map json) { final textDocument = json['textDocument'] != null - ? VersionedTextDocumentIdentifier.fromJson(json['textDocument']) + ? OptionalVersionedTextDocumentIdentifier.fromJson(json['textDocument']) : null; final edits = json['edits'] - ?.map((item) => item != null ? TextEdit.fromJson(item) : null) - ?.cast() + ?.map((item) => TextEdit.canParse(item, nullLspJsonReporter) + ? Either2.t1( + item != null ? TextEdit.fromJson(item) : null) + : (AnnotatedTextEdit.canParse(item, nullLspJsonReporter) + ? Either2.t2( + item != null ? AnnotatedTextEdit.fromJson(item) : null) + : (throw '''${item} was not one of (TextEdit, AnnotatedTextEdit)'''))) + ?.cast>() ?.toList(); return TextDocumentEdit(textDocument: textDocument, edits: edits); } /// The edits to be applied. - final List edits; + /// @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the + /// client capability `workspace.workspaceEdit.changeAnnotationSupport` + final List> edits; /// The text document to change. - final VersionedTextDocumentIdentifier textDocument; + final OptionalVersionedTextDocumentIdentifier textDocument; Map toJson() { var __result = {}; @@ -21816,10 +30570,10 @@ class TextDocumentEdit implements ToJsonable { reporter.reportError('must not be null'); return false; } - if (!(VersionedTextDocumentIdentifier.canParse( + if (!(OptionalVersionedTextDocumentIdentifier.canParse( obj['textDocument'], reporter))) { - reporter - .reportError('must be of type VersionedTextDocumentIdentifier'); + reporter.reportError( + 'must be of type OptionalVersionedTextDocumentIdentifier'); return false; } } finally { @@ -21836,9 +30590,10 @@ class TextDocumentEdit implements ToJsonable { return false; } if (!((obj['edits'] is List && - (obj['edits'] - .every((item) => TextEdit.canParse(item, reporter)))))) { - reporter.reportError('must be of type List'); + (obj['edits'].every((item) => (TextEdit.canParse(item, reporter) || + AnnotatedTextEdit.canParse(item, reporter))))))) { + reporter.reportError( + 'must be of type List>'); return false; } } finally { @@ -21855,7 +30610,12 @@ class TextDocumentEdit implements ToJsonable { bool operator ==(Object other) { if (other is TextDocumentEdit && other.runtimeType == TextDocumentEdit) { return textDocument == other.textDocument && - listEqual(edits, other.edits, (TextEdit a, TextEdit b) => a == b) && + listEqual( + edits, + other.edits, + (Either2 a, + Either2 b) => + a == b) && true; } return false; @@ -21886,6 +30646,10 @@ class TextDocumentIdentifier implements ToJsonable { if (VersionedTextDocumentIdentifier.canParse(json, nullLspJsonReporter)) { return VersionedTextDocumentIdentifier.fromJson(json); } + if (OptionalVersionedTextDocumentIdentifier.canParse( + json, nullLspJsonReporter)) { + return OptionalVersionedTextDocumentIdentifier.fromJson(json); + } final uri = json['uri']; return TextDocumentIdentifier(uri: uri); } @@ -22153,6 +30917,15 @@ class TextDocumentPositionParams implements ToJsonable { if (PrepareRenameParams.canParse(json, nullLspJsonReporter)) { return PrepareRenameParams.fromJson(json); } + if (CallHierarchyPrepareParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyPrepareParams.fromJson(json); + } + if (LinkedEditingRangeParams.canParse(json, nullLspJsonReporter)) { + return LinkedEditingRangeParams.fromJson(json); + } + if (MonikerParams.canParse(json, nullLspJsonReporter)) { + return MonikerParams.fromJson(json); + } final textDocument = json['textDocument'] != null ? TextDocumentIdentifier.fromJson(json['textDocument']) : null; @@ -22323,6 +31096,19 @@ class TextDocumentRegistrationOptions implements ToJsonable { if (SelectionRangeRegistrationOptions.canParse(json, nullLspJsonReporter)) { return SelectionRangeRegistrationOptions.fromJson(json); } + if (CallHierarchyRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return CallHierarchyRegistrationOptions.fromJson(json); + } + if (SemanticTokensRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return SemanticTokensRegistrationOptions.fromJson(json); + } + if (LinkedEditingRangeRegistrationOptions.canParse( + json, nullLspJsonReporter)) { + return LinkedEditingRangeRegistrationOptions.fromJson(json); + } + if (MonikerRegistrationOptions.canParse(json, nullLspJsonReporter)) { + return MonikerRegistrationOptions.fromJson(json); + } final documentSelector = json['documentSelector'] ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null) ?.cast() @@ -22331,7 +31117,7 @@ class TextDocumentRegistrationOptions implements ToJsonable { } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; Map toJson() { @@ -22398,8 +31184,8 @@ class TextDocumentSaveReason { return obj is num; } - /// Manually triggered, for example, by the user pressing save, by starting - /// debugging, or by an API call. + /// Manually triggered, e.g. by the user pressing save, by starting debugging, + /// or by an API call. static const Manual = TextDocumentSaveReason(1); /// Automatic after a delay. @@ -22440,7 +31226,7 @@ class TextDocumentSaveRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The client is supposed to include the content on save. @@ -22711,25 +31497,25 @@ class TextDocumentSyncOptions implements ToJsonable { } /// Change notifications are sent to the server. See - /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full, and - /// TextDocumentSyncKind.Incremental. If omitted, it defaults to + /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full and + /// TextDocumentSyncKind.Incremental. If omitted it defaults to /// TextDocumentSyncKind.None. final TextDocumentSyncKind change; - /// Open and close notifications are sent to the server. If omitted, open - /// close notification should not be sent. + /// Open and close notifications are sent to the server. If omitted open close + /// notification should not be sent. final bool openClose; - /// If present save notifications are sent to the server. If omitted, the + /// If present save notifications are sent to the server. If omitted the /// notification should not be sent. final Either2 save; - /// If present will save notifications are sent to the server. If omitted, the + /// If present will save notifications are sent to the server. If omitted the /// notification should not be sent. final bool willSave; /// If present will save wait until requests are sent to the server. If - /// omitted, the request should not be sent. + /// omitted the request should not be sent. final bool willSaveWaitUntil; Map toJson() { @@ -22852,6 +31638,9 @@ class TextEdit implements ToJsonable { } } static TextEdit fromJson(Map json) { + if (AnnotatedTextEdit.canParse(json, nullLspJsonReporter)) { + return AnnotatedTextEdit.fromJson(json); + } final range = json['range'] != null ? Range.fromJson(json['range']) : null; final newText = json['newText']; return TextEdit(range: range, newText: newText); @@ -22936,6 +31725,29 @@ class TextEdit implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class TokenFormat { + const TokenFormat(this._value); + const TokenFormat.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + static const Relative = TokenFormat(r'relative'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is TokenFormat && o._value == _value; +} + class TypeDefinitionClientCapabilities implements ToJsonable { static const jsonHandler = LspJsonHandler( TypeDefinitionClientCapabilities.canParse, @@ -22951,7 +31763,7 @@ class TypeDefinitionClientCapabilities implements ToJsonable { } /// Whether implementation supports dynamic registration. If this is set to - /// `true`, the client supports the new ` TypeDefinitionRegistrationOptions` + /// `true` the client supports the new `TypeDefinitionRegistrationOptions` /// return value for the corresponding server capability as well. final bool dynamicRegistration; @@ -23131,8 +31943,8 @@ class TypeDefinitionParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// The position inside the text document. @@ -23277,7 +32089,7 @@ class TypeDefinitionRegistrationOptions } /// A document selector to identify the scope of the registration. If set to - /// null, the document selector provided on the client side will be used. + /// null the document selector provided on the client side will be used. final List documentSelector; /// The id used to register the request. The id can be used to deregister the @@ -23367,6 +32179,43 @@ class TypeDefinitionRegistrationOptions String toString() => jsonEncoder.convert(toJson()); } +/// Moniker uniqueness level to define scope of the moniker. +class UniquenessLevel { + const UniquenessLevel(this._value); + const UniquenessLevel.fromJson(this._value); + + final String _value; + + static bool canParse(Object obj, LspJsonReporter reporter) { + return obj is String; + } + + /// The moniker is only unique inside a document + static const document = UniquenessLevel(r'document'); + + /// The moniker is unique inside a project for which a dump got created + static const project = UniquenessLevel(r'project'); + + /// The moniker is unique inside the group to which a project belongs + static const group = UniquenessLevel(r'group'); + + /// The moniker is unique inside the moniker scheme. + static const scheme = UniquenessLevel(r'scheme'); + + /// The moniker is globally unique + static const global = UniquenessLevel(r'global'); + + Object toJson() => _value; + + @override + String toString() => _value.toString(); + + @override + int get hashCode => _value.hashCode; + + bool operator ==(Object o) => o is UniquenessLevel && o._value == _value; +} + /// General parameters to unregister a capability. class Unregistration implements ToJsonable { static const jsonHandler = @@ -23548,7 +32397,11 @@ class VersionedTextDocumentIdentifier VersionedTextDocumentIdentifier.canParse, VersionedTextDocumentIdentifier.fromJson); - VersionedTextDocumentIdentifier({this.version, @required this.uri}) { + VersionedTextDocumentIdentifier( + {@required this.version, @required this.uri}) { + if (version == null) { + throw 'version is required but was not provided'; + } if (uri == null) { throw 'uri is required but was not provided'; } @@ -23562,12 +32415,7 @@ class VersionedTextDocumentIdentifier /// The text document's URI. final String uri; - /// The version number of this document. If a versioned text document - /// identifier is sent from the server to the client and the file is not open - /// in the editor (the server has not received an open notification before), - /// the server can send `null` to indicate that the version is known and the - /// content on disk is the master (as specified with document content - /// ownership). + /// The version number of this document. /// /// The version number of a document will increase after each change, /// including undo/redo. The number doesn't need to be consecutive. @@ -23575,7 +32423,8 @@ class VersionedTextDocumentIdentifier Map toJson() { var __result = {}; - __result['version'] = version; + __result['version'] = + version ?? (throw 'version is required but was not set'); __result['uri'] = uri ?? (throw 'uri is required but was not set'); return __result; } @@ -23588,7 +32437,11 @@ class VersionedTextDocumentIdentifier reporter.reportError('must not be undefined'); return false; } - if (obj['version'] != null && !(obj['version'] is num)) { + if (obj['version'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!(obj['version'] is num)) { reporter.reportError('must be of type num'); return false; } @@ -23688,13 +32541,15 @@ class WillSaveTextDocumentParams implements ToJsonable { final textDocument = json['textDocument'] != null ? TextDocumentIdentifier.fromJson(json['textDocument']) : null; - final reason = json['reason']; + final reason = json['reason'] != null + ? TextDocumentSaveReason.fromJson(json['reason']) + : null; return WillSaveTextDocumentParams( textDocument: textDocument, reason: reason); } /// The 'TextDocumentSaveReason'. - final num reason; + final TextDocumentSaveReason reason; /// The document that will be saved. final TextDocumentIdentifier textDocument; @@ -23703,7 +32558,8 @@ class WillSaveTextDocumentParams implements ToJsonable { var __result = {}; __result['textDocument'] = textDocument?.toJson() ?? (throw 'textDocument is required but was not set'); - __result['reason'] = reason ?? (throw 'reason is required but was not set'); + __result['reason'] = + reason?.toJson() ?? (throw 'reason is required but was not set'); return __result; } @@ -23736,8 +32592,8 @@ class WillSaveTextDocumentParams implements ToJsonable { reporter.reportError('must not be null'); return false; } - if (!(obj['reason'] is num)) { - reporter.reportError('must be of type num'); + if (!(TextDocumentSaveReason.canParse(obj['reason'], reporter))) { + reporter.reportError('must be of type TextDocumentSaveReason'); return false; } } finally { @@ -23805,8 +32661,8 @@ class WorkDoneProgressBegin implements ToJsonable { } /// Controls if a cancel button should show to allow the user to cancel the - /// long running operation. Clients that don't support cancellation can ignore - /// the setting. + /// long running operation. Clients that don't support cancellation are + /// allowed to ignore the setting. final bool cancellable; final String kind; @@ -23822,7 +32678,7 @@ class WorkDoneProgressBegin implements ToJsonable { /// ignore the `percentage` value in subsequent in report notifications. /// /// The value should be steadily rising. Clients are free to ignore values - /// that are not following this rule. + /// that are not following this rule. The value range is [0, 100] final num percentage; /// Mandatory title of the progress operation. Used to briefly inform about @@ -24249,6 +33105,18 @@ class WorkDoneProgressOptions implements ToJsonable { if (SelectionRangeOptions.canParse(json, nullLspJsonReporter)) { return SelectionRangeOptions.fromJson(json); } + if (CallHierarchyOptions.canParse(json, nullLspJsonReporter)) { + return CallHierarchyOptions.fromJson(json); + } + if (SemanticTokensOptions.canParse(json, nullLspJsonReporter)) { + return SemanticTokensOptions.fromJson(json); + } + if (LinkedEditingRangeOptions.canParse(json, nullLspJsonReporter)) { + return LinkedEditingRangeOptions.fromJson(json); + } + if (MonikerOptions.canParse(json, nullLspJsonReporter)) { + return MonikerOptions.fromJson(json); + } final workDoneProgress = json['workDoneProgress']; return WorkDoneProgressOptions(workDoneProgress: workDoneProgress); } @@ -24377,6 +33245,30 @@ class WorkDoneProgressParams implements ToJsonable { if (SelectionRangeParams.canParse(json, nullLspJsonReporter)) { return SelectionRangeParams.fromJson(json); } + if (CallHierarchyPrepareParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyPrepareParams.fromJson(json); + } + if (CallHierarchyIncomingCallsParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyIncomingCallsParams.fromJson(json); + } + if (CallHierarchyOutgoingCallsParams.canParse(json, nullLspJsonReporter)) { + return CallHierarchyOutgoingCallsParams.fromJson(json); + } + if (SemanticTokensParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensParams.fromJson(json); + } + if (SemanticTokensDeltaParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensDeltaParams.fromJson(json); + } + if (SemanticTokensRangeParams.canParse(json, nullLspJsonReporter)) { + return SemanticTokensRangeParams.fromJson(json); + } + if (LinkedEditingRangeParams.canParse(json, nullLspJsonReporter)) { + return LinkedEditingRangeParams.fromJson(json); + } + if (MonikerParams.canParse(json, nullLspJsonReporter)) { + return MonikerParams.fromJson(json); + } final workDoneToken = json['workDoneToken'] is num ? Either2.t1(json['workDoneToken']) : (json['workDoneToken'] is String @@ -24460,11 +33352,11 @@ class WorkDoneProgressReport implements ToJsonable { percentage: percentage); } - /// Controls enablement state of a cancel button. T This property is only - /// valid if a cancel button is requested in the `WorkDoneProgressStart` - /// payload. + /// Controls enablement state of a cancel button. This property is only valid /// - /// Clients that don't support cancellation or don't support controlling the + /// if a cancel button got requested in the `WorkDoneProgressStart` payload. + /// + /// Clients that don't support cancellation or don't support control the /// button's enablement state are allowed to ignore the setting. final bool cancellable; final String kind; @@ -24481,7 +33373,7 @@ class WorkDoneProgressReport implements ToJsonable { /// ignore the `percentage` value in subsequent in report notifications. /// /// The value should be steadily rising. Clients are free to ignore values - /// that are not following this rule. + /// that are not following this rule. The value range is [0, 100] final num percentage; Map toJson() { @@ -24583,7 +33475,7 @@ class WorkspaceEdit implements ToJsonable { static const jsonHandler = LspJsonHandler(WorkspaceEdit.canParse, WorkspaceEdit.fromJson); - WorkspaceEdit({this.changes, this.documentChanges}); + WorkspaceEdit({this.changes, this.documentChanges, this.changeAnnotations}); static WorkspaceEdit fromJson(Map json) { final changes = json['changes'] ?.map((key, value) => MapEntry( @@ -24611,24 +33503,39 @@ class WorkspaceEdit implements ToJsonable { ?.cast>() ?.toList()) : (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List, List>)'''))); - return WorkspaceEdit(changes: changes, documentChanges: documentChanges); + final changeAnnotations = json['changeAnnotations'] + ?.map((key, value) => MapEntry( + key, value != null ? ChangeAnnotation.fromJson(value) : null)) + ?.cast(); + return WorkspaceEdit( + changes: changes, + documentChanges: documentChanges, + changeAnnotations: changeAnnotations); } + /// A map of change annotations that can be referenced in `AnnotatedTextEdit`s + /// or create, rename and delete file / folder operations. + /// + /// Whether clients honor this property depends on the client capability + /// `workspace.changeAnnotationSupport`. + /// @since 3.16.0 - proposed state + final Map changeAnnotations; + /// Holds changes to existing resources. final Map> changes; - /// The client capability `workspace.workspaceEdit.resourceOperations` - /// determines whether document changes are either an array of - /// `TextDocumentEdit`s to express changes to different text documents, where - /// each text document edit addresses a specific version of a text document, - /// or it can contains the above `TextDocumentEdit`s mixed with create, - /// rename, and delete file / folder operations. + /// Depending on the client capability + /// `workspace.workspaceEdit.resourceOperations` document changes are either + /// an array of `TextDocumentEdit`s to express changes to n different text + /// documents where each text document edit addresses a specific version of a + /// text document. Or it can contain above `TextDocumentEdit`s mixed with + /// create, rename and delete file / folder operations. /// /// Whether a client supports versioned document edits is expressed via /// `workspace.workspaceEdit.documentChanges` client capability. /// - /// If a client doesn't support `documentChanges` or - /// `workspace.workspaceEdit.resourceOperations`, then only plain `TextEdit`s + /// If a client neither supports `documentChanges` nor + /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s /// using the `changes` property are supported. final Either2, List>> @@ -24642,6 +33549,9 @@ class WorkspaceEdit implements ToJsonable { if (documentChanges != null) { __result['documentChanges'] = documentChanges; } + if (changeAnnotations != null) { + __result['changeAnnotations'] = changeAnnotations; + } return __result; } @@ -24681,6 +33591,20 @@ class WorkspaceEdit implements ToJsonable { } finally { reporter.pop(); } + reporter.push('changeAnnotations'); + try { + if (obj['changeAnnotations'] != null && + !((obj['changeAnnotations'] is Map && + (obj['changeAnnotations'].keys.every((item) => + item is String && + obj['changeAnnotations'].values.every((item) => + ChangeAnnotation.canParse(item, reporter))))))) { + reporter.reportError('must be of type Map'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type WorkspaceEdit'); @@ -24697,6 +33621,8 @@ class WorkspaceEdit implements ToJsonable { (List a, List b) => listEqual(a, b, (TextEdit a, TextEdit b) => a == b)) && documentChanges == other.documentChanges && + mapEqual(changeAnnotations, other.changeAnnotations, + (ChangeAnnotation a, ChangeAnnotation b) => a == b) && true; } return false; @@ -24707,6 +33633,7 @@ class WorkspaceEdit implements ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, lspHashCode(changes)); hash = JenkinsSmiHash.combine(hash, documentChanges.hashCode); + hash = JenkinsSmiHash.combine(hash, lspHashCode(changeAnnotations)); return JenkinsSmiHash.finish(hash); } @@ -24720,7 +33647,11 @@ class WorkspaceEditClientCapabilities implements ToJsonable { WorkspaceEditClientCapabilities.fromJson); WorkspaceEditClientCapabilities( - {this.documentChanges, this.resourceOperations, this.failureHandling}); + {this.documentChanges, + this.resourceOperations, + this.failureHandling, + this.normalizesLineEndings, + this.changeAnnotationSupport}); static WorkspaceEditClientCapabilities fromJson(Map json) { final documentChanges = json['documentChanges']; final resourceOperations = json['resourceOperations'] @@ -24731,12 +33662,25 @@ class WorkspaceEditClientCapabilities implements ToJsonable { final failureHandling = json['failureHandling'] != null ? FailureHandlingKind.fromJson(json['failureHandling']) : null; + final normalizesLineEndings = json['normalizesLineEndings']; + final changeAnnotationSupport = json['changeAnnotationSupport'] != null + ? WorkspaceEditClientCapabilitiesChangeAnnotationSupport.fromJson( + json['changeAnnotationSupport']) + : null; return WorkspaceEditClientCapabilities( documentChanges: documentChanges, resourceOperations: resourceOperations, - failureHandling: failureHandling); + failureHandling: failureHandling, + normalizesLineEndings: normalizesLineEndings, + changeAnnotationSupport: changeAnnotationSupport); } + /// Whether the client in general supports change annotations on text edits, + /// create file, rename file and delete file changes. + /// @since 3.16.0 - proposed state + final WorkspaceEditClientCapabilitiesChangeAnnotationSupport + changeAnnotationSupport; + /// The client supports versioned document changes in `WorkspaceEdit`s final bool documentChanges; @@ -24745,6 +33689,12 @@ class WorkspaceEditClientCapabilities implements ToJsonable { /// @since 3.13.0 final FailureHandlingKind failureHandling; + /// Whether the client normalizes line endings to the client specific setting. + /// If set to `true` the client will normalize line ending characters in a + /// workspace edit to the client specific new line character(s). + /// @since 3.16.0 - proposed state + final bool normalizesLineEndings; + /// The resource operations the client supports. Clients should at least /// support 'create', 'rename' and 'delete' files and folders. /// @since 3.13.0 @@ -24761,6 +33711,12 @@ class WorkspaceEditClientCapabilities implements ToJsonable { if (failureHandling != null) { __result['failureHandling'] = failureHandling.toJson(); } + if (normalizesLineEndings != null) { + __result['normalizesLineEndings'] = normalizesLineEndings; + } + if (changeAnnotationSupport != null) { + __result['changeAnnotationSupport'] = changeAnnotationSupport.toJson(); + } return __result; } @@ -24798,6 +33754,28 @@ class WorkspaceEditClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('normalizesLineEndings'); + try { + if (obj['normalizesLineEndings'] != null && + !(obj['normalizesLineEndings'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + reporter.push('changeAnnotationSupport'); + try { + if (obj['changeAnnotationSupport'] != null && + !(WorkspaceEditClientCapabilitiesChangeAnnotationSupport.canParse( + obj['changeAnnotationSupport'], reporter))) { + reporter.reportError( + 'must be of type WorkspaceEditClientCapabilitiesChangeAnnotationSupport'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type WorkspaceEditClientCapabilities'); @@ -24813,6 +33791,8 @@ class WorkspaceEditClientCapabilities implements ToJsonable { listEqual(resourceOperations, other.resourceOperations, (ResourceOperationKind a, ResourceOperationKind b) => a == b) && failureHandling == other.failureHandling && + normalizesLineEndings == other.normalizesLineEndings && + changeAnnotationSupport == other.changeAnnotationSupport && true; } return false; @@ -24824,6 +33804,75 @@ class WorkspaceEditClientCapabilities implements ToJsonable { hash = JenkinsSmiHash.combine(hash, documentChanges.hashCode); hash = JenkinsSmiHash.combine(hash, lspHashCode(resourceOperations)); hash = JenkinsSmiHash.combine(hash, failureHandling.hashCode); + hash = JenkinsSmiHash.combine(hash, normalizesLineEndings.hashCode); + hash = JenkinsSmiHash.combine(hash, changeAnnotationSupport.hashCode); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + +class WorkspaceEditClientCapabilitiesChangeAnnotationSupport + implements ToJsonable { + static const jsonHandler = LspJsonHandler( + WorkspaceEditClientCapabilitiesChangeAnnotationSupport.canParse, + WorkspaceEditClientCapabilitiesChangeAnnotationSupport.fromJson); + + WorkspaceEditClientCapabilitiesChangeAnnotationSupport({this.groupsOnLabel}); + static WorkspaceEditClientCapabilitiesChangeAnnotationSupport fromJson( + Map json) { + final groupsOnLabel = json['groupsOnLabel']; + return WorkspaceEditClientCapabilitiesChangeAnnotationSupport( + groupsOnLabel: groupsOnLabel); + } + + /// Whether the client groups edits with equal labels into tree nodes, for + /// instance all edits labelled with "Changes in Strings" would be a tree + /// node. + final bool groupsOnLabel; + + Map toJson() { + var __result = {}; + if (groupsOnLabel != null) { + __result['groupsOnLabel'] = groupsOnLabel; + } + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('groupsOnLabel'); + try { + if (obj['groupsOnLabel'] != null && !(obj['groupsOnLabel'] is bool)) { + reporter.reportError('must be of type bool'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type WorkspaceEditClientCapabilitiesChangeAnnotationSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is WorkspaceEditClientCapabilitiesChangeAnnotationSupport && + other.runtimeType == + WorkspaceEditClientCapabilitiesChangeAnnotationSupport) { + return groupsOnLabel == other.groupsOnLabel && true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, groupsOnLabel.hashCode); return JenkinsSmiHash.finish(hash); } @@ -25140,15 +34189,21 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { WorkspaceSymbolClientCapabilities.fromJson); WorkspaceSymbolClientCapabilities( - {this.dynamicRegistration, this.symbolKind}); + {this.dynamicRegistration, this.symbolKind, this.tagSupport}); static WorkspaceSymbolClientCapabilities fromJson(Map json) { final dynamicRegistration = json['dynamicRegistration']; final symbolKind = json['symbolKind'] != null ? WorkspaceSymbolClientCapabilitiesSymbolKind.fromJson( json['symbolKind']) : null; + final tagSupport = json['tagSupport'] != null + ? WorkspaceSymbolClientCapabilitiesTagSupport.fromJson( + json['tagSupport']) + : null; return WorkspaceSymbolClientCapabilities( - dynamicRegistration: dynamicRegistration, symbolKind: symbolKind); + dynamicRegistration: dynamicRegistration, + symbolKind: symbolKind, + tagSupport: tagSupport); } /// Symbol request supports dynamic registration. @@ -25158,6 +34213,11 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { /// request. final WorkspaceSymbolClientCapabilitiesSymbolKind symbolKind; + /// The client supports tags on `SymbolInformation`. Clients supporting tags + /// have to handle unknown tags gracefully. + /// @since 3.16.0 + final WorkspaceSymbolClientCapabilitiesTagSupport tagSupport; + Map toJson() { var __result = {}; if (dynamicRegistration != null) { @@ -25166,6 +34226,9 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { if (symbolKind != null) { __result['symbolKind'] = symbolKind.toJson(); } + if (tagSupport != null) { + __result['tagSupport'] = tagSupport.toJson(); + } return __result; } @@ -25193,6 +34256,18 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { } finally { reporter.pop(); } + reporter.push('tagSupport'); + try { + if (obj['tagSupport'] != null && + !(WorkspaceSymbolClientCapabilitiesTagSupport.canParse( + obj['tagSupport'], reporter))) { + reporter.reportError( + 'must be of type WorkspaceSymbolClientCapabilitiesTagSupport'); + return false; + } + } finally { + reporter.pop(); + } return true; } else { reporter.reportError('must be of type WorkspaceSymbolClientCapabilities'); @@ -25206,6 +34281,7 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { other.runtimeType == WorkspaceSymbolClientCapabilities) { return dynamicRegistration == other.dynamicRegistration && symbolKind == other.symbolKind && + tagSupport == other.tagSupport && true; } return false; @@ -25216,6 +34292,7 @@ class WorkspaceSymbolClientCapabilities implements ToJsonable { var hash = 0; hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode); hash = JenkinsSmiHash.combine(hash, symbolKind.hashCode); + hash = JenkinsSmiHash.combine(hash, tagSupport.hashCode); return JenkinsSmiHash.finish(hash); } @@ -25298,6 +34375,86 @@ class WorkspaceSymbolClientCapabilitiesSymbolKind implements ToJsonable { String toString() => jsonEncoder.convert(toJson()); } +class WorkspaceSymbolClientCapabilitiesTagSupport implements ToJsonable { + static const jsonHandler = LspJsonHandler( + WorkspaceSymbolClientCapabilitiesTagSupport.canParse, + WorkspaceSymbolClientCapabilitiesTagSupport.fromJson); + + WorkspaceSymbolClientCapabilitiesTagSupport({@required this.valueSet}) { + if (valueSet == null) { + throw 'valueSet is required but was not provided'; + } + } + static WorkspaceSymbolClientCapabilitiesTagSupport fromJson( + Map json) { + final valueSet = json['valueSet'] + ?.map((item) => item != null ? SymbolTag.fromJson(item) : null) + ?.cast() + ?.toList(); + return WorkspaceSymbolClientCapabilitiesTagSupport(valueSet: valueSet); + } + + /// The tags supported by the client. + final List valueSet; + + Map toJson() { + var __result = {}; + __result['valueSet'] = + valueSet ?? (throw 'valueSet is required but was not set'); + return __result; + } + + static bool canParse(Object obj, LspJsonReporter reporter) { + if (obj is Map) { + reporter.push('valueSet'); + try { + if (!obj.containsKey('valueSet')) { + reporter.reportError('must not be undefined'); + return false; + } + if (obj['valueSet'] == null) { + reporter.reportError('must not be null'); + return false; + } + if (!((obj['valueSet'] is List && + (obj['valueSet'] + .every((item) => SymbolTag.canParse(item, reporter)))))) { + reporter.reportError('must be of type List'); + return false; + } + } finally { + reporter.pop(); + } + return true; + } else { + reporter.reportError( + 'must be of type WorkspaceSymbolClientCapabilitiesTagSupport'); + return false; + } + } + + @override + bool operator ==(Object other) { + if (other is WorkspaceSymbolClientCapabilitiesTagSupport && + other.runtimeType == WorkspaceSymbolClientCapabilitiesTagSupport) { + return listEqual( + valueSet, other.valueSet, (SymbolTag a, SymbolTag b) => a == b) && + true; + } + return false; + } + + @override + int get hashCode { + var hash = 0; + hash = JenkinsSmiHash.combine(hash, lspHashCode(valueSet)); + return JenkinsSmiHash.finish(hash); + } + + @override + String toString() => jsonEncoder.convert(toJson()); +} + class WorkspaceSymbolOptions implements WorkDoneProgressOptions, ToJsonable { static const jsonHandler = LspJsonHandler( WorkspaceSymbolOptions.canParse, WorkspaceSymbolOptions.fromJson); @@ -25395,8 +34552,8 @@ class WorkspaceSymbolParams partialResultToken: partialResultToken); } - /// An optional token that a server can use to report partial results (for - /// example, streaming) to the client. + /// An optional token that a server can use to report partial results (e.g. + /// streaming) to the client. final Either2 partialResultToken; /// A query string to filter symbols by. Clients may send an empty string here diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart index c58b195a12d..6fea377a259 100644 --- a/pkg/analysis_server/lib/src/lsp/constants.dart +++ b/pkg/analysis_server/lib/src/lsp/constants.dart @@ -78,17 +78,18 @@ abstract class Commands { } abstract class CustomMethods { - static const DiagnosticServer = Method('dart/diagnosticServer'); - static const Reanalyze = Method('dart/reanalyze'); - static const PublishClosingLabels = + static const diagnosticServer = Method('dart/diagnosticServer'); + static const reanalyze = Method('dart/reanalyze'); + static const publishClosingLabels = Method('dart/textDocument/publishClosingLabels'); - static const PublishOutline = Method('dart/textDocument/publishOutline'); - static const PublishFlutterOutline = + static const publishOutline = Method('dart/textDocument/publishOutline'); + static const publishFlutterOutline = Method('dart/textDocument/publishFlutterOutline'); - static const Super = Method('dart/textDocument/super'); + static const super_ = Method('dart/textDocument/super'); + // TODO(dantup): Remove custom AnalyzerStatus status method soon as no clients // should be relying on it and we now support proper $/progress events. - static const AnalyzerStatus = Method(r'$/analyzerStatus'); + static const analyzerStatus = Method(r'$/analyzerStatus'); } /// CodeActionKinds supported by the server that are not declared in the LSP spec. diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart index 559c54e08e5..8a5727a7292 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart @@ -28,7 +28,7 @@ abstract class SimpleEditCommandHandler } Future> sendSourceEditsToClient( - VersionedTextDocumentIdentifier docIdentifier, + OptionalVersionedTextDocumentIdentifier docIdentifier, CompilationUnit unit, List edits) async { // If there are no edits to apply, just complete the command without going diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart index 9e3373a6c31..66f95f638e7 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart @@ -13,7 +13,7 @@ class DiagnosticServerHandler extends MessageHandler { DiagnosticServerHandler(LspAnalysisServer server) : super(server); @override - Method get handlesMessage => CustomMethods.DiagnosticServer; + Method get handlesMessage => CustomMethods.diagnosticServer; @override LspJsonHandler get jsonHandler => NullJsonHandler; diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart index 68a04e9ba6d..0c2cde4d97b 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart @@ -11,7 +11,7 @@ import 'package:analysis_server/src/lsp/lsp_analysis_server.dart'; class ReanalyzeHandler extends MessageHandler { ReanalyzeHandler(LspAnalysisServer server) : super(server); @override - Method get handlesMessage => CustomMethods.Reanalyze; + Method get handlesMessage => CustomMethods.reanalyze; @override LspJsonHandler get jsonHandler => NullJsonHandler; diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart index b33967fd777..9ddba98a608 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart @@ -14,7 +14,7 @@ class SuperHandler extends MessageHandler { SuperHandler(LspAnalysisServer server) : super(server); @override - Method get handlesMessage => CustomMethods.Super; + Method get handlesMessage => CustomMethods.super_; @override LspJsonHandler get jsonHandler => diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart index 71205a04950..eae5c8c2663 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart @@ -87,6 +87,7 @@ class RenameHandler extends MessageHandler { } final pos = params.position; + final textDocument = params.textDocument; final path = pathOfDoc(params.textDocument); // If the client provided us a version doc identifier, we'll use it to ensure // we're not computing a rename for an old document. If not, we'll just assume @@ -94,9 +95,12 @@ class RenameHandler extends MessageHandler { // and then use it to verify the document hadn't changed again before we // send the edits. final docIdentifier = await path.mapResult((path) => success( - params.textDocument is VersionedTextDocumentIdentifier - ? params.textDocument as VersionedTextDocumentIdentifier - : server.getVersionedDocumentIdentifier(path))); + textDocument is OptionalVersionedTextDocumentIdentifier + ? textDocument + : textDocument is VersionedTextDocumentIdentifier + ? OptionalVersionedTextDocumentIdentifier( + uri: textDocument.uri, version: textDocument.version) + : server.getVersionedDocumentIdentifier(path))); final unit = await path.mapResult(requireResolvedUnit); final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos)); diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart index 152ba37e8f7..fccc0ebf7fa 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart @@ -118,7 +118,7 @@ class TextDocumentOpenHandler final doc = params.textDocument; final path = pathOfDocItem(doc); return path.mapResult((path) { - // We don't get a VersionedTextDocumentIdentifier with a didOpen but we + // We don't get a OptionalVersionedTextDocumentIdentifier with a didOpen but we // do get the necessary info to create one. server.documentVersions[path] = VersionedTextDocumentIdentifier( version: params.textDocument.version, diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart index 3c67aab5349..bc6f7b7b347 100644 --- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart +++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart @@ -248,11 +248,13 @@ class LspAnalysisServer extends AbstractAnalysisServer { } /// Gets the version of a document known to the server, returning a - /// [VersionedTextDocumentIdentifier] with a version of `null` if the document + /// [OptionalVersionedTextDocumentIdentifier] with a version of `null` if the document /// version is not known. - VersionedTextDocumentIdentifier getVersionedDocumentIdentifier(String path) { - return documentVersions[path] ?? - VersionedTextDocumentIdentifier(uri: Uri.file(path).toString()); + OptionalVersionedTextDocumentIdentifier getVersionedDocumentIdentifier( + String path) { + return OptionalVersionedTextDocumentIdentifier( + uri: Uri.file(path).toString(), + version: documentVersions[path]?.version); } void handleClientConnection( @@ -424,7 +426,7 @@ class LspAnalysisServer extends AbstractAnalysisServer { final params = PublishClosingLabelsParams( uri: Uri.file(path).toString(), labels: labels); final message = NotificationMessage( - method: CustomMethods.PublishClosingLabels, + method: CustomMethods.publishClosingLabels, params: params, jsonrpc: jsonRpcVersion, ); @@ -446,7 +448,7 @@ class LspAnalysisServer extends AbstractAnalysisServer { final params = PublishFlutterOutlineParams( uri: Uri.file(path).toString(), outline: outline); final message = NotificationMessage( - method: CustomMethods.PublishFlutterOutline, + method: CustomMethods.publishFlutterOutline, params: params, jsonrpc: jsonRpcVersion, ); @@ -457,7 +459,7 @@ class LspAnalysisServer extends AbstractAnalysisServer { final params = PublishOutlineParams(uri: Uri.file(path).toString(), outline: outline); final message = NotificationMessage( - method: CustomMethods.PublishOutline, + method: CustomMethods.publishOutline, params: params, jsonrpc: jsonRpcVersion, ); @@ -552,7 +554,7 @@ class LspAnalysisServer extends AbstractAnalysisServer { // it's unlikely to be in use by any clients. if (clientCapabilities.window?.workDoneProgress != true) { channel.sendNotification(NotificationMessage( - method: CustomMethods.AnalyzerStatus, + method: CustomMethods.analyzerStatus, params: AnalyzerStatusParams(isAnalyzing: status.isAnalyzing), jsonrpc: jsonRpcVersion, )); diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart index 6f0cd7b1769..e9b77bfb342 100644 --- a/pkg/analysis_server/lib/src/lsp/mapping.dart +++ b/pkg/analysis_server/lib/src/lsp/mapping.dart @@ -1211,7 +1211,10 @@ lsp.SignatureHelp toSignatureHelp(List preferredFormats, lsp.TextDocumentEdit toTextDocumentEdit(FileEditInformation edit) { return lsp.TextDocumentEdit( textDocument: edit.doc, - edits: edit.edits.map((e) => toTextEdit(edit.lineInfo, e)).toList(), + edits: edit.edits + .map((e) => Either2.t1( + toTextEdit(edit.lineInfo, e))) + .toList(), ); } diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart index b621c694f82..81005d6cd56 100644 --- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart +++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart @@ -13,7 +13,7 @@ class ClientDynamicRegistrations { /// All dynamic registrations supported by the Dart LSP server. /// /// Anything listed here and supported by the client will not send a static - /// registration but intead dynamically register (usually only for a subset of + /// registration but instead dynamically register (usually only for a subset of /// files such as for .dart/pubspec.yaml/etc). /// /// When adding new capabilities that will be registered dynamically, the @@ -124,7 +124,8 @@ class ServerCapabilitiesComputer { return ServerCapabilities( textDocumentSync: dynamicRegistrations.textSync ? null - : Either2.t1(TextDocumentSyncOptions( + : Either2.t1( + TextDocumentSyncOptions( // The open/close and sync kind flags are registered dynamically if the // client supports them, so these static registrations are based on whether // the client supports dynamic registration. diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart index b98a101b387..03074177115 100644 --- a/pkg/analysis_server/lib/src/lsp/source_edits.dart +++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart @@ -302,7 +302,7 @@ Token _parse(String s, FeatureSet featureSet) { /// Helper class that bundles up all information required when converting server /// SourceEdits into LSP-compatible WorkspaceEdits. class FileEditInformation { - final VersionedTextDocumentIdentifier doc; + final OptionalVersionedTextDocumentIdentifier doc; final LineInfo lineInfo; final List edits; diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart index 50bcc589e86..613ad4a6b63 100644 --- a/pkg/analysis_server/test/lsp/initialization_test.dart +++ b/pkg/analysis_server/test/lsp/initialization_test.dart @@ -44,7 +44,7 @@ class InitializationTest extends AbstractLspAnalysisServerTest { emptyTextDocumentClientCapabilities))), ); - // Because we support dynamic registration for synchronisation, we won't send + // Because we support dynamic registration for synchronization, we won't send // static registrations for them. // https://github.com/dart-lang/sdk/issues/38490 final initResult = InitializeResult.fromJson(initResponse.result); @@ -53,7 +53,7 @@ class InitializationTest extends AbstractLspAnalysisServerTest { expect(initResult.capabilities, isNotNull); expect(initResult.capabilities.textDocumentSync, isNull); - // Should container Hover, DidOpen, DidClose, DidChange. + // Should contain Hover, DidOpen, DidClose, DidChange. expect(registrations, hasLength(4)); final hover = registrationOptionsFor(registrations, Method.textDocument_hover); diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart index f99877eea9c..2c4f8abcfc1 100644 --- a/pkg/analysis_server/test/lsp/server_abstract.dart +++ b/pkg/analysis_server/test/lsp/server_abstract.dart @@ -565,13 +565,16 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { }); } - String applyTextEdit(String content, TextEdit change) { - final startPos = change.range.start; - final endPos = change.range.end; + String applyTextEdit( + String content, Either2 change) { + // Both sites of the union can cast to TextEdit. + final edit = change.map((e) => e, (e) => e); + final startPos = edit.range.start; + final endPos = edit.range.end; final lineInfo = LineInfo.fromContent(content); final start = lineInfo.getOffsetOfLine(startPos.line) + startPos.character; final end = lineInfo.getOffsetOfLine(endPos.line) + endPos.character; - return content.replaceRange(start, end, change.newText); + return content.replaceRange(start, end, edit.newText); } String applyTextEdits(String oldContent, List changes) { @@ -626,7 +629,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { ); for (final change in sortedChanges) { - newContent = applyTextEdit(newContent, change); + newContent = applyTextEdit( + newContent, Either2.t1(change)); } return newContent; @@ -702,7 +706,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { final path = Uri.parse(edit.textDocument.uri).toFilePath(); final expectedVersion = expectedVersions[path]; - if (edit.textDocument is VersionedTextDocumentIdentifier) { + if (edit.textDocument is OptionalVersionedTextDocumentIdentifier) { expect(edit.textDocument.version, equals(expectedVersion)); } else { throw 'Document identifier for $path was not versioned (expected version $expectedVersion)'; @@ -901,7 +905,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { Future getDiagnosticServer() { final request = makeRequest( - CustomMethods.DiagnosticServer, + CustomMethods.diagnosticServer, null, ); return expectSuccessfulResponseTo(request, DartDiagnosticServer.fromJson); @@ -1009,7 +1013,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { Position pos, ) { final request = makeRequest( - CustomMethods.Super, + CustomMethods.super_, TextDocumentPositionParams( textDocument: TextDocumentIdentifier(uri: uri.toString()), position: pos, @@ -1428,10 +1432,10 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { Future waitForAnalysisStatus(bool analyzing) async { await serverToClient.firstWhere((message) { if (message is NotificationMessage) { - if (message.method == CustomMethods.AnalyzerStatus) { + if (message.method == CustomMethods.analyzerStatus) { if (_clientCapabilities.window?.workDoneProgress == true) { throw Exception( - 'Recieved ${CustomMethods.AnalyzerStatus} notification ' + 'Recieved ${CustomMethods.analyzerStatus} notification ' 'but client supports workDoneProgress'); } @@ -1440,7 +1444,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { } else if (message.method == Method.progress) { if (_clientCapabilities.window?.workDoneProgress != true) { throw Exception( - 'Recieved ${CustomMethods.AnalyzerStatus} notification ' + 'Recieved ${CustomMethods.analyzerStatus} notification ' 'but client supports workDoneProgress'); } @@ -1473,7 +1477,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { PublishClosingLabelsParams closingLabelsParams; await serverToClient.firstWhere((message) { if (message is NotificationMessage && - message.method == CustomMethods.PublishClosingLabels) { + message.method == CustomMethods.publishClosingLabels) { closingLabelsParams = PublishClosingLabelsParams.fromJson(message.params); @@ -1501,7 +1505,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { PublishFlutterOutlineParams outlineParams; await serverToClient.firstWhere((message) { if (message is NotificationMessage && - message.method == CustomMethods.PublishFlutterOutline) { + message.method == CustomMethods.publishFlutterOutline) { outlineParams = PublishFlutterOutlineParams.fromJson(message.params); return outlineParams.uri == uri.toString(); @@ -1515,7 +1519,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin { PublishOutlineParams outlineParams; await serverToClient.firstWhere((message) { if (message is NotificationMessage && - message.method == CustomMethods.PublishOutline) { + message.method == CustomMethods.publishOutline) { outlineParams = PublishOutlineParams.fromJson(message.params); return outlineParams.uri == uri.toString(); diff --git a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart index 1334077ebdd..915c417bdaa 100644 --- a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart +++ b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart @@ -167,7 +167,7 @@ void main() { // Value whether expected to parse const testTraceValues = { 'off': true, - 'messages': true, + 'message': true, 'verbose': true, null: true, 'invalid': false, diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart index a265eb52b82..ff160b1a668 100644 --- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart +++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart @@ -68,7 +68,7 @@ final Uri specLicenseUri = Uri.parse( /// The URI of the version of the spec to generate from. This should be periodically updated as /// there's no longer a stable URI for the latest published version. final Uri specUri = Uri.parse( - 'https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/specification-3-15.md'); + 'https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/specification-3-16.md'); /// Pattern to extract inline types from the `result: {xx, yy }` notes in the spec. /// Doesn't parse past full stops as some of these have english sentences tagged on diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md index 14ab9bc29ed..cd6473cb974 100644 --- a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md +++ b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md @@ -1,5 +1,5 @@ This is an unmodified copy of the Language Server Protocol Specification, -downloaded from https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/specification-3-15.md. It is the version of the specification that was +downloaded from https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/specification-3-16.md. It is the version of the specification that was used to generate a portion of the Dart code used to support the protocol. To regenerate the generated code, run the script in @@ -22,24 +22,30 @@ Distributed under the following terms: --- title: Specification -shortTitle: 3.15 - Current +shortTitle: 3.16 - Upcoming layout: specifications -sectionid: specification-3-15 -toc: specification-3-15-toc +sectionid: specification-3-16 +toc: specification-3-16-toc index: 2 --- -# Language Server Protocol Specification - 3.15 +# Language Server Protocol Specification - 3.16 -This document describes the 3.15.x version of the language server protocol. An implementation for node of the 3.15.x version of the protocol can be found [here](https://github.com/Microsoft/vscode-languageserver-node). +This document describes the upcoming 3.16.x version of the language server protocol. An implementation for node of the 3.16.x version of the protocol can be found [here](https://github.com/Microsoft/vscode-languageserver-node). -**Note:** edits to this specification can be made via a pull request against this Markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-15.md). +**Note:** edits to this specification can be made via a pull request against this markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md). -## What's new in 3.15 +## What's new in 3.16 -All new 3.15 features are tagged with a corresponding since version 3.15 text or in JSDoc using `@since 3.15.0` annotation. Major new features are: +All new 3.16 features are tagged with a corresponding since version 3.16 text or in JSDoc using `@since 3.16.0` annotation. Major new feature are: -- [general progress support](#progress), [work done progress](#workDoneProgress) and [partial result progress](#partialResults) -- support for [selection ranges](#textDocument_selectionRange) +- Call Hierarchy support +- Semantic Token support +- Better trace logging support +- Moniker support +- Code Action disabled support +- Code Action resolve support + +The version of the specification is used to group features into a new specification release and to refer to their first appearance. Features in the spec are kept compatible using so called capability flags which are exchanged between the client and the server during initialization. ## Base Protocol @@ -84,6 +90,35 @@ Content-Length: ...\r\n The following TypeScript definitions describe the base [JSON-RPC protocol](http://www.jsonrpc.org/specification): +#### Numbers + +The protocol use the following definitions for integers, unsigned integers and decimal numbers: + +```typescript +/** + * Defines an integer number in the range of -2^31 to 2^31 - 1. + */ +export type integer = number; +``` + +```typescript +/** + * Defines an unsigned integer number in the range of 0 to 2^31 - 1. + */ +export type uinteger = number; +``` + +```typescript +/** + * Defines a decimal number. Since decimal numbers are very + * rare in the language server specification we denote the + * exact range with every decimal using the mathematics + * interval notation (e.g. [0, 1] denotes all decimals d with + * 0 <= d <= 1. + */ +export type decimal = number; +``` + #### Abstract Message A general message as defined by JSON-RPC. The language server protocol always uses "2.0" as the `jsonrpc` version. @@ -103,7 +138,7 @@ interface RequestMessage extends Message { /** * The request id. */ - id: number | string; + id: integer | string; /** * The method to be invoked. @@ -126,7 +161,7 @@ interface ResponseMessage extends Message { /** * The request id. */ - id: number | string | null; + id: integer | string | null; /** * The result of a request. This member is REQUIRED on success. @@ -144,7 +179,7 @@ interface ResponseError { /** * A number indicating the error type that occurred. */ - code: number; + code: integer; /** * A string providing a short description of the error. @@ -160,19 +195,54 @@ interface ResponseError { export namespace ErrorCodes { // Defined by JSON RPC - export const ParseError: number = -32700; - export const InvalidRequest: number = -32600; - export const MethodNotFound: number = -32601; - export const InvalidParams: number = -32602; - export const InternalError: number = -32603; - export const serverErrorStart: number = -32099; - export const serverErrorEnd: number = -32000; - export const ServerNotInitialized: number = -32002; - export const UnknownErrorCode: number = -32001; + export const ParseError: integer = -32700; + export const InvalidRequest: integer = -32600; + export const MethodNotFound: integer = -32601; + export const InvalidParams: integer = -32602; + export const InternalError: integer = -32603; - // Defined by the protocol. - export const RequestCancelled: number = -32800; - export const ContentModified: number = -32801; + /** + * This is the start range of JSON RPC reserved error codes. + * It doesn't denote a real error code. No LSP error codes should + * be defined between the start and end range. For backwards + * compatibility the `ServerNotInitialized` and the `UnknownErrorCode` + * are left in the range. + * + * @since 3.16.0 + */ + export const jsonrpcReservedErrorRangeStart: integer = -32099; + /** @deprecated use jsonrpcReservedErrorRangeStart */ + export const serverErrorStart: integer = jsonrpcReservedErrorRangeStart; + + export const ServerNotInitialized: integer = -32002; + export const UnknownErrorCode: integer = -32001; + + /** + * This is the start range of JSON RPC reserved error codes. + * It doesn't denote a real error code. + */ + export const jsonrpcReservedErrorRangeEnd = -32000; + /** @deprecated use jsonrpcReservedErrorRangeEnd */ + export const serverErrorEnd: integer = jsonrpcReservedErrorRangeEnd; + + /** + * This is the start range of LSP reserved error codes. + * It doesn't denote a real error code. + * + * @since 3.16.0 + */ + export const lspReservedErrorRangeStart: integer = -32899; + + export const ContentModified: integer = -32801; + export const RequestCancelled: integer = -32800; + + /** + * This is the end range of LSP reserved error codes. + * It doesn't denote a real error code. + * + * @since 3.16.0 + */ + export const lspReservedErrorRangeEnd: integer = -32800; } ``` #### Notification Message @@ -195,7 +265,7 @@ interface NotificationMessage extends Message { #### $ Notifications and Requests -Notification and requests whose methods start with '$/' are messages which are protocol implementation dependent and might not be implementable in all clients or servers. For example if the server implementation uses a single threaded synchronous programming language then there is little a server can do to react to a '$/cancelRequest' notification. If a server or client receives notifications starting with '$/' it is free to ignore the notification. If a server or client receives a requests starting with '$/' it must error the request with error code `MethodNotFound` (e.g. `-32601`). +Notification and requests whose methods start with '\$/' are messages which are protocol implementation dependent and might not be implementable in all clients or servers. For example if the server implementation uses a single threaded synchronous programming language then there is little a server can do to react to a `$/cancelRequest` notification. If a server or client receives notifications starting with '\$/' it is free to ignore the notification. If a server or client receives a requests starting with '\$/' it must error the request with error code `MethodNotFound` (e.g. `-32601`). #### Cancellation Support (:arrow_right: :arrow_left:) @@ -210,7 +280,7 @@ interface CancelParams { /** * The request id to cancel. */ - id: number | string; + id: integer | string; } ``` @@ -229,7 +299,8 @@ _Notification_: * params: `ProgressParams` defined as follows: ```typescript -type ProgressToken = number | string; +type ProgressToken = integer | string; + interface ProgressParams { /** * The progress token provided by the client or server. @@ -259,6 +330,10 @@ The protocol currently assumes that one server serves one tool. There is current URI's are transferred as strings. The URI's format is defined in [http://tools.ietf.org/html/rfc3986](http://tools.ietf.org/html/rfc3986) +```typescript +type URI = string; +``` + ``` foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ @@ -277,6 +352,54 @@ Many of the interfaces contain fields that correspond to the URI of a document. type DocumentUri = string; ``` +#### Regular Expressions + +Regular expression are a powerful tool and there are actual use cases for them in the language server protocol. However the downside with them is that almost every programming language has its own set of regular expression features so the specification can not simply refer to them as a regular expression. So the LSP uses a two step approach to support regular expressions: + +* the client will announce which regular expression engine it will use. This will allow server that are written for a very specific client make full use of the regular expression capabilities of the client +* the specification will define a set of regular expression features that should be supported by a client. Instead of writing a new specification LSP will refer to the [ECMAScript Regular Expression specification](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) and remove features from it that are not necessary in the context of LSP or hard to implement for other clients. + +_Client Capability_: + +The following client capability is used to announce a client's regular expression engine + +* property path (optional): `general.regularExpressions` +* property type: `RegularExpressionsClientCapabilities` defined as follows: + +```typescript +/** + * Client capabilities specific to regular expressions. + */ +export interface RegularExpressionsClientCapabilities { + /** + * The engine's name. + */ + engine: string; + + /** + * The engine's version. + */ + version?: string; +} +``` + +The following table lists the well known engine values. Please note that the table should be driven by the community which integrates LSP into existing clients. It is not the goal of the spec to list all available regular expression engines. + +Engine | Version | Documentation +------- | ------- | ------------- +ECMAScript | `ES2020` | [ECMAScript 2020](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) & [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) + +_Regular Expression Subset_: + +The following features from the [ECMAScript 2020](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) regular expression specification are NOT mandatory for a client: + +- *Assertions*: Lookahead assertion, Negative lookahead assertion, lookbehind assertion, negative lookbehind assertion. +- *Character classes*: matching control characters using caret notation (e.g. `\cX`) and matching UTF-16 code units (e.g. `\uhhhh`). +- *Group and ranges*: named capturing groups. +- *Unicode property escapes*: none of the features needs to be supported. + +The only regular expression flag that a client needs to support is 'i' to specify a case insensitive search. + #### Text Documents The current protocol is tailored for textual documents whose content can be represented as a string. There is currently no support for binary documents. A position inside a document (see Position definition below) is expressed as a zero-based line and character offset. The offsets are based on a UTF-16 string representation. So a string of the form `a𐐀b` the character offset of the character `a` is 0, the character offset of `𐐀` is 1 and the character offset of b is 3 since `𐐀` is represented using two code units in UTF-16. To ensure that both client and server split the string into the same line representation the protocol specifies the following end-of-line sequences: '\n', '\r\n' and '\r'. @@ -296,17 +419,17 @@ interface Position { /** * Line position in a document (zero-based). */ - line: number; + line: uinteger; /** - * Character offset on a line in a document (zero-based). Assuming that the - * line is represented as a string, the `character` value represents the gap - * between the `character` and `character + 1`. + * Character offset on a line in a document (zero-based). Assuming that + * the line is represented as a string, the `character` value represents + * the gap between the `character` and `character + 1`. * * If the character value is greater than the line length it defaults back * to the line length. */ - character: number; + character: uinteger; } ``` #### Range @@ -353,8 +476,8 @@ interface LocationLink { /** * Span of the origin of this link. * - * Used as the underlined span for mouse interaction. - * Defaults to the word range at the mouse position. + * Used as the underlined span for mouse interaction. Defaults to the word + * range at the mouse position. */ originSelectionRange?: Range; @@ -364,19 +487,17 @@ interface LocationLink { targetUri: DocumentUri; /** - * The full target range of this link. - * For example, if the target is a symbol, then target range is the range - * enclosing this symbol not including leading/trailing whitespace but - * everything else like comments. - * This information is typically used to highlight the range in the editor. + * The full target range of this link. If the target for example is a symbol + * then target range is the range enclosing this symbol not including + * leading/trailing whitespace but everything else like comments. This + * information is typically used to highlight the range in the editor. */ targetRange: Range; /** * The range that should be selected and revealed when this link is being - * followed, for example, the name of a function. - * Must be contained by the the `targetRange`. - * See also `DocumentSymbol#range` + * followed, e.g the name of a function. Must be contained by the the + * `targetRange`. See also `DocumentSymbol#range` */ targetSelectionRange: Range; } @@ -402,7 +523,14 @@ export interface Diagnostic { /** * The diagnostic's code, which might appear in the user interface. */ - code?: number | string; + code?: integer | string; + + /** + * An optional property to describe the error code. + * + * @since 3.16.0 - proposed state + */ + codeDescription?: CodeDescription; /** * A human-readable string describing the source of this @@ -427,6 +555,15 @@ export interface Diagnostic { * a scope collide all definitions can be marked via this property. */ relatedInformation?: DiagnosticRelatedInformation[]; + + /** + * A data entry field that is preserved between a + * `textDocument/publishDiagnostics` notification and + * `textDocument/codeAction` request. + * + * @since 3.16.0 - proposed state + */ + data?: unknown; } ``` @@ -483,8 +620,8 @@ export type DiagnosticTag = 1 | 2; ```typescript /** * Represents a related message and source code location for a diagnostic. - * This should be used to point to code locations that cause or are related - * to a diagnostics, for example, when duplicating a symbol in a scope. + * This should be used to point to code locations that cause or are related to + * a diagnostics, e.g when duplicating a symbol in a scope. */ export interface DiagnosticRelatedInformation { /** @@ -499,6 +636,22 @@ export interface DiagnosticRelatedInformation { } ``` +`CodeDescription` is defined as follows: + +```typescript +/** + * Structure to capture a description for an error code. + * + * @since 3.16.0 - proposed state + */ +export interface CodeDescription { + /** + * An URI to open with more information about the diagnostic error. + */ + href: URI; +} +``` + #### Command Represents a reference to a command. Provides a title which will be used to represent a command in the UI. Commands are identified by a string identifier. The recommended way to handle commands is to implement their execution on the server side if the client and server provides the corresponding capabilities. Alternatively the tool extension code could handle the command. The protocol currently doesn't specify a set of well-known commands. @@ -521,7 +674,9 @@ interface Command { } ``` -#### TextEdit +#### TextEdit & AnnotatedTextEdit + +> New in version 3.16: Support for `AnnotatedTextEdit`. A textual edit applicable to a text document. @@ -541,33 +696,93 @@ interface TextEdit { } ``` +Since 3.16.0 there is also the concept of an annotated text edit which supports to add an annotation to a text edit. The annotation can add information describing the change to the text edit. + +```typescript +/** + * Additional information that describes document changes. + * + * @since 3.16.0 - proposed state + */ +export interface ChangeAnnotation { + /** + * A human-readable string describing the actual change. The string + * is rendered prominent in the user interface. + */ + label: string; + + /** + * A flag which indicates that user confirmation is needed + * before applying the change. + */ + needsConfirmation?: boolean; + + /** + * A human-readable string which is rendered less prominent in + * the user interface. + */ + description?: string; +} +``` + +Usually clients provide options to group the changes along the annotations they are associated with. To support this in the protocol an edit or resource operation refers to a change annotation using an identifier and not the change annotation literal directly. This allows servers to use the identical annotation across multiple edits or resource operations which then allows clients to group the operations under that change annotation. The actual change annotations together with their identifers are managed by the workspace edit via the new property `changeAnnotations`. + +```typescript + +/** + * An identifier referring to a change annotation managed by a workspace + * edit. + * + * @since 3.16.0 - proposed state. + */ +export type ChangeAnnotationIdentifier = string; + + +/** + * A special text edit with an additional change annotation. + * + * @since 3.16.0 - proposed state. + */ +export interface AnnotatedTextEdit extends TextEdit { + /** + * The actual annotation identifier. + */ + annotationId: ChangeAnnotationIdentifier; +} +``` + #### TextEdit[] -Complex text manipulations are described with an array of `TextEdit`'s, representing a single change to the document. +Complex text manipulations are described with an array of `TextEdit`'s or `AnnotatedTextEdit`'s, representing a single change to the document. All text edits ranges refer to positions in the document the are computed on. They therefore move a document from state S1 to S2 without describing any intermediate state. Text edits ranges must never overlap, that means no part of the original document must be manipulated by more than one edit. However, it is possible that multiple edits have the same start position: multiple inserts, or any number of inserts followed by a single remove or replace edit. If multiple inserts have the same position, the order in the array defines the order in which the inserted strings appear in the resulting text. #### TextDocumentEdit -Describes textual changes on a single text document. The text document is referred to as a `VersionedTextDocumentIdentifier` to allow clients to check the text document version before an edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to sort the array of edits or do any kind of ordering. However the edits must be non overlapping. +> New in version 3.16: support for `AnnotatedTextEdit`. The support is guarded by the client capability `workspace.workspaceEdit.changeAnnotationSupport`. If a client doesn't signal the capability, servers shouldn't send `AnnotatedTextEdit` literals back to the client. + +Describes textual changes on a single text document. The text document is referred to as a `OptionalVersionedTextDocumentIdentifier` to allow clients to check the text document version before an edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to sort the array of edits or do any kind of ordering. However the edits must be non overlapping. ```typescript export interface TextDocumentEdit { /** * The text document to change. */ - textDocument: VersionedTextDocumentIdentifier; + textDocument: OptionalVersionedTextDocumentIdentifier; /** * The edits to be applied. + * + * @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the + * client capability `workspace.workspaceEdit.changeAnnotationSupport` */ - edits: TextEdit[]; + edits: (TextEdit | AnnotatedTextEdit)[]; } ``` ### File Resource changes -> New in version 3.13: +> New in version 3.13. Since version 3.16 file resource changes can carry an additional property `changeAnnotation` to describe the actual change in more detail. Whether a client has support for change annotations is guarded by the client capability `workspace.workspaceEdit.changeAnnotationSupport`. File resource changes allow servers to create, rename and delete files and folders via the client. Note that the names talk about files but the operations are supposed to work on files and folders. This is in line with other naming in the Language Server Protocol (see file watchers which can watch files and folders). The corresponding change literals look as follows: @@ -580,6 +795,7 @@ export interface CreateFileOptions { * Overwrite existing file. Overwrite wins over `ignoreIfExists` */ overwrite?: boolean; + /** * Ignore if exists. */ @@ -594,14 +810,23 @@ export interface CreateFile { * A create */ kind: 'create'; + /** * The resource to create. */ uri: DocumentUri; + /** * Additional options */ options?: CreateFileOptions; + + /** + * An optional annotation identifer describing the operation. + * + * @since 3.16.0 - proposed state + */ + annotationId?: ChangeAnnotationIdentifier; } /** @@ -612,6 +837,7 @@ export interface RenameFileOptions { * Overwrite target if existing. Overwrite wins over `ignoreIfExists` */ overwrite?: boolean; + /** * Ignores if target exists. */ @@ -626,18 +852,28 @@ export interface RenameFile { * A rename */ kind: 'rename'; + /** * The old (existing) location. */ oldUri: DocumentUri; + /** * The new location. */ newUri: DocumentUri; + /** * Rename options. */ options?: RenameFileOptions; + + /** + * An optional annotation identifer describing the operation. + * + * @since 3.16.0 - proposed state + */ + annotationId?: ChangeAnnotationIdentifier; } /** @@ -648,6 +884,7 @@ export interface DeleteFileOptions { * Delete the content recursively if a folder is denoted. */ recursive?: boolean; + /** * Ignore the operation if the file doesn't exist. */ @@ -662,14 +899,23 @@ export interface DeleteFile { * A delete */ kind: 'delete'; + /** * The file to delete. */ uri: DocumentUri; + /** * Delete options. */ options?: DeleteFileOptions; + + /** + * An optional annotation identifer describing the operation. + * + * @since 3.16.0 - proposed state + */ + annotationId?: ChangeAnnotationIdentifier; } ``` @@ -685,24 +931,38 @@ export interface WorkspaceEdit { changes?: { [uri: DocumentUri]: TextEdit[]; }; /** - * The client capability `workspace.workspaceEdit.resourceOperations` - * determines whether document changes are either an array of - * `TextDocumentEdit`s to express changes to different text documents, - * where each text document edit addresses a specific version - * of a text document, or it can contains the above `TextDocumentEdit`s - * mixed with create, rename, and delete file / folder operations. + * Depending on the client capability + * `workspace.workspaceEdit.resourceOperations` document changes are either + * an array of `TextDocumentEdit`s to express changes to n different text + * documents where each text document edit addresses a specific version of + * a text document. Or it can contain above `TextDocumentEdit`s mixed with + * create, rename and delete file / folder operations. * * Whether a client supports versioned document edits is expressed via * `workspace.workspaceEdit.documentChanges` client capability. * - * If a client doesn't support `documentChanges` or - * `workspace.workspaceEdit.resourceOperations`, then only plain - * `TextEdit`s using the `changes` property are supported. + * If a client neither supports `documentChanges` nor + * `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s + * using the `changes` property are supported. */ documentChanges?: ( TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[] ); + + /** + * A map of change annotations that can be referenced in + * `AnnotatedTextEdit`s or create, rename and delete file / folder + * operations. + * + * Whether clients honor this property depends on the client capability + * `workspace.changeAnnotationSupport`. + * + * @since 3.16.0 - proposed state + */ + changeAnnotations?: { + [id: string /* ChangeAnnotationIdentifier */]: ChangeAnnotation; + } } ``` @@ -738,6 +998,31 @@ export interface WorkspaceEditClientCapabilities { * @since 3.13.0 */ failureHandling?: FailureHandlingKind; + + /** + * Whether the client normalizes line endings to the client specific + * setting. + * If set to `true` the client will normalize line ending characters + * in a workspace edit to the client specific new line character(s). + * + * @since 3.16.0 - proposed state + */ + normalizesLineEndings?: boolean; + + /** + * Whether the client in general supports change annotations on text edits, + * create file, rename file and delete file changes. + * + * @since 3.16.0 - proposed state + */ + changeAnnotationSupport?: { + /** + * Whether the client groups edits with equal labels into tree nodes, + * for instance all edits labelled with "Changes in Strings" would + * be a tree node. + */ + groupsOnLabel?: boolean; + }; } /** @@ -770,8 +1055,8 @@ export namespace FailureHandlingKind { /** * Applying the workspace change is simply aborted if one of the changes - * provided fails. - * All operations executed before the failing operation stay executed. + * provided fails. All operations executed before the failing operation + * stay executed. */ export const Abort: FailureHandlingKind = 'abort'; @@ -783,10 +1068,9 @@ export namespace FailureHandlingKind { /** - * If the workspace edit contains only textual file changes, they are - * executed transactionally. - * If resource changes (create, rename or delete file) are part of the - * change, the failure handling strategy is abort. + * If the workspace edit contains only textual file changes they are + * executed transactional. If resource changes (create, rename or delete + * file) are part of the change the failure handling strategy is abort. */ export const TextOnlyTransactional: FailureHandlingKind = 'textOnlyTransactional'; @@ -831,7 +1115,7 @@ interface TextDocumentItem { * The version number of this document (it will increase after each * change, including undo/redo). */ - version: number; + version: integer; /** * The content of the opened text document. @@ -903,22 +1187,36 @@ YAML | `yaml` #### VersionedTextDocumentIdentifier -An identifier to denote a specific version of a text document. +An identifier to denote a specific version of a text document. This information usually flows from the client to the server. ```typescript interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier { /** * The version number of this document. - * If a versioned text document identifier is sent from the server to the - * client and the file is not open in the editor (the server has not - * received an open notification before), the server can send `null` to - * indicate that the version is known and the content on disk is the - * master (as specified with document content ownership). * * The version number of a document will increase after each change, * including undo/redo. The number doesn't need to be consecutive. */ - version: number | null; + version: integer; +} +``` + +An identifier which optionally denotes a specific version of a text document. This information usually flows from the server to the client. + +```typescript +interface OptionalVersionedTextDocumentIdentifier extends TextDocumentIdentifier { + /** + * The version number of this document. If an optional versioned text document + * identifier is sent from the server to the client and the file is not + * open in the editor (the server has not received an open notification + * before) the server can send `null` to indicate that the version is + * known and the content on disk is the master (as specified with document + * content ownership). + * + * The version number of a document will increase after each change, + * including undo/redo. The number doesn't need to be consecutive. + */ + version: integer | null; } ``` @@ -926,7 +1224,7 @@ interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier { Was `TextDocumentPosition` in 1.0 with inlined parameters. -A parameter literal used in requests to pass a text document and a position inside that document. +A parameter literal used in requests to pass a text document and a position inside that document. It is up to the client to decide how a selection is converted into a position when issuing a request for a text document. The client can for example honor or ignore the selection direction to make LSP request consistent with features implemented internally. ```typescript interface TextDocumentPositionParams { @@ -969,13 +1267,13 @@ export interface DocumentFilter { * - `*` to match one or more characters in a path segment * - `?` to match on one character in a path segment * - `**` to match any number of path segments, including none - * - `{}` to group conditions - * (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) + * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript + * and JavaScript files) * - `[]` to declare a range of characters to match in a path segment * (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) * - `[!...]` to negate a range of characters to match in a path segment - * (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, - * but not `example.0`) + * (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + * not `example.0`) */ pattern?: string; } @@ -1014,9 +1312,8 @@ Options to dynamically register for requests for a set of text documents. */ export interface TextDocumentRegistrationOptions { /** - * A document selector to identify the scope of the registration. - * If set to null, the document selector provided on the client side - * will be used. + * A document selector to identify the scope of the registration. If set to + * null the document selector provided on the client side will be used. */ documentSelector: DocumentSelector | null; } @@ -1024,7 +1321,7 @@ export interface TextDocumentRegistrationOptions { #### MarkupContent - A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`. If the format is `markdown` the content can contain fenced code blocks like in [GitHub issues](https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting) + A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`. If the format is `markdown` the content should follow the [GitHub Flavored Markdown Specification](https://github.github.com/gfm/). ```typescript /** @@ -1048,14 +1345,15 @@ export namespace MarkupKind { export type MarkupKind = 'plaintext' | 'markdown'; /** - * A `MarkupContent` literal represents a string value, which content is - * interpreted base on its kind flag. - * Currently the protocol supports `plaintext` and `markdown` as markup kinds. + * A `MarkupContent` literal represents a string value which content is + * interpreted base on its kind flag. Currently the protocol supports + * `plaintext` and `markdown` as markup kinds. * - * If the kind is `markdown`, then the value can contain fenced code blocks - * like in GitHub issues. + * If the kind is `markdown` then the value can contain fenced code blocks like + * in GitHub issues. * - * An example how such a string is constructed using JavaScript / TypeScript: + * Here is an example how such a string can be constructed using + * JavaScript / TypeScript: * ```typescript * let markdown: MarkdownContent = { * kind: MarkupKind.Markdown, @@ -1069,9 +1367,8 @@ export type MarkupKind = 'plaintext' | 'markdown'; * }; * ``` * - * *Please Note* that clients might sanitize the returned Markdown. - * A client could decide to remove HTML from the Markdown to avoid - * script execution. + * *Please Note* that clients might sanitize the return markdown. A client could + * decide to remove HTML from the markdown to avoid script execution. */ export interface MarkupContent { /** @@ -1086,6 +1383,34 @@ export interface MarkupContent { } ``` +In addition clients should signal the markdown parser they are using via the client capability `general.markdown` introduced in version 3.16.0 defined as follows: + + ```typescript +/** + * Client capabilities specific to the used markdown parser. + * + * @since 3.16.0 - proposed state + */ +export interface MarkdownClientCapabilities { + /** + * The name of the parser. + */ + parser: string; + + /** + * The version of the parser. + */ + version?: string; +} + ``` + +Known markdown parsers used by clients right now are: + +Parser | Version | Documentation +------ | ------- | ------------- +marked | 1.1.0 | [Marked Documentation](https://marked.js.org/) + + #### Work Done Progress > *Since version 3.15.0* @@ -1111,8 +1436,8 @@ export interface WorkDoneProgressBegin { /** * Controls if a cancel button should show to allow the user to cancel the - * long running operation. - * Clients that don't support cancellation can ignore the setting. + * long running operation. Clients that don't support cancellation are + * allowed to ignore the setting. */ cancellable?: boolean; @@ -1131,9 +1456,9 @@ export interface WorkDoneProgressBegin { * to ignore the `percentage` value in subsequent in report notifications. * * The value should be steadily rising. Clients are free to ignore values - * that are not following this rule. + * that are not following this rule. The value range is [0, 100] */ - percentage?: number; + percentage?: uinteger; } ``` @@ -1147,12 +1472,11 @@ export interface WorkDoneProgressReport { kind: 'report'; /** - * Controls enablement state of a cancel button. T - * This property is only valid if a cancel button is requested in - * the `WorkDoneProgressStart` payload. + * Controls enablement state of a cancel button. This property is only valid + * if a cancel button got requested in the `WorkDoneProgressStart` payload. * - * Clients that don't support cancellation or don't support controlling - * the button's enablement state are allowed to ignore the setting. + * Clients that don't support cancellation or don't support control the + * button's enablement state are allowed to ignore the setting. */ cancellable?: boolean; @@ -1171,9 +1495,9 @@ export interface WorkDoneProgressReport { * to ignore the `percentage` value in subsequent in report notifications. * * The value should be steadily rising. Clients are free to ignore values - * that are not following this rule. + * that are not following this rule. The value range is [0, 100] */ - percentage?: number; + percentage?: uinteger; } ``` @@ -1248,6 +1572,8 @@ A server uses the `workDoneToken` to report progress for the specific `textDocum } ``` +The token received via the `workDoneToken` property in a request's param literal is only valid as long as the request has not send a response back. + There is no specific client capability signaling whether a client will send a progress token per request. The reason for this is that this is in many clients not a static aspect and might even change for every request instance for the same request type. So the capability is signal on every request instance by the presence of a `workDoneToken` property. To avoid that clients set up a progress monitor user interface before sending a request but the server doesn't actually report any progress a server needs to signal general work done progress reporting support in the corresponding server capability. For the above find references example a server would signal such a support by setting the `referencesProvider` property in the server capabilities as follows: @@ -1269,7 +1595,7 @@ export interface WorkDoneProgressOptions { ``` ###### Server Initiated Progress -Servers can also initiate progress reporting using the `window/workDoneProgress/create` request. This is useful if the server needs to report progress outside of a request (for example the server needs to re-index a database). The returned token can then be used to report progress using the same notifications used as for client initiated progress. +Servers can also initiate progress reporting using the `window/workDoneProgress/create` request. This is useful if the server needs to report progress outside of a request (for example the server needs to re-index a database). The returned token can then be used to report progress using the same notifications used as for client initiated progress. A token obtained using the create request should only be used once (e.g. only one begin, many report and one end notification should be sent to it). To keep the protocol backwards compatible servers are only allowed to use `window/workDoneProgress/create` request if the client signals corresponding support using the client capability `window.workDoneProgress` which is defined as follows: @@ -1327,23 +1653,32 @@ A parameter literal used to pass a partial result token. ```typescript export interface PartialResultParams { /** - * An optional token that a server can use to report partial results - * (for example, streaming) to the client. + * An optional token that a server can use to report partial results (e.g. + * streaming) to the client. */ partialResultToken?: ProgressToken; } ``` +#### TraceValue + +A `TraceValue` represents the level of verbosity with which the server systematically reports its execution trace using [$/logTrace](#logTrace) notifications. +The initial trace value is set by the client at initialization and can be modified later using the [$/setTrace](#setTrace) notification. + +```typescript +export type TraceValue = 'off' | 'message' | 'verbose' +``` + ### Actual Protocol This section documents the actual language server protocol. It uses the following format: * a header describing the request * an optional _Client capability_ section describing the client capability of the request. This includes the client capabilities property path and JSON structure. -* an optional _Server Capability_ section describing the server capability of the request. This includes the server capabilities property path and JSON structure. +* an optional _Server Capability_ section describing the server capability of the request. This includes the server capabilities property path and JSON structure. Clients should ignore server capabilities they don't understand (e.g. the initialize request shouldn't fail in this case). +* an optional _Registration Options_ section describing the registration option if the request or notification supports dynamic capability registration. See the [register](#client_registerCapability) and [unregister](#client_unregisterCapability) request for how this works in detail. * a _Request_ section describing the format of the request sent. The method is a string identifying the request the params are documented using a TypeScript interface. It is also documented whether the request supports work done progress and partial result progress. * a _Response_ section describing the format of the response. The result item describes the returned data in case of a success. The optional partial result item describes the returned data of a partial result notification. The error.data describes the returned data in case of an error. Please remember that in case of a failure the response already contains an error.code and an error.message field. These fields are only specified if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren't listed here. -* a _Registration Options_ section describing the registration option if the request or notification supports dynamic capability registration. #### Request, Notification and Response ordering @@ -1373,12 +1708,12 @@ _Request_: ```typescript interface InitializeParams extends WorkDoneProgressParams { /** - * The process ID of the parent process that started the server. - * Is null if the process has not been started by another process. - * If the parent process is not alive, then the server should exit - * (see exit notification) its process. + * The process Id of the parent process that started the server. Is null if + * the process has not been started by another process. If the parent + * process is not alive then the server should exit (see exit notification) + * its process. */ - processId: number | null; + processId: integer | null; /** * Information about the client @@ -1397,11 +1732,23 @@ interface InitializeParams extends WorkDoneProgressParams { version?: string; }; + /** + * The locale the client is currently showing the user interface + * in. This must not necessarily be the locale of the operating + * system. + * + * Uses IETF language tags as the value's syntax + * (See https://en.wikipedia.org/wiki/IETF_language_tag) + * + * @since 3.16.0 - proposed state + */ + locale?: string; + /** * The rootPath of the workspace. Is null * if no folder is open. * - * @deprecated in favour of rootUri. + * @deprecated in favour of `rootUri`. */ rootPath?: string | null; @@ -1409,6 +1756,8 @@ interface InitializeParams extends WorkDoneProgressParams { * The rootUri of the workspace. Is null if no * folder is open. If both `rootPath` and `rootUri` are set * `rootUri` wins. + * + * @deprecated in favour of `workspaceFolders` */ rootUri: DocumentUri | null; @@ -1425,7 +1774,7 @@ interface InitializeParams extends WorkDoneProgressParams { /** * The initial trace setting. If omitted trace is disabled ('off'). */ - trace?: 'off' | 'messages' | 'verbose'; + trace?: TraceValue; /** * The workspace folders configured in the client when the server starts. @@ -1441,7 +1790,9 @@ interface InitializeParams extends WorkDoneProgressParams { Where `ClientCapabilities` and `TextDocumentClientCapabilities` are defined as follows: -##### `TextDocumentClientCapabilities` define capabilities the editor / tool provides on text documents. +##### TextDocumentClientCapabilities + +`TextDocumentClientCapabilities` define capabilities the editor / tool provides on text documents. ```typescript /** @@ -1569,6 +1920,34 @@ export interface TextDocumentClientCapabilities { * @since 3.15.0 */ selectionRange?: SelectionRangeClientCapabilities; + + /** + * Capabilities specific to the `textDocument/linkedEditingRange` request. + * + * @since 3.16.0 + */ + linkedEditingRange?: LinkedEditingRangeClientCapabilities; + + /** + * Capabilities specific to the various call hierarchy requests. + * + * @since 3.16.0 + */ + callHierarchy?: CallHierarchyClientCapabilities; + + /** + * Capabilities specific to the various semantic token requests. + * + * @since 3.16.0 + */ + semanticTokens?: SemanticTokensClientCapabilities; + + /** + * Capabilities specific to the `textDocument/moniker` request. + * + * @since 3.16.0 + */ + moniker?: MonikerClientCapabilities; } ``` @@ -1583,52 +1962,111 @@ interface ClientCapabilities { */ workspace?: { /** - * The client supports applying batch edits - * to the workspace by supporting the request - * 'workspace/applyEdit' - */ + * The client supports applying batch edits + * to the workspace by supporting the request + * 'workspace/applyEdit' + */ applyEdit?: boolean; /** - * Capabilities specific to `WorkspaceEdit`s - */ + * Capabilities specific to `WorkspaceEdit`s + */ workspaceEdit?: WorkspaceEditClientCapabilities; /** - * Capabilities specific to the `workspace/didChangeConfiguration` - * notification. - */ + * Capabilities specific to the `workspace/didChangeConfiguration` + * notification. + */ didChangeConfiguration?: DidChangeConfigurationClientCapabilities; /** - * Capabilities specific to the `workspace/didChangeWatchedFiles` - * notification. - */ + * Capabilities specific to the `workspace/didChangeWatchedFiles` + * notification. + */ didChangeWatchedFiles?: DidChangeWatchedFilesClientCapabilities; /** - * Capabilities specific to the `workspace/symbol` request. - */ + * Capabilities specific to the `workspace/symbol` request. + */ symbol?: WorkspaceSymbolClientCapabilities; /** - * Capabilities specific to the `workspace/executeCommand` request. - */ + * Capabilities specific to the `workspace/executeCommand` request. + */ executeCommand?: ExecuteCommandClientCapabilities; /** - * The client has support for workspace folders. - * - * Since 3.6.0 - */ + * The client has support for workspace folders. + * + * @since 3.6.0 + */ workspaceFolders?: boolean; /** - * The client supports `workspace/configuration` requests. - * - * Since 3.6.0 - */ + * The client supports `workspace/configuration` requests. + * + * @since 3.6.0 + */ configuration?: boolean; + + /** + * Capabilities specific to the semantic token requests scoped to the + * workspace. + * + * @since 3.16.0 - proposed state + */ + semanticTokens?: SemanticTokensWorkspaceClientCapabilities; + + /** + * Capabilities specific to the code lens requests scoped to the + * workspace. + * + * @since 3.16.0 - proposed state + */ + codeLens?: CodeLensWorkspaceClientCapabilities; + + /** + * The client has support for file requests/notifications. + * + * @since 3.16.0 - proposed state + */ + fileOperations?: { + /** + * Whether the client supports dynamic registration for file + * requests/notifications. + */ + dynamicRegistration?: boolean; + + /** + * The client has support for sending didCreateFiles notifications. + */ + didCreate?: boolean; + + /** + * The client has support for sending willCreateFiles requests. + */ + willCreate?: boolean; + + /** + * The client has support for sending didRenameFiles notifications. + */ + didRename?: boolean; + + /** + * The client has support for sending willRenameFiles requests. + */ + willRename?: boolean; + + /** + * The client has support for sending didDeleteFiles notifications. + */ + didDelete?: boolean; + + /** + * The client has support for sending willDeleteFiles requests. + */ + willDelete?: boolean; + } }; /** @@ -1641,13 +2079,48 @@ interface ClientCapabilities { */ window?: { /** - * Whether client supports handling progress notifications. - * If set, servers are allowed to report in `workDoneProgress` property - * in the request specific server capabilities. + * Whether client supports handling progress notifications. If set + * servers are allowed to report in `workDoneProgress` property in the + * request specific server capabilities. * - * Since 3.15.0 + * @since 3.15.0 */ workDoneProgress?: boolean; + + /** + * Capabilities specific to the showMessage request + * + * @since 3.16.0 - proposed state + */ + showMessage?: ShowMessageRequestClientCapabilities; + + /** + * Client capabilities for the show document request. + * + * @since 3.16.0 - proposed state + */ + showDocument?: ShowDocumentClientCapabilities; + } + + /** + * General client capabilities. + * + * @since 3.16.0 - proposed state + */ + general?: { + /** + * Client capabilities specific to regular expressions. + * + * @since 3.16.0 - proposed state + */ + regularExpressions?: RegularExpressionsClientCapabilities; + + /** + * Client capabilities specific to the client's markdown parser. + * + * @since 3.16.0 - proposed state + */ + markdown?: MarkdownClientCapabilities; } /** @@ -1693,12 +2166,13 @@ interface InitializeResult { */ export namespace InitializeError { /** - * If the protocol version provided by the client can't be handled by - * the server. - * @deprecated This initialize error was replaced by client capabilities. + * If the protocol version provided by the client can't be handled by the + * server. + * + * @deprecated This initialize error got replaced by client capabilities. * There is no version handshake in version 3.0x */ - export const unknownProtocolVersion: number = 1; + export const unknownProtocolVersion: 1 = 1; } ``` @@ -1721,12 +2195,12 @@ The server can signal the following capabilities: ```typescript interface ServerCapabilities { /** - * Defines how text documents are synced. - * Is either a detailed structure defining each notification - * or for backwards compatibility, the TextDocumentSyncKind number. - * If omitted, it defaults to `TextDocumentSyncKind.None`. + * Defines how text documents are synced. Is either a detailed structure + * defining each notification or for backwards compatibility the + * TextDocumentSyncKind number. If omitted it defaults to + * `TextDocumentSyncKind.None`. */ - textDocumentSync?: TextDocumentSyncOptions | number; + textDocumentSync?: TextDocumentSyncOptions | TextDocumentSyncKind; /** * The server provides completion support. @@ -1788,15 +2262,14 @@ interface ServerCapabilities { documentSymbolProvider?: boolean | DocumentSymbolOptions; /** - * The server provides code actions. - * The `CodeActionOptions` return type is only valid if the client signals - * code action literal support via the property - * `textDocument.codeAction.codeActionLiteralSupport`. + * The server provides code actions. The `CodeActionOptions` return type is + * only valid if the client signals code action literal support via the + * property `textDocument.codeAction.codeActionLiteralSupport`. */ codeActionProvider?: boolean | CodeActionOptions; /** - * The server provides CodeLens. + * The server provides code lens. */ codeLensProvider?: CodeLensOptions; @@ -1856,6 +2329,37 @@ interface ServerCapabilities { selectionRangeProvider?: boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions; + /** + * The server provides linked editing range support. + * + * @since 3.16.0 - proposed state + */ + linkedEditingRangeProvider?: boolean | LinkedEditingRangeOptions + | LinkedEditingRangeRegistrationOptions; + + /** + * The server provides call hierarchy support. + * + * @since 3.16.0 + */ + callHierarchyProvider?: boolean | CallHierarchyOptions + | CallHierarchyRegistrationOptions; + + /** + * The server provides semantic tokens support. + * + * @since 3.16.0 + */ + semanticTokensProvider?: SemanticTokensOptions + | SemanticTokensRegistrationOptions; + + /** + * Whether server provides moniker support. + * + * @since 3.16.0 - proposed state + */ + monikerProvider?: boolean | MonikerOptions | MonikerRegistrationOptions; + /** * The server provides workspace symbol support. */ @@ -1871,6 +2375,47 @@ interface ServerCapabilities { * @since 3.6.0 */ workspaceFolders?: WorkspaceFoldersServerCapabilities; + + /** + * The server is interested in file notifications/requests. + * + * @since 3.16.0 - proposed state + */ + fileOperations?: { + /** + * The server is interested in receiving didCreateFiles + * notifications. + */ + didCreate?: FileOperationRegistrationOptions; + + /** + * The server is interested in receiving willCreateFiles requests. + */ + willCreate?: FileOperationRegistrationOptions; + + /** + * The server is interested in receiving didRenameFiles + * notifications. + */ + didRename?: FileOperationRegistrationOptions; + + /** + * The server is interested in receiving willRenameFiles requests. + */ + willRename?: FileOperationRegistrationOptions; + + /** + * The server is interested in receiving didDeleteFiles file + * notifications. + */ + didDelete?: FileOperationRegistrationOptions; + + /** + * The server is interested in receiving willDeleteFiles file + * requests. + */ + willDelete?: FileOperationRegistrationOptions; + } } /** @@ -1914,6 +2459,51 @@ _Notification_: * method: 'exit' * params: void +#### LogTrace Notification (:arrow_left:) + +A notification to log the trace of the server's execution. +The amount and content of these notifications depends on the current `trace` configuration. +If `trace` is `'off'`, the server should not send any `logTrace` notification. +If `trace` is `'message'`, the server should not add the `'verbose'` field in the `LogTraceParams`. + +`$/logTrace` should be used for systematic trace reporting. For single debugging messages, the server should send [`window/logMessage`](#window_logMessage) notifications. + + +_Notification_: +* method: '$/logTrace' +* params: `LogTraceParams` defined as follows: + +```typescript +interface LogTraceParams { + /** + * The message to be logged. + */ + message: string; + /** + * Additional information that can be computed if the `trace` configuration + * is set to `'verbose'` + */ + verbose?: string; +} +``` + +#### SetTrace Notification (:arrow_right:) + +A notification that should be used by the client to modify the trace setting of the server. + +_Notification_: +* method: '$/setTrace' +* params: `SetTraceParams` defined as follows: + +```typescript +interface SetTraceParams { + /** + * The new value that should be assigned to the trace setting. + */ + value: TraceValue; +} +``` + #### ShowMessage Notification (:arrow_left:) The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. @@ -1927,7 +2517,7 @@ interface ShowMessageParams { /** * The message type. See {@link MessageType}. */ - type: number; + type: MessageType; /** * The actual message. @@ -1957,12 +2547,37 @@ export namespace MessageType { */ export const Log = 4; } + +export type MessageType = 1 | 2 | 3 | 4; ``` #### ShowMessage Request (:arrow_right_hook:) The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. +_Client Capability_: +* property path (optional): `window.showMessage` +* property type: `ShowMessageRequestClientCapabilities` defined as follows: + +```typescript +/** + * Show message request client capabilities + */ +export interface ShowMessageRequestClientCapabilities { + /** + * Capabilities specific to the `MessageActionItem` type. + */ + messageActionItem?: { + /** + * Whether the client supports additional attributes which + * are preserved and sent back to the server in the + * request's response. + */ + additionalPropertiesSupport?: boolean; + } +} +``` + _Request_: * method: 'window/showMessageRequest' * params: `ShowMessageRequestParams` defined as follows: @@ -1976,7 +2591,7 @@ interface ShowMessageRequestParams { /** * The message type. See {@link MessageType} */ - type: number; + type: MessageType; /** * The actual message @@ -2001,6 +2616,91 @@ interface MessageActionItem { } ``` +#### Show Document Request (:arrow_right_hook:) + +> New in version 3.16.0 + +The show document request is sent from a server to a client to ask the client to display a particular document in the user interface. + +_Client Capability_: +* property path (optional): `window.showDocument` +* property type: `ShowDocumentClientCapabilities` defined as follows: + +```typescript +/** + * Client capabilities for the show document request. + * + * @since 3.16.0 - proposed state + */ +export interface ShowDocumentClientCapabilities { + /** + * The client has support for the show document + * request. + */ + support: boolean; +} +``` + +_Request_: +* method: 'window/showDocument' +* params: `ShowDocumentParams` defined as follows: + +```typescript +/** + * Params to show a document. + * + * @since 3.16.0 - proposed state + */ +export interface ShowDocumentParams { + /** + * The document uri to show. + */ + uri: URI; + + /** + * Indicates to show the resource in an external program. + * To show for example `https://code.visualstudio.com/` + * in the default WEB browser set `external` to `true`. + */ + external?: boolean; + + /** + * An optional property to indicate whether the editor + * showing the document should take focus or not. + * Clients might ignore this property if an external + * program is started. + */ + takeFocus?: boolean; + + /** + * An optional selection range if the document is a text + * document. Clients might ignore the property if an + * external program is started or the file is not a text + * file. + */ + selection?: Range; +} +``` + +_Response_: + +* result: `ShowDocumentResult` defined as follows: + +```typescript +/** + * The result of an show document request. + * + * @since 3.16.0 - proposed state + */ +export interface ShowDocumentResult { + /** + * A boolean indicating if the show was successful. + */ + success: boolean; +} +``` +* error: code and message set in case an exception happens during showing a document. + #### LogMessage Notification (:arrow_left:) The log message notification is sent from the server to the client to ask the client to log a particular message. @@ -2014,7 +2714,7 @@ interface LogMessageParams { /** * The message type. See {@link MessageType} */ - type: number; + type: MessageType; /** * The actual message @@ -2048,7 +2748,7 @@ _Response_: #### Canceling a Work Done Progress (:arrow_right:) -The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`. +The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`. The progress need not be marked as `cancellable` to be cancelled and a client may cancel a progress for any number of reasons: in case of error, reloading a workspace etc. _Notification_: @@ -2066,11 +2766,11 @@ export interface WorkDoneProgressCancelParams { #### Telemetry Notification (:arrow_left:) -The telemetry notification is sent from the server to the client to ask the client to log a telemetry event. +The telemetry notification is sent from the server to the client to ask the client to log a telemetry event. The protocol doesn't specify the payload since no interpretation of the data happens in the protocol. Most clients even don't handle the event directly but forward them to the extensions owing the corresponding server issuing the event. _Notification_: * method: 'telemetry/event' -* params: 'any' +* params: 'object' \| 'number' \| 'boolean' \| 'string'; #### Register Capability (:arrow_right_hook:) @@ -2363,13 +3063,13 @@ _Response_: #### DidChangeWatchedFiles Notification (:arrow_right:) -The watched files notification is sent from the client to the server when the client detects changes to files watched by the language client. It is recommended that servers register for these file events using the registration mechanism. In former implementations clients pushed file events without the server actively asking for it. +The watched files notification is sent from the client to the server when the client detects changes to files and folders watched by the language client (note although the name suggest that only file events are sent it is about file system events which include folders as well). It is recommended that servers register for these file system events using the registration mechanism. In former implementations clients pushed file events without the server actively asking for it. -Servers are allowed to run their own file watching mechanism and not rely on clients to provide file events. However this is not recommended due to the following reasons: +Servers are allowed to run their own file system watching mechanism and not rely on clients to provide file system events. However this is not recommended due to the following reasons: -- to our experience getting file watching on disk right is challenging, especially if it needs to be supported across multiple OSes. -- file watching is not for free especially if the implementation uses some sort of polling and keeps a file tree in memory to compare time stamps (as for example some node modules do) -- a client usually starts more than one server. If every server runs its own file watching it can become a CPU or memory problem. +- to our experience getting file system watching on disk right is challenging, especially if it needs to be supported across multiple OSes. +- file system watching is not for free especially if the implementation uses some sort of polling and keeps a file system tree in memory to compare time stamps (as for example some node modules do) +- a client usually starts more than one server. If every server runs its own file system watching it can become a CPU or memory problem. - in general there are more server than client implementations. So this problem is better solved on the client side. _Client Capability_: @@ -2412,8 +3112,8 @@ export interface FileSystemWatcher { * - `[]` to declare a range of characters to match in a path segment * (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) * - `[!...]` to negate a range of characters to match in a path segment - * (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, - * but not `example.0`) + * (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not + * `example.0`) */ globPattern: string; @@ -2422,7 +3122,7 @@ export interface FileSystemWatcher { * to WatchKind.Create | WatchKind.Change | WatchKind.Delete * which is 7. */ - kind?: number; + kind?: uinteger; } export namespace WatchKind { @@ -2470,7 +3170,7 @@ interface FileEvent { /** * The change type. */ - type: number; + type: uinteger; } /** @@ -2508,8 +3208,8 @@ interface WorkspaceSymbolClientCapabilities { dynamicRegistration?: boolean; /** - * Specific capabilities for the `SymbolKind` in the - * `workspace/symbol` request. + * Specific capabilities for the `SymbolKind` in the `workspace/symbol` + * request. */ symbolKind?: { /** @@ -2524,6 +3224,19 @@ interface WorkspaceSymbolClientCapabilities { */ valueSet?: SymbolKind[]; } + + /** + * The client supports tags on `SymbolInformation`. + * Clients supporting tags have to handle unknown tags gracefully. + * + * @since 3.16.0 + */ + tagSupport?: { + /** + * The tags supported by the client. + */ + valueSet: SymbolTag[] + } } ``` @@ -2551,8 +3264,8 @@ _Request_: /** * The parameters of a Workspace Symbol Request. */ -interface WorkspaceSymbolParams - extends WorkDoneProgressParams, PartialResultParams { +interface WorkspaceSymbolParams extends WorkDoneProgressParams, + PartialResultParams { /** * A query string to filter symbols by. Clients may send an empty * string here to request all symbols. @@ -2568,9 +3281,7 @@ _Response_: #### Execute a command (:leftwards_arrow_with_hook:) -The `workspace/executeCommand` request is sent from the client to the server to trigger command execution on the server. In most cases -the server creates a `WorkspaceEdit` structure and applies the changes to the workspace using the request `workspace/applyEdit` which is -sent from the server to the client. +The `workspace/executeCommand` request is sent from the client to the server to trigger command execution on the server. In most cases the server creates a `WorkspaceEdit` structure and applies the changes to the workspace using the request `workspace/applyEdit` which is sent from the server to the client. _Client Capability_: * property path (optional): `workspace.executeCommand` @@ -2674,15 +3385,329 @@ export interface ApplyWorkspaceEditResponse { /** * An optional textual description for why the edit was not applied. - * This may be used may be used by the server for diagnostic - * logging or to provide a suitable error for a request that - * triggered the edit. + * This may be used by the server for diagnostic logging or to provide + * a suitable error for a request that triggered the edit. */ failureReason?: string; + + /** + * Depending on the client's failure handling strategy `failedChange` + * might contain the index of the change that failed. This property is + * only available if the client signals a `failureHandlingStrategy` + * in its client capabilities. + */ + failedChange?: uinteger; } ``` * error: code and message set in case an exception happens during the request. +#### WillCreateFiles Request (:leftwards_arrow_with_hook:) + +The will create files request is sent from the client to the server before files are actually created as long as the creation is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are created. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep creates fast and reliable. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.willCreate` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/willCreateFiles` requests. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.willCreate` +* property type: `FileOperationRegistrationOptions` where `FileOperationRegistrationOptions` is defined as follows: + +```typescript +/** + * The options to register for file operations. + * + * @since 3.16.0 - proposed state + */ +interface FileOperationRegistrationOptions { + patterns: FileOperationPattern[]; +} + +/** + * A pattern kind describing if a glob pattern matches a file a folder or + * both. + * + * @since 3.16.0 - proposed state + */ +export namespace FileOperationPatternKind { + /** + * The pattern matches a file only. + */ + export const file: 'file' = 'file'; + + /** + * The pattern matches a folder only. + */ + export const folder: 'folder' = 'folder'; +} + +export type FileOperationPatternKind = 'file' | 'folder'; + +/** + * Matching options for the file operation pattern. + * + * @since 3.16.0 - proposed state + */ +export interface FileOperationPatternOptions { + + /** + * The pattern should be matched ignoring casing. + */ + ignoreCase?: boolean; +} + +/** + * A pattern to describe in which file operation requests or notifications + * the server is interested in. + * + * @since 3.16.0 - proposed state + */ +interface FileOperationPattern { + /** + * The glob pattern to match. Glob patterns can have the following syntax: + * - `*` to match one or more characters in a path segment + * - `?` to match on one character in a path segment + * - `**` to match any number of path segments, including none + * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript + * and JavaScript files) + * - `[]` to declare a range of characters to match in a path segment + * (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + * - `[!...]` to negate a range of characters to match in a path segment + * (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + * not `example.0`) + */ + glob: string; + + /** + * Whether to match files or folders with this pattern. + * + * Matches both if undefined. + */ + matches?: FileOperationPatternKind; + + /** + * Additional options used during matching. + */ + options?: FileOperationPatternOptions; +} +``` + +The capability indicates that the server is interested in receiving `workspace/willCreateFiles` requests. + +_Registration Options_: none + +_Request_: +* method: 'workspace/willCreateFiles' +* params: `CreateFilesParams` defined as follows: + +```typescript +/** + * The parameters sent in notifications/requests for user-initiated creation + * of files. + * + * @since 3.16.0 - proposed state + */ +export interface CreateFilesParams { + + /** + * An array of all files/folders created in this operation. + */ + files: FileCreate[]; +} +/** + * Represents information on a file/folder create. + * + * @since 3.16.0 - proposed state + */ +export interface FileCreate { + + /** + * A file:// URI for the location of the file/folder being created. + */ + uri: string; +} +``` + +_Response_: +* result:`WorkspaceEdit` \| `null` +* error: code and message set in case an exception happens during the `willCreateFiles` request. + +#### DidCreateFiles Notification (:arrow_right:) + +The did create files notification is sent from the client to the server when files were created from within the client. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.didCreate` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/didCreateFiles` notifications. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.didCreate` +* property type: `FileOperationRegistrationOptions` + +The capability indicates that the server is interested in receiving `workspace/didCreateFiles` notifications. + +_Notification_: +* method: 'workspace/didCreateFiles' +* params: `CreateFilesParams` + +#### WillRenameFiles Request (:leftwards_arrow_with_hook:) + +The will rename files request is sent from the client to the server before files are actually renamed as long as the rename is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are renamed. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep renames fast and reliable. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.willRename` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/willRenameFiles` requests. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.willRename` +* property type: `FileOperationRegistrationOptions` + +The capability indicates that the server is interested in receiving `workspace/willRenameFiles` requests. + +_Registration Options_: none + +_Request_: +* method: 'workspace/willRenameFiles' +* params: `RenameFilesParams` defined as follows: + +```typescript +/** + * The parameters sent in notifications/requests for user-initiated renames + * of files. + * + * @since 3.16.0 - proposed state + */ +export interface RenameFilesParams { + + /** + * An array of all files/folders renamed in this operation. When a folder + * is renamed, only the folder will be included, and not its children. + */ + files: FileRename[]; +} +/** + * Represents information on a file/folder rename. + * + * @since 3.16.0 - proposed state + */ +export interface FileRename { + + /** + * A file:// URI for the original location of the file/folder being renamed. + */ + oldUri: string; + + /** + * A file:// URI for the new location of the file/folder being renamed. + */ + newUri: string; +} +``` + +_Response_: +* result:`WorkspaceEdit` \| `null` +* error: code and message set in case an exception happens during the `willRenameFiles` request. + +#### DidRenameFiles Notification (:arrow_right:) + +The did rename files notification is sent from the client to the server when files were renamed from within the client. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.didRename` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/didRenameFiles` notifications. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.didRename` +* property type: `FileOperationRegistrationOptions` + +The capability indicates that the server is interested in receiving `workspace/didRenameFiles` notifications. + +_Notification_: +* method: 'workspace/didRenameFiles' +* params: `RenameFilesParams` + +#### WillDeleteFiles Request (:leftwards_arrow_with_hook:) + +The will delete files request is sent from the client to the server before files are actually deleted as long as the deletion is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are deleted. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep deletes fast and reliable. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.willDelete` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/willDeleteFiles` requests. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.willDelete` +* property type: `FileOperationRegistrationOptions` + +The capability indicates that the server is interested in receiving `workspace/willDeleteFiles` requests. + +_Registration Options_: none + +_Request_: +* method: 'workspace/willDeleteFiles' +* params: `DeleteFilesParams` defined as follows: + +```typescript +/** + * The parameters sent in notifications/requests for user-initiated deletes + * of files. + * + * @since 3.16.0 - proposed state + */ +export interface DeleteFilesParams { + + /** + * An array of all files/folders deleted in this operation. + */ + files: FileDelete[]; +} +/** + * Represents information on a file/folder delete. + * + * @since 3.16.0 - proposed state + */ +export interface FileDelete { + + /** + * A file:// URI for the location of the file/folder being deleted. + */ + uri: string; +} +``` + +_Response_: +* result:`WorkspaceEdit` \| `null` +* error: code and message set in case an exception happens during the `willDeleteFiles` request. + +#### DidDeleteFiles Notification (:arrow_right:) + +The did delete files notification is sent from the client to the server when files were deleted from within the client. + +_Client Capability_: +* property name (optional): `workspace.fileOperations.didDelete` +* property type: `boolean` + +The capability indicates that the client supports sending `workspace/didDeleteFiles` notifications. + +_Server Capability_: +* property name (optional): `workspace.fileOperations.didDelete` +* property type: `FileOperationRegistrationOptions` + +The capability indicates that the server is interested in receiving `workspace/didDeleteFiles` notifications. + +_Notification_: +* method: 'workspace/didDeleteFiles' +* params: `DeleteFilesParams` + #### Text Document Synchronization Client support for `textDocument/didOpen`, `textDocument/didChange` and `textDocument/didClose` notifications is mandatory in the protocol and clients can not opt out supporting them. This includes both full and incremental synchronization in the `textDocument/didChange` notification. In addition a server must either implement all three of them or none. Their capabilities are therefore controlled via a combined client and server capability. @@ -2699,8 +3724,8 @@ Controls whether text document synchronization supports dynamic registration. ```typescript /** - * Defines how the host (editor) should sync document changes - * to the language server. + * Defines how the host (editor) should sync document changes to the language + * server. */ export namespace TextDocumentSyncKind { /** @@ -2724,16 +3749,16 @@ export namespace TextDocumentSyncKind { export interface TextDocumentSyncOptions { /** - * Open and close notifications are sent to the server. - * If omitted open close notification should not be sent. + * Open and close notifications are sent to the server. If omitted open + * close notification should not be sent. */ openClose?: boolean; /** - * Change notifications are sent to the server. - * See TextDocumentSyncKind.None, TextDocumentSyncKind.Full, - * and TextDocumentSyncKind.Incremental. - * If omitted, it defaults to TextDocumentSyncKind.None. + * Change notifications are sent to the server. See + * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and + * TextDocumentSyncKind.Incremental. If omitted it defaults to + * TextDocumentSyncKind.None. */ change?: TextDocumentSyncKind; } @@ -2805,28 +3830,26 @@ interface DidChangeTextDocumentParams { textDocument: VersionedTextDocumentIdentifier; /** - * The actual content changes. - * The content changes describe single state changes to the document. - * If there are two content changes c1 (at array index 0) and - * c2 (at array index 1) for a document in state S, then c1 moves the - * document from S to S' and c2 from S' to S''. - * So c1 is computed on the state S and c2 is computed on the state S'. + * The actual content changes. The content changes describe single state + * changes to the document. So if there are two content changes c1 (at + * array index 0) and c2 (at array index 1) for a document in state S then + * c1 moves the document from S to S' and c2 from S' to S''. So c1 is + * computed on the state S and c2 is computed on the state S'. * - * To mirror the content of a document using change events, - * use the following approach: + * To mirror the content of a document using change events use the following + * approach: * - start with the same initial content - * - apply the 'textDocument/didChange' notifications - * in the order you receive them. - * - apply the `TextDocumentContentChangeEvent`s - * in a single notification in the order you receive them. + * - apply the 'textDocument/didChange' notifications in the order you + * receive them. + * - apply the `TextDocumentContentChangeEvent`s in a single notification + * in the order you receive them. */ contentChanges: TextDocumentContentChangeEvent[]; } /** - * An event describing a change to a text document. - * If range and rangeLength are omitted, the new text is considered to be - * the full content of the document. + * An event describing a change to a text document. If range and rangeLength are + * omitted the new text is considered to be the full content of the document. */ export type TextDocumentContentChangeEvent = { /** @@ -2839,7 +3862,7 @@ export type TextDocumentContentChangeEvent = { * * @deprecated use range instead. */ - rangeLength?: number; + rangeLength?: uinteger; /** * The new text for the provided range. @@ -2888,7 +3911,7 @@ export interface WillSaveTextDocumentParams { /** * The 'TextDocumentSaveReason'. */ - reason: number; + reason: TextDocumentSaveReason; } /** @@ -2897,8 +3920,8 @@ export interface WillSaveTextDocumentParams { export namespace TextDocumentSaveReason { /** - * Manually triggered, for example, by the user pressing save, - * by starting debugging, or by an API call. + * Manually triggered, e.g. by the user pressing save, by starting + * debugging, or by an API call. */ export const Manual = 1; @@ -2912,6 +3935,8 @@ export namespace TextDocumentSaveReason { */ export const FocusOut = 3; } + +export type TextDocumentSaveReason = 1 | 2 | 3; ``` #### WillSaveWaitUntilTextDocument Request (:leftwards_arrow_with_hook:) @@ -3048,8 +4073,8 @@ export interface TextDocumentSyncClientCapabilities { } /** - * Defines how the host (editor) should sync document changes - * to the language server. + * Defines how the host (editor) should sync document changes to the language + * server. */ export namespace TextDocumentSyncKind { /** @@ -3071,32 +4096,34 @@ export namespace TextDocumentSyncKind { export const Incremental = 2; } +export type TextDocumentSyncKind = 0 | 1 | 2; + export interface TextDocumentSyncOptions { /** - * Open and close notifications are sent to the server. - * If omitted, open close notification should not be sent. + * Open and close notifications are sent to the server. If omitted open + * close notification should not be sent. */ openClose?: boolean; /** - * Change notifications are sent to the server. - * See TextDocumentSyncKind.None, TextDocumentSyncKind.Full, - * and TextDocumentSyncKind.Incremental. - * If omitted, it defaults to TextDocumentSyncKind.None. + * Change notifications are sent to the server. See + * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and + * TextDocumentSyncKind.Incremental. If omitted it defaults to + * TextDocumentSyncKind.None. */ - change?: number; + change?: TextDocumentSyncKind; /** - * If present will save notifications are sent to the server. - * If omitted, the notification should not be sent. + * If present will save notifications are sent to the server. If omitted + * the notification should not be sent. */ willSave?: boolean; /** - * If present will save wait until requests are sent to the server. - * If omitted, the request should not be sent. + * If present will save wait until requests are sent to the server. If + * omitted the request should not be sent. */ willSaveWaitUntil?: boolean; /** - * If present save notifications are sent to the server. - * If omitted, the notification should not be sent. + * If present save notifications are sent to the server. If omitted the + * notification should not be sent. */ save?: boolean | SaveOptions; } @@ -3108,7 +4135,7 @@ Diagnostics notification are sent from the server to the client to signal result Diagnostics are "owned" by the server so it is the server's responsibility to clear them if necessary. The following rule is used for VS Code servers that generate diagnostics: -* if a language is single file only (for example HTML) then diagnostics are cleared by the server when the file is closed. +* if a language is single file only (for example HTML) then diagnostics are cleared by the server when the file is closed. Please note that open / close events don't necessarily reflect what the user sees in the user interface. These events are ownership events. So with the current version of the specification it is possible that problems are not cleared although the file is not visible in the user interface since the client has not closed the file yet. * if a language has a project system (for example C#) diagnostics are not cleared when a file closes. When a project is opened all diagnostics for all files are recomputed (or read from a cache). When a file changes it is the server's responsibility to re-compute diagnostics and push them to the client. If the computed set is empty it has to push the empty array to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. There is no merging that happens on the client side. @@ -3146,6 +4173,22 @@ export interface PublishDiagnosticsClientCapabilities { * @since 3.15.0 */ versionSupport?: boolean; + + /** + * Client supports a codeDescription property + * + * @since 3.16.0 - proposed state + */ + codeDescriptionSupport?: boolean; + + /** + * Whether code action supports the `data` property which is + * preserved between a `textDocument/publishDiagnostics` and + * `textDocument/codeAction` request. + * + * @since 3.16.0 - proposed state + */ + dataSupport?: boolean; } ``` @@ -3161,11 +4204,12 @@ interface PublishDiagnosticsParams { uri: DocumentUri; /** - * The version number of the document the diagnostics are published for. - * Optional. + * Optional the version number of the document the diagnostics are published + * for. + * * @since 3.15.0 */ - version?: number; + version?: uinteger; /** * An array of diagnostic information items. @@ -3176,7 +4220,8 @@ interface PublishDiagnosticsParams { #### Completion Request (:leftwards_arrow_with_hook:) -The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the 'textDocument/completion' request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. The request can only delay the computation of the `detail` and `documentation` properties. Other properties like `sortText`, `filterText`, `insertText`, `textEdit` and `additionalTextEdits` must be provided in the `textDocument/completion` response and must not be changed during resolve. +The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) user interface. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the 'textDocument/completion' request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. By default the request can only delay the computation of the `detail` and `documentation` properties. Since 3.16.0 the client +can signal that it can resolve more properties lazily. This is done using the `completionItem#resolveSupport` client capability which lists all properties that can be filled in during a 'completionItem/resolve' request. All other properties (usually `sortText`, `filterText`, `insertText` and `textEdit`) must be provided in the `textDocument/completion` response and must not be changed during resolve. _Client Capability_: * property name (optional): `textDocument.completion` @@ -3199,9 +4244,8 @@ export interface CompletionClientCapabilities { * * A snippet can define tab stops and placeholders with `$1`, `$2` * and `${3:foo}`. `$0` defines the final tab stop, it defaults to - * the end of the snippet. - * Placeholders with equal identifiers are linked, so that typing in - * one will update others as well. + * the end of the snippet. Placeholders with equal identifiers are + * linked, that is typing in one will update others too. */ snippetSupport?: boolean; @@ -3227,10 +4271,10 @@ export interface CompletionClientCapabilities { preselectSupport?: boolean; /** - * Client supports the tag property on a completion item. - * Clients supporting tags have to handle unknown tags gracefully. - * Clients especially need to preserve unknown tags when sending - * a completion item back to the server in a resolve call. + * Client supports the tag property on a completion item. Clients + * supporting tags have to handle unknown tags gracefully. Clients + * especially need to preserve unknown tags when sending a completion + * item back to the server in a resolve call. * * @since 3.15.0 */ @@ -3240,6 +4284,39 @@ export interface CompletionClientCapabilities { */ valueSet: CompletionItemTag[] } + + /** + * Client supports insert replace edit to control different behavior if + * a completion item is inserted in the text or should replace text. + * + * @since 3.16.0 - proposed state + */ + insertReplaceSupport?: boolean; + + /** + * Indicates which properties a client can resolve lazily on a + * completion item. Before version 3.16.0 only the predefined properties + * `documentation` and `details` could be resolved lazily. + * + * @since 3.16.0 - proposed state + */ + resolveSupport?: { + /** + * The properties that a client can resolve lazily. + */ + properties: string[]; + }; + + /** + * The client supports the `insertTextMode` property on + * a completion item to override the whitespace handling mode + * as defined by the client (see `insertTextMode`). + * + * @since 3.16.0 - proposed state + */ + insertTextModeSupport?: { + valueSet: InsertTextMode[]; + } }; completionItemKind?: { @@ -3275,27 +4352,26 @@ _Server Capability_: export interface CompletionOptions extends WorkDoneProgressOptions { /** * Most tools trigger completion request automatically without explicitly - * requesting it using a keyboard shortcut (for example Ctrl+Space). - * Typically they do so when the user starts to type an identifier. - * For example, if the user types `c` in a JavaScript file, code complete - * will automatically display `console` along with others as a - * completion item. - * Characters that make up identifiers don't need to be listed here. + * requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they + * do so when the user starts to type an identifier. For example if the user + * types `c` in a JavaScript file code complete will automatically pop up + * present `console` besides others as a completion item. Characters that + * make up identifiers don't need to be listed here. * - * If code complete should automatically be triggered on characters - * not being valid inside an identifier (for example `.` in JavaScript), - * list them in `triggerCharacters`. + * If code complete should automatically be trigger on characters not being + * valid inside an identifier (for example `.` in JavaScript) list them in + * `triggerCharacters`. */ triggerCharacters?: string[]; /** - * The list of all possible characters that commit a completion. - * This field can be used if clients don't support individual commit - * characters per completion item. See `ClientCapabilities.` - * `textDocument.completion.completionItem.commitCharactersSupport`. + * The list of all possible characters that commit a completion. This field + * can be used if clients don't support individual commit characters per + * completion item. See client capability + * `completion.completionItem.commitCharactersSupport`. * - * If a server provides both `allCommitCharacters` and commit characters - * on an individual completion item, the ones on the completion item win. + * If a server provides both `allCommitCharacters` and commit characters on + * an individual completion item the ones on the completion item win. * * @since 3.2.0 */ @@ -3321,13 +4397,12 @@ _Request_: * params: `CompletionParams` defined as follows: ```typescript -export interface CompletionParams - extends TextDocumentPositionParams, WorkDoneProgressParams, - PartialResultParams { +export interface CompletionParams extends TextDocumentPositionParams, + WorkDoneProgressParams, PartialResultParams { /** - * The completion context. - * This is only available if the client specifies to send this using - * `ClientCapabilities.textDocument.completion.contextSupport === true` + * The completion context. This is only available if the client specifies + * to send this using the client capability + * `completion.contextSupport === true` */ context?: CompletionContext; } @@ -3344,7 +4419,8 @@ export namespace CompletionTriggerKind { /** * Completion was triggered by a trigger character specified by - * the `triggerCharacters` properties of `CompletionRegistrationOptions`. + * the `triggerCharacters` properties of the + * `CompletionRegistrationOptions`. */ export const TriggerCharacter: 2 = 2; @@ -3367,8 +4443,9 @@ export interface CompletionContext { triggerKind: CompletionTriggerKind; /** - * The trigger character (single character) that has trigger code complete. - * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` + * The trigger character (a single character) that has trigger code + * complete. Is undefined if + * `triggerKind !== CompletionTriggerKind.TriggerCharacter` */ triggerCharacter?: string; } @@ -3419,8 +4496,8 @@ export namespace InsertTextFormat { export type InsertTextFormat = 1 | 2; /** - * Completion item tags are extra annotations that tweak the rendering of - * a completion item. + * Completion item tags are extra annotations that tweak the rendering of a + * completion item. * * @since 3.15.0 */ @@ -3433,6 +4510,58 @@ export namespace CompletionItemTag { export type CompletionItemTag = 1; +/** + * A special text edit to provide an insert and a replace operation. + * + * @since 3.16.0 - proposed state + */ +export interface InsertReplaceEdit { + /** + * The string to be inserted. + */ + newText: string; + + /** + * The range if the insert is requested + */ + insert: Range; + + /** + * The range if the replace is requested. + */ + replace: Range; +} + +/** + * How whitespace and indentation is handled during completion + * item insertion. + * + * @since 3.16.0 - proposed state + */ +export namespace InsertTextMode { + /** + * The insertion or replace strings is taken as it is. If the + * value is multi line the lines below the cursor will be + * inserted using the indentation defined in the string value. + * The client will not apply any kind of adjustments to the + * string. + */ + export const asIs: 1 = 1; + + /** + * The editor adjusts leading whitespace of new lines so that + * they match the indentation up to the cursor of the line for + * which the item is accepted. + * + * Consider a line like this: <2tabs><3tabs>foo. Accepting a + * multi line completion item is indented using 2 tabs and all + * following lines inserted will be indented using 2 tabs as well. + */ + export const adjustIndentation: 2 = 2; +} + +export type InsertTextMode = 1 | 2; + export interface CompletionItem { /** * The label of this completion item. By default @@ -3446,7 +4575,7 @@ export interface CompletionItem { * an icon is chosen by the editor. The standardized set * of available values is defined in `CompletionItemKind`. */ - kind?: number; + kind?: CompletionItemKind; /** * Tags for this completion item. @@ -3499,37 +4628,61 @@ export interface CompletionItem { * this completion. When `falsy` the label is used. * * The `insertText` is subject to interpretation by the client side. - * Some tools might not take the string literally. - * For example, VS Code when code complete is requested in this example + * Some tools might not take the string literally. For example + * VS Code when code complete is requested in this example * `con` and a completion item with an `insertText` of - * `console` is provided, it will only insert `sole`. - * Therefore, it is recommended to use `textEdit` instead since it avoids - * additional client side interpretation. + * `console` is provided it will only insert `sole`. Therefore it is + * recommended to use `textEdit` instead since it avoids additional client + * side interpretation. */ insertText?: string; /** - * The format of the insert text. - * The format applies to both the `insertText` property and the `newText` - * property of a provided `textEdit`. - * If omitted, defaults to `InsertTextFormat.PlainText`. + * The format of the insert text. The format applies to both the + * `insertText` property and the `newText` property of a provided + * `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`. */ insertTextFormat?: InsertTextFormat; /** - * An edit that is applied to a document when selecting this completion. - * When an edit is provided, the value of `insertText` is ignored. + * How whitespace and indentation is handled during completion + * item insertion. If not provided the client's default value depends on + * the `textDocument.completion.insertTextMode` client capability. + * + * @since 3.16.0 - proposed state + */ + insertTextMode?: InsertTextMode; + + /** + * An edit which is applied to a document when selecting this completion. + * When an edit is provided the value of `insertText` is ignored. * * *Note:* The range of the edit must be a single line range and it must * contain the position at which completion has been requested. + * + * Most editors support two different operations when accepting a completion + * item. One is to insert a completion text and the other is to replace an + * existing text with a completion text. Since this can usually not be + * predetermined by a server it can report both ranges. Clients need to + * signal support for `InsertReplaceEdits` via the + * `textDocument.completion.insertReplaceSupport` client capability + * property. + * + * *Note 1:* The text edit's range as well as both ranges from an insert + * replace edit must be a [single line] and they must contain the position + * at which completion has been requested. + * *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range + * must be a prefix of the edit's replace range, that means it must be + * contained and starting at the same position. + * + * @since 3.16.0 additional type `InsertReplaceEdit` - proposed state */ - textEdit?: TextEdit; + textEdit?: TextEdit | InsertReplaceEdit; /** * An optional array of additional text edits that are applied when - * selecting this completion. - * Edits must not overlap (including the same insert position) with the - * main edit nor with themselves. + * selecting this completion. Edits must not overlap (including the same + * insert position) with the main edit nor with themselves. * * Additional text edits should be used to change text unrelated to the * current cursor position (for example adding an import statement at the @@ -3538,10 +4691,10 @@ export interface CompletionItem { additionalTextEdits?: TextEdit[]; /** - * An optional set of characters that when pressed, while this completion - * is active, will accept it first and then type that character. - * *Note* that all commit characters should have `length=1` and that - * superfluous characters will be ignored. + * An optional set of characters that when pressed while this completion is + * active will accept it first and then type that character. *Note* that all + * commit characters should have `length=1` and that superfluous characters + * will be ignored. */ commitCharacters?: string[]; @@ -3631,7 +4784,7 @@ The following variables can be used: Transformations allow you to modify the value of a variable before it is inserted. The definition of a transformation consists of three parts: -1. A regular expression that is matched against the value of a variable, or the empty string when the variable cannot be resolved. +1. A [regular expression](#regExp) that is matched against the value of a variable, or the empty string when the variable cannot be resolved. 2. A "format string" that allows to reference matching groups from the regular expression. The format string allows for conditional inserts and simple modifications. 3. Options that are passed to the regular expression. @@ -3668,8 +4821,8 @@ format ::= '$' int | '${' int '}' | '${' int ':+' if '}' | '${' int ':?' if ':' else '}' | '${' int ':-' else '}' | '${' int ':' else '}' -regex ::= JavaScript Regular Expression value (ctor-string) -options ::= JavaScript Regular Expression option (ctor-options) +regex ::= Regular Expression value (ctor-string) +options ::= Regular Expression option (ctor-options) var ::= [_a-zA-Z] [_a-zA-Z0-9]* int ::= [0-9]+ text ::= .* @@ -3703,8 +4856,9 @@ export interface HoverClientCapabilities { dynamicRegistration?: boolean; /** - * Client supports the follow content formats for the content - * property. The order describes the preferred format of the client. + * Client supports the follow content formats if the content + * property refers to a `literal of type MarkupContent`. + * The order describes the preferred format of the client. */ contentFormat?: MarkupKind[]; } @@ -3731,8 +4885,8 @@ _Request_: * params: `HoverParams` defined as follows: ```typescript -export interface HoverParams - extends TextDocumentPositionParams, WorkDoneProgressParams { +export interface HoverParams extends TextDocumentPositionParams, + WorkDoneProgressParams { } ``` @@ -3761,19 +4915,21 @@ Where `MarkedString` is defined as follows: ```typescript /** - * MarkedString can be used to render human readable text. - * It is either a Markdown string or a code-block that provides a language - * and a code snippet. The language identifier is semantically equal to the - * optional language identifier in fenced code blocks in GitHub issues. + * MarkedString can be used to render human readable text. It is either a + * markdown string or a code-block that provides a language and a code snippet. + * The language identifier is semantically equal to the optional language + * identifier in fenced code blocks in GitHub issues. * - * The pair of a language and a value is an equivalent to Markdown: + * The pair of a language and a value is an equivalent to markdown: * ```${language} * ${value} * ``` * - * Note that Markdown strings will be sanitized, meaning HTML will be escaped. -* @deprecated use MarkupContent instead. -*/ + * Note that markdown strings will be sanitized - that means html will be + * escaped. + * + * @deprecated use MarkupContent instead. + */ type MarkedString = string | { language: string; value: string }; ``` @@ -3817,6 +4973,14 @@ export interface SignatureHelpClientCapabilities { */ labelOffsetSupport?: boolean; }; + + /** + * The client supports the `activeParameter` property on + * `SignatureInformation` literal. + * + * @since 3.16.0 - proposed state + */ + activeParameterSupport?: boolean; }; /** @@ -3847,8 +5011,8 @@ export interface SignatureHelpOptions extends WorkDoneProgressOptions { * List of characters that re-trigger signature help. * * These trigger characters are only active when signature help is already - * showing. - * All trigger characters are also counted as re-trigger characters. + * showing. All trigger characters are also counted as re-trigger + * characters. * * @since 3.15.0 */ @@ -3871,9 +5035,9 @@ _Request_: export interface SignatureHelpParams extends TextDocumentPositionParams, WorkDoneProgressParams { /** - * The signature help context. - * This is only available if the client specifies to send this using the - * client capability `textDocument.signatureHelp.contextSupport === true`. + * The signature help context. This is only available if the client + * specifies to send this using the client capability + * `textDocument.signatureHelp.contextSupport === true` * * @since 3.15.0 */ @@ -3895,16 +5059,16 @@ export namespace SignatureHelpTriggerKind { */ export const TriggerCharacter: 2 = 2; /** - * Signature help was triggered by the cursor moving or - * by the document content changing. + * Signature help was triggered by the cursor moving or by the document + * content changing. */ export const ContentChange: 3 = 3; } export type SignatureHelpTriggerKind = 1 | 2 | 3; /** - * Additional information about the context in which a - * signature help request was triggered. + * Additional information about the context in which a signature help request + * was triggered. * * @since 3.15.0 */ @@ -3917,8 +5081,8 @@ export interface SignatureHelpContext { /** * Character that caused signature help to be triggered. * - * This is undefined when - * `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter`. + * This is undefined when triggerKind !== + * SignatureHelpTriggerKind.TriggerCharacter */ triggerCharacter?: string; @@ -3926,8 +5090,8 @@ export interface SignatureHelpContext { * `true` if signature help was already showing when it was triggered. * * Retriggers occur when the signature help is already active and can be - * caused by actions such as typing a trigger character, a cursor move, - * or document content changes. + * caused by actions such as typing a trigger character, a cursor move, or + * document content changes. */ isRetrigger: boolean; @@ -3968,7 +5132,7 @@ export interface SignatureHelp { * In future version of the protocol this property might become * mandatory to better express this. */ - activeSignature?: number; + activeSignature?: uinteger; /** * The active parameter of the active signature. If omitted or the value @@ -3979,7 +5143,7 @@ export interface SignatureHelp { * mandatory to better express the active parameter if the * active signature does have any. */ - activeParameter?: number; + activeParameter?: uinteger; } /** @@ -4004,6 +5168,15 @@ export interface SignatureInformation { * The parameters of this signature. */ parameters?: ParameterInformation[]; + + /** + * The index of the active parameter. + * + * If provided, this is used in place of `SignatureHelp.activeParameter`. + * + * @since 3.16.0 - proposed state + */ + activeParameter?: uinteger; } /** @@ -4016,15 +5189,15 @@ export interface ParameterInformation { * The label of this parameter information. * * Either a string or an inclusive start and exclusive end offsets within - * its containing signature label. (see SignatureInformation.label). - * The offsets are based on a UTF-16 string representation - * as `Position` and `Range` does. + * its containing signature label. (see SignatureInformation.label). The + * offsets are based on a UTF-16 string representation as `Position` and + * `Range` does. * * *Note*: a label of type string should be a substring of its containing - * signature label. Its intended use case is to highlight the - * parameter label part in the `SignatureInformation.label`. + * signature label. Its intended use case is to highlight the parameter + * label part in the `SignatureInformation.label`. */ - label: string | [number, number]; + label: string | [uinteger, uinteger]; /** * The human-readable doc-comment of this parameter. Will be shown @@ -4051,10 +5224,9 @@ _Client Capability_: ```typescript export interface DeclarationClientCapabilities { /** - * Whether declaration supports dynamic registration. - * If this is set to `true`, the client supports the new - * `DeclarationRegistrationOptions` return value for the - * corresponding server capability as well. + * Whether declaration supports dynamic registration. If this is set to + * `true` the client supports the new `DeclarationRegistrationOptions` + * return value for the corresponding server capability as well. */ dynamicRegistration?: boolean; @@ -4133,8 +5305,8 @@ export interface DefinitionOptions extends WorkDoneProgressOptions { _Registration Options_: `DefinitionRegistrationOptions` defined as follows: ```typescript -export interface DefinitionRegistrationOptions - extends TextDocumentRegistrationOptions, DefinitionOptions { +export interface DefinitionRegistrationOptions extends + TextDocumentRegistrationOptions, DefinitionOptions { } ``` @@ -4143,9 +5315,8 @@ _Request_: * params: `DefinitionParams` defined as follows: ```typescript -export interface DefinitionParams - extends TextDocumentPositionParams, WorkDoneProgressParams, - PartialResultParams { +export interface DefinitionParams extends TextDocumentPositionParams, + WorkDoneProgressParams, PartialResultParams { } ``` @@ -4169,10 +5340,9 @@ _Client Capability_: ```typescript export interface TypeDefinitionClientCapabilities { /** - * Whether implementation supports dynamic registration. - * If this is set to `true`, the client supports the new ` - * TypeDefinitionRegistrationOptions` return value for the - * corresponding server capability as well. + * Whether implementation supports dynamic registration. If this is set to + * `true` the client supports the new `TypeDefinitionRegistrationOptions` + * return value for the corresponding server capability as well. */ dynamicRegistration?: boolean; @@ -4196,9 +5366,9 @@ export interface TypeDefinitionOptions extends WorkDoneProgressOptions { _Registration Options_: `TypeDefinitionRegistrationOptions` defined as follows: ```typescript -export interface TypeDefinitionRegistrationOptions - extends TextDocumentRegistrationOptions, TypeDefinitionOptions, - StaticRegistrationOptions { +export interface TypeDefinitionRegistrationOptions extends + TextDocumentRegistrationOptions, TypeDefinitionOptions, + StaticRegistrationOptions { } ``` @@ -4207,9 +5377,8 @@ _Request_: * params: `TypeDefinitionParams` defined as follows: ```typescript -export interface TypeDefinitionParams - extends TextDocumentPositionParams, WorkDoneProgressParams, - PartialResultParams { +export interface TypeDefinitionParams extends TextDocumentPositionParams, + WorkDoneProgressParams, PartialResultParams { } ``` @@ -4233,10 +5402,9 @@ _Client Capability_: ```typescript export interface ImplementationClientCapabilities { /** - * Whether implementation supports dynamic registration. - * If this is set to `true`, the client supports the new - * `ImplementationRegistrationOptions` return value for the - * corresponding server capability as well. + * Whether implementation supports dynamic registration. If this is set to + * `true` the client supports the new `ImplementationRegistrationOptions` + * return value for the corresponding server capability as well. */ dynamicRegistration?: boolean; @@ -4260,9 +5428,9 @@ export interface ImplementationOptions extends WorkDoneProgressOptions { _Registration Options_: `ImplementationRegistrationOptions` defined as follows: ```typescript -export interface ImplementationRegistrationOptions - extends TextDocumentRegistrationOptions, ImplementationOptions, - StaticRegistrationOptions { +export interface ImplementationRegistrationOptions extends + TextDocumentRegistrationOptions, ImplementationOptions, + StaticRegistrationOptions { } ``` @@ -4309,8 +5477,8 @@ export interface ReferenceOptions extends WorkDoneProgressOptions { _Registration Options_: `ReferenceRegistrationOptions` defined as follows: ```typescript -export interface ReferenceRegistrationOptions - extends TextDocumentRegistrationOptions, ReferenceOptions { +export interface ReferenceRegistrationOptions extends + TextDocumentRegistrationOptions, ReferenceOptions { } ``` @@ -4367,8 +5535,8 @@ export interface DocumentHighlightOptions extends WorkDoneProgressOptions { _Registration Options_: `DocumentHighlightRegistrationOptions` defined as follows: ```typescript -export interface DocumentHighlightRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentHighlightOptions { +export interface DocumentHighlightRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentHighlightOptions { } ``` @@ -4401,7 +5569,7 @@ export interface DocumentHighlight { /** * The highlight kind, default is DocumentHighlightKind.Text. */ - kind?: number; + kind?: DocumentHighlightKind; } /** @@ -4423,6 +5591,8 @@ export namespace DocumentHighlightKind { */ export const Write = 3; } + +export type DocumentHighlightKind = 1 | 2 | 3; ``` * partial result: `DocumentHighlight[]` @@ -4435,6 +5605,8 @@ The document symbol request is sent from the client to the server. The returned - `SymbolInformation[]` which is a flat list of all symbols found in a given text document. Then neither the symbol's location range nor the symbol's container name should be used to infer a hierarchy. - `DocumentSymbol[]` which is a hierarchy of symbols found in a given text document. +Servers should whenever possible return `DocumentSymbol` since it is the richer data structure. + _Client Capability_: * property name (optional): `textDocument.documentSymbol` * property type: `DocumentSymbolClientCapabilities` defined as follows: @@ -4468,6 +5640,28 @@ export interface DocumentSymbolClientCapabilities { * The client supports hierarchical document symbols. */ hierarchicalDocumentSymbolSupport?: boolean; + + /** + * The client supports tags on `SymbolInformation`. Tags are supported on + * `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true. + * Clients supporting tags have to handle unknown tags gracefully. + * + * @since 3.16.0 + */ + tagSupport?: { + /** + * The tags supported by the client. + */ + valueSet: SymbolTag[] + } + + /** + * The client supports an additional label presented in the UI when + * registering a document symbol provider. + * + * @since 3.16.0 + */ + labelSupport?: boolean; } ``` @@ -4477,13 +5671,20 @@ _Server Capability_: ```typescript export interface DocumentSymbolOptions extends WorkDoneProgressOptions { + /** + * A human-readable string that is shown when multiple outlines trees + * are shown for the same document. + * + * @since 3.16.0 - proposed state + */ + label?: string; } ``` _Registration Options_: `DocumentSymbolRegistrationOptions` defined as follows: ```typescript -export interface DocumentSymbolRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentSymbolOptions { +export interface DocumentSymbolRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentSymbolOptions { } ``` @@ -4492,8 +5693,8 @@ _Request_: * params: `DocumentSymbolParams` defined as follows: ```typescript -export interface DocumentSymbolParams - extends WorkDoneProgressParams, PartialResultParams { +export interface DocumentSymbolParams extends WorkDoneProgressParams, + PartialResultParams { /** * The text document. */ @@ -4537,18 +5738,34 @@ export namespace SymbolKind { export const TypeParameter = 26; } +/** + * Symbol tags are extra annotations that tweak the rendering of a symbol. + * + * @since 3.16 + */ +export namespace SymbolTag { + + /** + * Render a symbol as obsolete, usually using a strike-out. + */ + export const Deprecated: 1 = 1; +} + +export type SymbolTag = 1; + + /** * Represents programming constructs like variables, classes, interfaces etc. * that appear in a document. Document symbols can be hierarchical and they - * have two ranges: one that encloses its definition and one that points to - * its most interesting range, for example, the range of an identifier. + * have two ranges: one that encloses its definition and one that points to its + * most interesting range, e.g. the range of an identifier. */ export interface DocumentSymbol { /** - * The name of this symbol. - * Will be displayed in the user interface and therefore must not be - * an empty string or a string only consisting of white spaces. + * The name of this symbol. Will be displayed in the user interface and + * therefore must not be an empty string or a string only consisting of + * white spaces. */ name: string; @@ -4562,23 +5779,31 @@ export interface DocumentSymbol { */ kind: SymbolKind; + /** + * Tags for this document symbol. + * + * @since 3.16.0 + */ + tags?: SymbolTag[]; + /** * Indicates if this symbol is deprecated. + * + * @deprecated Use tags instead */ deprecated?: boolean; /** - * The range enclosing this symbol not including leading/trailing - * whitespace but everything else like comments. - * This information is typically used to determine if the client's cursor - * is inside the symbol to reveal in the symbol in the UI. + * The range enclosing this symbol not including leading/trailing whitespace + * but everything else like comments. This information is typically used to + * determine if the clients cursor is inside the symbol to reveal in the + * symbol in the UI. */ range: Range; /** - * The range that should be selected and revealed when this symbol - * is being picked, for example, the name of a function. - * Must be contained by the `range`. + * The range that should be selected and revealed when this symbol is being + * picked, e.g. the name of a function. Must be contained by the `range`. */ selectionRange: Range; @@ -4603,8 +5828,17 @@ export interface SymbolInformation { */ kind: SymbolKind; + /** + * Tags for this completion item. + * + * @since 3.16.0 + */ + tags?: SymbolTag[]; + /** * Indicates if this symbol is deprecated. + * + * @deprecated Use tags instead */ deprecated?: boolean; @@ -4636,9 +5870,11 @@ export interface SymbolInformation { #### Code Action Request (:leftwards_arrow_with_hook:) -The code action request is sent from the client to the server to compute commands for a given text document and range. These commands are typically code fixes to either fix problems or to beautify/refactor code. The result of a `textDocument/codeAction` request is an array of `Command` literals which are typically presented in the user interface. To ensure that a server is useful in many clients the commands specified in a code actions should be handled by the server and not by the client (see `workspace/executeCommand` and `ServerCapabilities.executeCommandProvider`). If the client supports providing edits with a code action then the mode should be used. +The code action request is sent from the client to the server to compute commands for a given text document and range. These commands are typically code fixes to either fix problems or to beautify/refactor code. The result of a `textDocument/codeAction` request is an array of `Command` literals which are typically presented in the user interface. To ensure that a server is useful in many clients the commands specified in a code actions should be handled by the server and not by the client (see `workspace/executeCommand` and `ServerCapabilities.executeCommandProvider`). If the client supports providing edits with a code action then that mode should be used. -When the command is selected the server should be contacted again (via the `workspace/executeCommand`) request to execute the command. +*Since version 3.16.0:* a client can offer a server to delay the computation of code action properties during a 'textDocument/codeAction' request: + +This is useful for cases where it is expensive to compute the value of a property (for example the `edit` property). Clients signal this through the `codeAction.resolveSupport` capability which lists all properties a client can resolve lazily. The server capability `codeActionProvider.resolveProvider` signals that a server will offer a `codeAction/resolve` route. To help servers to uniquely identify a code action in the resolve request, a code action literal can optional carry a data property. This is also guarded by an additional client capability `codeAction.dataSupport`. In general, a client should offer data support if it offers resolve support. It should also be noted that servers shouldn't alter existing attributes of a code action in a codeAction/resolve request. > *Since version 3.8.0:* support for CodeAction literals to enable the following scenarios: @@ -4683,9 +5919,51 @@ export interface CodeActionClientCapabilities { /** * Whether code action supports the `isPreferred` property. + * * @since 3.15.0 */ isPreferredSupport?: boolean; + + /** + * Whether code action supports the `disabled` property. + * + * @since 3.16.0 - proposed state + */ + disabledSupport?: boolean; + + /** + * Whether code action supports the `data` property which is + * preserved between a `textDocument/codeAction` and a + * `codeAction/resolve` request. + * + * @since 3.16.0 - proposed state + */ + dataSupport?: boolean; + + + /** + * Whether the client supports resolving additional code action + * properties via a separate `codeAction/resolve` request. + * + * @since 3.16.0 - proposed state + */ + resolveSupport?: { + /** + * The properties that a client can resolve lazily. + */ + properties: string[]; + }; + + /** + * Whether th client honors the change annotations in + * text edits and resource operations returned via the + * `CodeAction#edit` property by for example presenting + * the workspace edit in the user interface and asking + * for confirmation. + * + * @since 3.16.0 - proposed state + */ + honorsChangeAnnotations?: boolean; } ``` @@ -4702,13 +5980,21 @@ export interface CodeActionOptions extends WorkDoneProgressOptions { * or the server may list out every specific kind they provide. */ codeActionKinds?: CodeActionKind[]; + + /** + * The server provides support to resolve additional + * information for a code action. + * + * @since 3.16.0 + */ + resolveProvider?: boolean; } ``` _Registration Options_: `CodeActionRegistrationOptions` defined as follows: ```typescript -export interface CodeActionRegistrationOptions - extends TextDocumentRegistrationOptions, CodeActionOptions { +export interface CodeActionRegistrationOptions extends + TextDocumentRegistrationOptions, CodeActionOptions { } ``` @@ -4720,8 +6006,8 @@ _Request_: /** * Params for the CodeActionRequest */ -export interface CodeActionParams - extends WorkDoneProgressParams, PartialResultParams { +export interface CodeActionParams extends WorkDoneProgressParams, + PartialResultParams { /** * The document in which the command was invoked. */ @@ -4744,8 +6030,8 @@ export interface CodeActionParams * Kinds are a hierarchical list of identifiers separated by `.`, * e.g. `"refactor.extract.function"`. * - * The set of kinds is open and the client needs to announce the kinds it - * supports to the server during initialization. + * The set of kinds is open and client needs to announce the kinds it supports + * to the server during initialization. */ export type CodeActionKind = string; @@ -4816,10 +6102,11 @@ export namespace CodeActionKind { export const Source: CodeActionKind = 'source'; /** - * Base kind for an organize imports source action `source.organizeImports`. + * Base kind for an organize imports source action: + * `source.organizeImports`. */ - export const SourceOrganizeImports: CodeActionKind - = 'source.organizeImports'; + export const SourceOrganizeImports: CodeActionKind = + 'source.organizeImports'; } /** @@ -4829,19 +6116,19 @@ export namespace CodeActionKind { export interface CodeActionContext { /** * An array of diagnostics known on the client side overlapping the range - * provided to the `textDocument/codeAction` request. - * They are provided so that the server knows which errors are currently - * presented to the user for the given range. There is no guarantee that - * these accurately reflect the error state of the resource. - * The primary parameter to compute code actions is the provided range. + * provided to the `textDocument/codeAction` request. They are provided so + * that the server knows which errors are currently presented to the user + * for the given range. There is no guarantee that these accurately reflect + * the error state of the resource. The primary parameter + * to compute code actions is the provided range. */ diagnostics: Diagnostic[]; /** * Requested kind of actions to return. * - * Actions not of this kind are filtered out by the client before - * being shown, so servers can omit computing them. + * Actions not of this kind are filtered out by the client before being + * shown. So servers can omit computing them. */ only?: CodeActionKind[]; } @@ -4852,12 +6139,11 @@ _Response_: ```typescript /** - * A code action represents a change that can be performed in code. - * For example, to fix a problem or to refactor code. + * A code action represents a change that can be performed in code, e.g. to fix + * a problem or to refactor code. * - * A CodeAction must set either `edit` and/or a `command`. - * If both are supplied, the `edit` is applied first, then the `command` - * is executed. + * A CodeAction must set either `edit` and/or a `command`. If both are supplied, + * the `edit` is applied first, then the `command` is executed. */ export interface CodeAction { @@ -4879,19 +6165,47 @@ export interface CodeAction { diagnostics?: Diagnostic[]; /** - * Marks this as a preferred action. - * Preferred actions are used by the `auto fix` command and can be - * targeted by keybindings. + * Marks this as a preferred action. Preferred actions are used by the + * `auto fix` command and can be targeted by keybindings. * * A quick fix should be marked preferred if it properly addresses the - * underlying error. - * A refactoring should be marked preferred if it is the most reasonable - * choice of actions to take. + * underlying error. A refactoring should be marked preferred if it is the + * most reasonable choice of actions to take. * * @since 3.15.0 */ isPreferred?: boolean; + /** + * Marks that the code action cannot currently be applied. + * + * Clients should follow the following guidelines regarding disabled code + * actions: + * + * - Disabled code actions are not shown in automatic lightbulbs code + * action menus. + * + * - Disabled actions are shown as faded out in the code action menu when + * the user request a more specific type of code action, such as + * refactorings. + * + * - If the user has a keybinding that auto applies a code action and only + * a disabled code actions are returned, the client should show the user + * an error message with `reason` in the editor. + * + * @since 3.16.0 + */ + disabled?: { + + /** + * Human readable description of why the code action is currently + * disabled. + * + * This is displayed in the code actions UI. + */ + reason: string; + }; + /** * The workspace edit this code action performs. */ @@ -4903,14 +6217,57 @@ export interface CodeAction { * executed and then the command. */ command?: Command; + + /** + * A data entry field that is preserved on a code action between + * a `textDocument/codeAction` and a `codeAction/resolve` request. + * + * @since 3.16.0 - proposed state + */ + data?: any } ``` * partial result: `(Command | CodeAction)[]` * error: code and message set in case an exception happens during the code action request. +#### Code Action Resolve Request (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The request is sent from the client to the server to resolve additional information for a given code action. This is usually used to compute +the `edit` property of a code action to avoid its unnecessary computation during the `textDocument/codeAction` request. + +Consider the clients announces the `edit` property as a property that can be resolved lazy using the client capability + +```typescript +textDocument.codeAction.resolveSupport = { properties: ['edit']}; +``` + +then a code action + +```typescript +{ + "title": "Do Foo" +} +``` + +needs to be resolved using the `codeAction/resolve` request before it can be applied. + +_Client Capability_: +* property name (optional): `textDocument.codeAction.resolveSupport` +* property type: `{ properties: string[]; }` + +_Request_: +* method: 'codeAction/resolve' +* params: `CodeAction` + +_Response_: +* result: `CodeAction` +* error: code and message set in case an exception happens during the completion resolve request. + #### Code Lens Request (:leftwards_arrow_with_hook:) -The CodeLens request is sent from the client to the server to compute CodeLens for a given text document. +The code lens request is sent from the client to the server to compute code lenses for a given text document. _Client Capability_: * property name (optional): `textDocument.codeLens` @@ -4919,7 +6276,7 @@ _Client Capability_: ```typescript export interface CodeLensClientCapabilities { /** - * Whether CodeLens supports dynamic registration. + * Whether code lens supports dynamic registration. */ dynamicRegistration?: boolean; } @@ -4940,8 +6297,8 @@ export interface CodeLensOptions extends WorkDoneProgressOptions { _Registration Options_: `CodeLensRegistrationOptions` defined as follows: ```typescript -export interface CodeLensRegistrationOptions - extends TextDocumentRegistrationOptions, CodeLensOptions { +export interface CodeLensRegistrationOptions extends + TextDocumentRegistrationOptions, CodeLensOptions { } ``` @@ -4952,7 +6309,7 @@ _Request_: ```typescript interface CodeLensParams extends WorkDoneProgressParams, PartialResultParams { /** - * The document to request CodeLens for. + * The document to request code lens for. */ textDocument: TextDocumentIdentifier; } @@ -4963,37 +6320,38 @@ _Response_: ```typescript /** - * A CodeLense represents a command that should be shown along with + * A code lens represents a command that should be shown along with * source text, like the number of references, a way to run tests, etc. * - * A CodeLens is _unresolved_ when no command is associated to it. - * For performance reasons, the creation of a CodeLens and resolving should - * be done in two stages. + * A code lens is _unresolved_ when no command is associated to it. For + * performance reasons the creation of a code lens and resolving should be done + * in two stages. */ interface CodeLens { /** - * The range in which the CodeLens is valid. Should only span a single line. + * The range in which this code lens is valid. Should only span a single + * line. */ range: Range; /** - * The command this CodeLens represents. + * The command this code lens represents. */ command?: Command; /** - * A data entry field that is preserved on a CodeLens item between - * a CodeLens and a CodeLens resolve request. + * A data entry field that is preserved on a code lens item between + * a code lens and a code lens resolve request. */ data?: any } ``` * partial result: `CodeLens[]` -* error: code and message set in case an exception happens during the CodeLens request. +* error: code and message set in case an exception happens during the code lens request. #### Code Lens Resolve Request (:leftwards_arrow_with_hook:) -The CodeLens resolve request is sent from the client to the server to resolve the command for a given CodeLens item. +The code lens resolve request is sent from the client to the server to resolve the command for a given code lens item. _Request_: * method: 'codeLens/resolve' @@ -5001,7 +6359,43 @@ _Request_: _Response_: * result: `CodeLens` -* error: code and message set in case an exception happens during the CodeLens resolve request. +* error: code and message set in case an exception happens during the code lens resolve request. + +#### Code Lens Refresh Request (:arrow_right_hook:) + +> *Since version 3.16.0* + +The `workspace/codeLens/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the code lenses currently shown in editors. As a result the client should ask the server to recompute the code lenses for these editors. This is useful if a server detects a configuration change which requires a re-calculation of all code lenses. Note that the client still has the freedom to delay the re-calculation of the code lenses if for example an editor is currently not visible. + +_Client Capability_: + +* property name (optional): `workspace.codeLens` +* property type: `CodeLensWorkspaceClientCapabilities` defined as follows: + +```typescript +export interface CodeLensWorkspaceClientCapabilities { + /** + * Whether the client implementation supports a refresh request sent from the + * server to the client. + * + * Note that this event is global and will force the client to refresh all + * code lenses currently shown. It should be used with absolute care and is + * useful for situation where a server for example detect a project wide + * change that requires such a calculation. + */ + refreshSupport?: boolean; +} +``` + +_Request_: + +* method: `workspace/codeLens/refresh` +* params: none + +_Response_: + +* result: void +* error: code and message set in case an exception happens during the 'workspace/codeLens/refresh' request #### Document Link Request (:leftwards_arrow_with_hook:) @@ -5042,8 +6436,8 @@ export interface DocumentLinkOptions extends WorkDoneProgressOptions { _Registration Options_: `DocumentLinkRegistrationOptions` defined as follows: ```typescript -export interface DocumentLinkRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentLinkOptions { +export interface DocumentLinkRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentLinkOptions { } ``` @@ -5052,8 +6446,8 @@ _Request_: * params: `DocumentLinkParams` defined as follows: ```typescript -interface DocumentLinkParams - extends WorkDoneProgressParams, PartialResultParams { +interface DocumentLinkParams extends WorkDoneProgressParams, + PartialResultParams { /** * The document to provide document links for. */ @@ -5066,8 +6460,8 @@ _Response_: ```typescript /** - * A document link is a range in a text document that links to an internal - * or external resource, like another text document or a web site. + * A document link is a range in a text document that links to an internal or + * external resource, like another text document or a web site. */ interface DocumentLink { /** @@ -5083,11 +6477,10 @@ interface DocumentLink { /** * The tooltip text when you hover over this link. * - * If a tooltip is provided, it will be displayed in a string that - * includes instructions on how to trigger the link, - * such as `{0} (ctrl + click)`. - * The specific instructions vary depending on OS, user settings, - * and localization. + * If a tooltip is provided, is will be displayed in a string that includes + * instructions on how to trigger the link, such as `{0} (ctrl + click)`. + * The specific instructions vary depending on OS, user settings, and + * localization. * * @since 3.15.0 */ @@ -5149,9 +6542,9 @@ export interface DocumentColorOptions extends WorkDoneProgressOptions { _Registration Options_: `DocumentColorRegistrationOptions` defined as follows: ```typescript -export interface DocumentColorRegistrationOptions - extends TextDocumentRegistrationOptions, StaticRegistrationOptions, - DocumentColorOptions { +export interface DocumentColorRegistrationOptions extends + TextDocumentRegistrationOptions, StaticRegistrationOptions, + DocumentColorOptions { } ``` @@ -5161,8 +6554,8 @@ _Request_: * params: `DocumentColorParams` defined as follows ```typescript -interface DocumentColorParams - extends WorkDoneProgressParams, PartialResultParams { +interface DocumentColorParams extends WorkDoneProgressParams, + PartialResultParams { /** * The text document. */ @@ -5194,22 +6587,22 @@ interface Color { /** * The red component of this color in the range [0-1]. */ - readonly red: number; + readonly red: decimal; /** * The green component of this color in the range [0-1]. */ - readonly green: number; + readonly green: decimal; /** * The blue component of this color in the range [0-1]. */ - readonly blue: number; + readonly blue: decimal; /** * The alpha component of this color in the range [0-1]. */ - readonly alpha: number; + readonly alpha: decimal; } ``` * partial result: `ColorInformation[]` @@ -5231,8 +6624,8 @@ _Request_: * params: `ColorPresentationParams` defined as follows ```typescript -interface ColorPresentationParams - extends WorkDoneProgressParams, PartialResultParams { +interface ColorPresentationParams extends WorkDoneProgressParams, + PartialResultParams { /** * The text document. */ @@ -5257,22 +6650,20 @@ _Response_: interface ColorPresentation { /** * The label of this color presentation. It will be shown on the color - * picker header. - * By default, this is also the text that is inserted when selecting - * this color presentation. + * picker header. By default this is also the text that is inserted when + * selecting this color presentation. */ label: string; /** * An [edit](#TextEdit) which is applied to a document when selecting - * this presentation for the color. - * When `falsy`, the [label](#ColorPresentation.label) is used. + * this presentation for the color. When `falsy` the + * [label](#ColorPresentation.label) is used. */ textEdit?: TextEdit; /** - * An optional array of additional [text edits](#TextEdit) that are - * applied when selecting this color presentation. - * Edits must not overlap with the main [edit](#ColorPresentation.textEdit) - * nor with themselves. + * An optional array of additional [text edits](#TextEdit) that are applied + * when selecting this color presentation. Edits must not overlap with the + * main [edit](#ColorPresentation.textEdit) nor with themselves. */ additionalTextEdits?: TextEdit[]; } @@ -5309,8 +6700,8 @@ export interface DocumentFormattingOptions extends WorkDoneProgressOptions { _Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows: ```typescript -export interface DocumentFormattingRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentFormattingOptions { +export interface DocumentFormattingRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentFormattingOptions { } ``` @@ -5338,7 +6729,7 @@ interface FormattingOptions { /** * Size of a tab in spaces. */ - tabSize: number; + tabSize: uinteger; /** * Prefer spaces over tabs. @@ -5369,7 +6760,7 @@ interface FormattingOptions { /** * Signature for further properties. */ - [key: string]: boolean | number | string; + [key: string]: boolean | integer | string; } ``` @@ -5399,15 +6790,15 @@ _Server Capability_: * property type: `boolean | DocumentRangeFormattingOptions` where `DocumentRangeFormattingOptions` is defined as follows: ```typescript -export interface DocumentRangeFormattingOptions - extends WorkDoneProgressOptions { +export interface DocumentRangeFormattingOptions extends + WorkDoneProgressOptions { } ``` _Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows: ```typescript -export interface DocumentRangeFormattingRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentRangeFormattingOptions { +export interface DocumentRangeFormattingRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentRangeFormattingOptions { } ``` @@ -5475,8 +6866,8 @@ export interface DocumentOnTypeFormattingOptions { _Registration Options_: `DocumentOnTypeFormattingRegistrationOptions` defined as follows: ```typescript -export interface DocumentOnTypeFormattingRegistrationOptions - extends TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions { +export interface DocumentOnTypeFormattingRegistrationOptions extends + TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions { } ``` @@ -5511,6 +6902,13 @@ _Client Capability_: * property type: `RenameClientCapabilities` defined as follows: ```typescript +export namespace PrepareSupportDefaultBehavior { + /** + * The client's default behavior is to select the identifier + * according the to language's syntax rule. + */ + export const Identifier: 1 = 1; +} export interface RenameClientCapabilities { /** * Whether rename supports dynamic registration. @@ -5524,6 +6922,28 @@ export interface RenameClientCapabilities { * @since version 3.12.0 */ prepareSupport?: boolean; + + /** + * Client supports the default behavior result + * (`{ defaultBehavior: boolean }`). + * + * The value indicates the default behavior used by the + * client. + * + * @since version 3.16.0 + */ + prepareSupportDefaultBehavior?: PrepareSupportDefaultBehavior; + + /** + * Whether th client honors the change annotations in + * text edits and resource operations returned via the + * rename request's workspace edit by for example presenting + * the workspace edit in the user interface and asking + * for confirmation. + * + * @since 3.16.0 - proposed state + */ + honorsChangeAnnotations?: boolean; } ``` @@ -5544,8 +6964,8 @@ export interface RenameOptions extends WorkDoneProgressOptions { _Registration Options_: `RenameRegistrationOptions` defined as follows: ```typescript -export interface RenameRegistrationOptions - extends TextDocumentRegistrationOptions, RenameOptions { +export interface RenameRegistrationOptions extends + TextDocumentRegistrationOptions, RenameOptions { } ``` @@ -5554,8 +6974,8 @@ _Request_: * params: `RenameParams` defined as follows ```typescript -interface RenameParams - extends TextDocumentPositionParams, WorkDoneProgressParams { +interface RenameParams extends TextDocumentPositionParams, + WorkDoneProgressParams { /** * The new name of the symbol. If the given name is not valid the * request must return a [ResponseError](#ResponseError) with an @@ -5584,7 +7004,7 @@ export interface PrepareRenameParams extends TextDocumentPositionParams { ``` _Response_: -* result: [`Range`](#range) \| `{ range: Range, placeholder: string }` \| `null` describing the range of the string to rename and optionally a placeholder text of the string content to be renamed. If `null` is returned then it is deemed that a 'textDocument/rename' request is not valid at the given position. +* result: `Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null` describing a [`Range`](#range) of the string to rename and optionally a placeholder text of the string content to be renamed. If `{ defaultBehavior: boolean }` is returned (since 3.16) the rename position is valid and the client should use its default behavior to compute the rename range. If `null` is returned then it is deemed that a 'textDocument/rename' request is not valid at the given position. * error: code and message set in case the element can't be renamed. Clients should show the information in their user interface. #### Folding Range Request (:leftwards_arrow_with_hook:) @@ -5600,23 +7020,22 @@ _Client Capability_: ```typescript export interface FoldingRangeClientCapabilities { /** - * Whether the implementation supports dynamic registration for - * folding range providers. - * If this is set to `true`, the client supports the new + * Whether implementation supports dynamic registration for folding range + * providers. If this is set to `true` the client supports the new * `FoldingRangeRegistrationOptions` return value for the corresponding * server capability as well. */ dynamicRegistration?: boolean; /** - * The maximum number of folding ranges that the client prefers to - * receive per document. - * The value serves as a hint, servers are free to follow the limit. + * The maximum number of folding ranges that the client prefers to receive + * per document. The value serves as a hint, servers are free to follow the + * limit. */ - rangeLimit?: number; + rangeLimit?: uinteger; /** * If set, the client signals that it only supports folding complete lines. - * If set, the client will ignore specified `startCharacter` and - * `endCharacter` properties in a FoldingRange. + * If set, client will ignore specified `startCharacter` and `endCharacter` + * properties in a FoldingRange. */ lineFoldingOnly?: boolean; } @@ -5633,9 +7052,9 @@ export interface FoldingRangeOptions extends WorkDoneProgressOptions { _Registration Options_: `FoldingRangeRegistrationOptions` defined as follows: ```typescript -export interface FoldingRangeRegistrationOptions - extends TextDocumentRegistrationOptions, FoldingRangeOptions, - StaticRegistrationOptions { +export interface FoldingRangeRegistrationOptions extends + TextDocumentRegistrationOptions, FoldingRangeOptions, + StaticRegistrationOptions { } ``` @@ -5645,8 +7064,8 @@ _Request_: * params: `FoldingRangeParams` defined as follows ```typescript -export interface FoldingRangeParams - extends WorkDoneProgressParams, PartialResultParams { +export interface FoldingRangeParams extends WorkDoneProgressParams, + PartialResultParams { /** * The text document. */ @@ -5677,38 +7096,43 @@ export enum FoldingRangeKind { } /** - * Represents a folding range. + * Represents a folding range. To be valid, start and end line must be bigger + * than zero and smaller than the number of lines in the document. Clients + * are free to ignore invalid ranges. */ export interface FoldingRange { /** - * The zero-based line number from where the folded range starts. + * The zero-based start line of the range to fold. The folded area starts + * after the line's last character. To be valid, the end must be zero or + * larger and smaller than the number of lines in the document. */ - startLine: number; + startLine: uinteger; /** - * The zero-based character offset from where the folded range starts. - * If not defined, defaults to the length of the start line. + * The zero-based character offset from where the folded range starts. If + * not defined, defaults to the length of the start line. */ - startCharacter?: number; + startCharacter?: uinteger; /** - * The zero-based line number where the folded range ends. + * The zero-based end line of the range to fold. The folded area ends with + * the line's last character. To be valid, the end must be zero or larger + * and smaller than the number of lines in the document. */ - endLine: number; + endLine: uinteger; /** - * The zero-based character offset before the folded range ends. - * If not defined, defaults to the length of the end line. + * The zero-based character offset before the folded range ends. If not + * defined, defaults to the length of the end line. */ - endCharacter?: number; + endCharacter?: uinteger; /** * Describes the kind of the folding range such as `comment` or `region`. - * The kind is used to categorize folding ranges and used by commands - * like 'Fold all comments'. - * See [FoldingRangeKind](#FoldingRangeKind) for an enumeration of - * standardized kinds. + * The kind is used to categorize folding ranges and used by commands like + * 'Fold all comments'. See [FoldingRangeKind](#FoldingRangeKind) for an + * enumeration of standardized kinds. */ kind?: string; } @@ -5734,9 +7158,8 @@ _Client Capability_: ```typescript export interface SelectionRangeClientCapabilities { /** - * Whether implementation supports dynamic registration for selection - * range providers. - * If set to `true`, the client supports the new + * Whether implementation supports dynamic registration for selection range + * providers. If this is set to `true` the client supports the new * `SelectionRangeRegistrationOptions` return value for the corresponding * server capability as well. */ @@ -5755,20 +7178,20 @@ export interface SelectionRangeOptions extends WorkDoneProgressOptions { _Registration Options_: `SelectionRangeRegistrationOptions` defined as follows: ```typescript -export interface SelectionRangeRegistrationOptions - extends SelectionRangeOptions, TextDocumentRegistrationOptions, - StaticRegistrationOptions { +export interface SelectionRangeRegistrationOptions extends + SelectionRangeOptions, TextDocumentRegistrationOptions, + StaticRegistrationOptions { } ``` _Request_: * method: 'textDocument/selectionRange' -* params: `SelectionRangeParams` defined as follows +* params: `SelectionRangeParams` defined as follows: ```typescript -export interface SelectionRangeParams - extends WorkDoneProgressParams, PartialResultParams { +export interface SelectionRangeParams extends WorkDoneProgressParams, + PartialResultParams { /** * The text document. */ @@ -5782,27 +7205,884 @@ export interface SelectionRangeParams ``` _Response_: + * result: `SelectionRange[] | null` defined as follows: ```typescript export interface SelectionRange { - /** - * The [range](#Range) of this selection range. - */ - range: Range; - - /** - * The parent selection range containing this range. - * Therefore `parent.range` must - * contain `this.range`. - */ - parent?: SelectionRange; + /** + * The [range](#Range) of this selection range. + */ + range: Range; + /** + * The parent selection range containing this range. Therefore + * `parent.range` must contain `this.range`. + */ + parent?: SelectionRange; } ``` * partial result: `SelectionRange[]` * error: code and message set in case an exception happens during the 'textDocument/selectionRange' request +#### Prepare Call Hierarchy Request (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The call hierarchy request is sent from the client to the server to return a call hierarchy for the language element of given text document positions. The call hierarchy requests are executed in two steps: + + 1. first a call hierarchy item is resolved for the given text document position + 1. for a call hierarchy item the incoming or outgoing call hierarchy items are resolved. + +_Client Capability_: + +* property name (optional): `textDocument.callHierarchy` +* property type: `CallHierarchyClientCapabilities` defined as follows: + +```typescript +interface CallHierarchyClientCapabilities { + /** + * Whether implementation supports dynamic registration. If this is set to + * `true` the client supports the new `(TextDocumentRegistrationOptions & + * StaticRegistrationOptions)` return value for the corresponding server + * capability as well. + */ + dynamicRegistration?: boolean; +} +``` + +_Server Capability_: + +* property name (optional): `callHierarchyProvider` +* property type: `boolean | CallHierarchyOptions | CallHierarchyRegistrationOptions` where `CallHierarchyOptions` is defined as follows: + +```typescript +export interface CallHierarchyOptions extends WorkDoneProgressOptions { +} +``` + +_Registration Options_: `CallHierarchyRegistrationOptions` defined as follows: + +```typescript +export interface CallHierarchyRegistrationOptions extends + TextDocumentRegistrationOptions, CallHierarchyOptions, + StaticRegistrationOptions { +} +``` + +_Request_: + +* method: 'textDocument/prepareCallHierarchy' +* params: `CallHierarchyPrepareParams` defined as follows: + +```typescript +export interface CallHierarchyPrepareParams extends TextDocumentPositionParams, + WorkDoneProgressParams { +} +``` + +_Response_: + +* result: `CallHierarchyItem[] | null` defined as follows: + +```typescript +export interface CallHierarchyItem { + /** + * The name of this item. + */ + name: string; + + /** + * The kind of this item. + */ + kind: SymbolKind; + + /** + * Tags for this item. + */ + tags?: SymbolTag[]; + + /** + * More detail for this item, e.g. the signature of a function. + */ + detail?: string; + + /** + * The resource identifier of this item. + */ + uri: DocumentUri; + + /** + * The range enclosing this symbol not including leading/trailing whitespace + * but everything else, e.g. comments and code. + */ + range: Range; + + /** + * The range that should be selected and revealed when this symbol is being + * picked, e.g. the name of a function. Must be contained by the + * [`range`](#CallHierarchyItem.range). + */ + selectionRange: Range; + + /** + * A data entry field that is preserved between a call hierarchy prepare and + * incoming calls or outgoing calls requests. + */ + data?: unknown; +} +``` + +* error: code and message set in case an exception happens during the 'textDocument/prepareCallHierarchy' request + +#### Call Hierarchy Incoming Calls (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The request is sent from the client to the server to resolve incoming calls for a given call hierarchy item. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareCallHierarchy` request](#textDocument_prepareCallHierarchy). + +_Request_: + +* method: 'callHierarchy/incomingCalls' +* params: `CallHierarchyIncomingCallsParams` defined as follows: + +```typescript +export interface CallHierarchyIncomingCallsParams extends + WorkDoneProgressParams, PartialResultParams { + item: CallHierarchyItem; +} +``` + +_Response_: + +* result: `CallHierarchyIncomingCall[] | null` defined as follows: + +```typescript +export interface CallHierarchyIncomingCall { + + /** + * The item that makes the call. + */ + from: CallHierarchyItem; + + /** + * The ranges at which the calls appear. This is relative to the caller + * denoted by [`this.from`](#CallHierarchyIncomingCall.from). + */ + fromRanges: Range[]; +} +``` + +* partial result: `CallHierarchyIncomingCall[]` +* error: code and message set in case an exception happens during the 'callHierarchy/incomingCalls' request + +#### Call Hierarchy Outgoing Calls (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The request is sent from the client to the server to resolve outgoing calls for a given call hierarchy item. The request doesn't define its own client and server capabilities. It is only issued if a server registers for the [`textDocument/prepareCallHierarchy` request](#textDocument_prepareCallHierarchy). + +_Request_: + +* method: 'callHierarchy/outgoingCalls' +* params: `CallHierarchyOutgoingCallsParams` defined as follows: + +```typescript +export interface CallHierarchyOutgoingCallsParams extends + WorkDoneProgressParams, PartialResultParams { + item: CallHierarchyItem; +} +``` + +_Response_: + +* result: `CallHierarchyOutgoingCall[] | null` defined as follows: + +```typescript +export interface CallHierarchyOutgoingCall { + + /** + * The item that is called. + */ + to: CallHierarchyItem; + + /** + * The range at which this item is called. This is the range relative to + * the caller, e.g the item passed to `callHierarchy/outgoingCalls` request. + */ + fromRanges: Range[]; +} +``` + +* partial result: `CallHierarchyOutgoingCall[]` +* error: code and message set in case an exception happens during the 'callHierarchy/outgoingCalls' request + +#### Semantic Tokens (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The request is sent from the client to the server to resolve semantic tokens for a given file. Semantic tokens are used to add additional color information to a file that depends on language specific symbol information. A semantic token request usually produces a large result. The protocol therefore supports encoding tokens with numbers. In addition optional support for deltas is available. + +_General Concepts_ + +Tokens are represented using one token type combined with n token modifiers. A token type is something like `class` or `function` and token modifiers are like `static` or `async`. The protocol defines a set of token types and modifiers but clients are allowed to extend these and announce the values they support in the corresponding client capability. The predefined values are: + +```typescript +export enum SemanticTokenTypes { + namespace = 'namespace', + /** + * Represents a generic type. Acts as a fallback for types which + * can't be mapped to a specific type like class or enum. + */ + type = 'type', + class = 'class', + enum = 'enum', + interface = 'interface', + struct = 'struct', + typeParameter = 'typeParameter', + parameter = 'parameter', + variable = 'variable', + property = 'property', + enumMember = 'enumMember', + event = 'event', + function = 'function', + method = 'method', + macro = 'macro', + keyword = 'keyword', + modifier = 'modifier', + comment = 'comment', + string = 'string', + number = 'number', + regexp = 'regexp', + operator = 'operator' +} + +export enum SemanticTokenModifiers { + declaration = 'declaration', + definition = 'definition', + readonly = 'readonly', + static = 'static', + deprecated = 'deprecated', + abstract = 'abstract', + async = 'async', + modification = 'modification', + documentation = 'documentation', + defaultLibrary = 'defaultLibrary' +} +``` + +The protocol defines an additional token format capability to allow future extensions of the format. The only format that is currently specified is `relative` expressing that the tokens are described using relative positions (see Integer Encoding for Tokens below). + +```typescript +export namespace TokenFormat { + export const Relative: 'relative' = 'relative'; +} + +export type TokenFormat = 'relative'; +``` + +_Integer Encoding for Tokens_ + +On the capability level types and modifiers are defined using strings. However the real encoding happens using numbers. The server therefore needs to let the client know which numbers it is using for which types and modifiers. They do so using a legend, which is defined as follows: + +```typescript +export interface SemanticTokensLegend { + /** + * The token types a server uses. + */ + tokenTypes: string[]; + + /** + * The token modifiers a server uses. + */ + tokenModifiers: string[]; +} +``` + +Token types are looked up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Since a token type can have n modifiers, multiple token modifiers can be set by using bit flags, +so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because bits 0 and 1 are set. + +There are different ways how the position of a token can be expressed in a file. Absolute positions or relative positions. The protocol for the token format `relative` uses relative positions, because most tokens remain stable relative to each other when edits are made in a file. This simplifies the computation of a delta if a server supports it. So each token is represented using 5 integers. A specific token `i` in the file consists of the following array indices: + +- at index `5*i` - `deltaLine`: token line number, relative to the previous token +- at index `5*i+1` - `deltaStart`: token start character, relative to the previous token (relative to 0 or the previous token's start if they are on the same line) +- at index `5*i+2` - `length`: the length of the token. +- at index `5*i+3` - `tokenType`: will be looked up in `SemanticTokensLegend.tokenTypes`. We currently ask that `tokenType` < 65536. +- at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` + +Whether a token can span multiple lines is defined by the client capability `multilineTokenSupport`. The client capability `overlappingTokenSupport` defines whether tokens can overlap each other. + +Lets look at a concrete example which uses single line tokens without overlaps for encoding a file with 3 tokens in a number array. We start with absolute positions to demonstrate how they can easily be transformed into relative positions: + +```typescript +{ line: 2, startChar: 5, length: 3, tokenType: "property", + tokenModifiers: ["private", "static"] +}, +{ line: 2, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] }, +{ line: 5, startChar: 2, length: 7, tokenType: "class", tokenModifiers: [] } +``` + +First of all, a legend must be devised. This legend must be provided up-front on registration and capture all possible token types and modifiers. For the example we use this legend: + +```typescript +{ + tokenTypes: ['property', 'type', 'class'], + tokenModifiers: ['private', 'static'] +} +``` + +The first transformation step is to encode `tokenType` and `tokenModifiers` as integers using the legend. As said, token types are looked up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Multiple token modifiers can be set by using bit flags, so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because bits 0 and 1 are set. Using this legend, the tokens now are: + +```typescript +{ line: 2, startChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 }, +{ line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 }, +{ line: 5, startChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 } +``` + +The next step is to represent each token relative to the previous token in the file. In this case, the second token is on the same line as the first token, so the `startChar` of the second token is made relative to the `startChar` of the first token, so it will be `10 - 5`. The third token is on a different line than the second token, so the `startChar` of the third token will not be altered: + +```typescript +{ deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 }, +{ deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 }, +{ deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 } +``` + +Finally, the last step is to inline each of the 5 fields for a token in a single array, which is a memory friendly representation: + +```typescript +// 1st token, 2nd token, 3rd token +[ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] +``` + +Now assume that the user types a new empty line at the beginning of the file which results in the following tokens in the file: + +```typescript +{ line: 3, startChar: 5, length: 3, tokenType: "property", + tokenModifiers: ["private", "static"] +}, +{ line: 3, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] }, +{ line: 6, startChar: 2, length: 7, tokenType: "class", tokenModifiers: [] } +``` + +Running the same transformations as above will result in the following number array: + +```typescript +// 1st token, 2nd token, 3rd token +[ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0] +``` + +The delta is now expressed on these number arrays without any form of interpretation what these numbers mean. This is comparable to the text document edits send from the server to the client to modify the content of a file. Those are character based and don't make any assumption about the meaning of the characters. So `[ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ]` can be transformed into `[ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0]` using the following edit description: `{ start: 0, deleteCount: 1, data: [3] }` which tells the client to simply replace the first number (e.g. `2`) in the array with `3`. + + +_Client Capability_: + +The following client capabilities are defined for semantic token requests sent from the client to the server: + +* property name (optional): `textDocument.semanticTokens` +* property type: `SemanticTokensClientCapabilities` defined as follows: + +```typescript +interface SemanticTokensClientCapabilities { + /** + * Whether implementation supports dynamic registration. If this is set to + * `true` the client supports the new `(TextDocumentRegistrationOptions & + * StaticRegistrationOptions)` return value for the corresponding server + * capability as well. + */ + dynamicRegistration?: boolean; + + /** + * Which requests the client supports and might send to the server. + */ + requests: { + /** + * The client will send the `textDocument/semanticTokens/range` request + * if the server provides a corresponding handler. + */ + range?: boolean | { + }; + + /** + * The client will send the `textDocument/semanticTokens/full` request + * if the server provides a corresponding handler. + */ + full?: boolean | { + /** + * The client will send the `textDocument/semanticTokens/full/delta` + * request if the server provides a corresponding handler. + */ + delta?: boolean + } + } + + /** + * The token types that the client supports. + */ + tokenTypes: string[]; + + /** + * The token modifiers that the client supports. + */ + tokenModifiers: string[]; + + /** + * The formats the clients supports. + */ + formats: TokenFormat[]; + + /** + * Whether the client supports tokens that can overlap each other. + */ + overlappingTokenSupport?: boolean; + + /** + * Whether the client supports tokens that can span multiple lines. + */ + multilineTokenSupport?: boolean; +} +``` + +_Server Capability_: + +The following server capabilities are defined for semantic tokens: + +* property name (optional): `semanticTokensProvider` +* property type: `SemanticTokensOptions | SemanticTokensRegistrationOptions` where `SemanticTokensOptions` is defined as follows: + +```typescript +export interface SemanticTokensOptions extends WorkDoneProgressOptions { + /** + * The legend used by the server + */ + legend: SemanticTokensLegend; + + /** + * Server supports providing semantic tokens for a specific range + * of a document. + */ + range?: boolean | { + }; + + /** + * Server supports providing semantic tokens for a full document. + */ + full?: boolean | { + /** + * The server supports deltas for full documents. + */ + delta?: boolean; + } +} +``` + +_Registration Options_: `SemanticTokensRegistrationOptions` defined as follows: + +```typescript +export interface SemanticTokensRegistrationOptions extends + TextDocumentRegistrationOptions, SemanticTokensOptions, + StaticRegistrationOptions { +} +``` + +Since the registration option handles range, full and delta requests the method used to register for semantic tokens requests is `textDocument/semanticTokens` and not one of the specific methods described below. + +**Requesting semantic tokens for a whole file** + +_Request_: + +* method: `textDocument/semanticTokens/full` +* params: `SemanticTokensParams` defined as follows: + +```typescript +export interface SemanticTokensParams extends WorkDoneProgressParams, + PartialResultParams { + /** + * The text document. + */ + textDocument: TextDocumentIdentifier; +} +``` + +_Response_: + +* result: `SemanticTokens | null` where `SemanticTokens` is defined as follows: + +```typescript +export interface SemanticTokens { + /** + * An optional result id. If provided and clients support delta updating + * the client will include the result id in the next semantic token request. + * A server can then instead of computing all semantic tokens again simply + * send a delta. + */ + resultId?: string; + + /** + * The actual tokens. + */ + data: uinteger[]; +} +``` + +* partial result: `SemanticTokensPartialResult` defines as follows: + +```typescript +export interface SemanticTokensPartialResult { + data: uinteger[]; +} +``` + +* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/full' request + +**Requesting semantic token delta for a whole file** + +_Request_: + +* method: `textDocument/semanticTokens/full/delta` +* params: `SemanticTokensDeltaParams` defined as follows: + +```typescript +export interface SemanticTokensDeltaParams extends WorkDoneProgressParams, + PartialResultParams { + /** + * The text document. + */ + textDocument: TextDocumentIdentifier; + + /** + * The result id of a previous response. The result Id can either point to + * a full response or a delta response depending on what was received last. + */ + previousResultId: string; +} +``` + +_Response_: + +* result: `SemanticTokens | SemanticTokensDelta | null` where `SemanticTokensDelta` is defined as follows: + +```typescript +export interface SemanticTokensDelta { + readonly resultId?: string; + /** + * The semantic token edits to transform a previous result into a new + * result. + */ + edits: SemanticTokensEdit[]; +} + +export interface SemanticTokensEdit { + /** + * The start offset of the edit. + */ + start: uinteger; + + /** + * The count of elements to remove. + */ + deleteCount: uinteger; + + /** + * The elements to insert. + */ + data?: uinteger[]; +} +``` + +* partial result: `SemanticTokensDeltaPartialResult` defines as follows: + +```typescript +export interface SemanticTokensDeltaPartialResult { + edits: SemanticTokensEdit[] +} +``` + +* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/full/delta' request + +**Requesting semantic tokens for a range** + +When a user opens a file it can be beneficial to only compute the semantic tokens for the visible range (faster rendering of the tokens in the user interface). If a server can compute these tokens faster than for the whole file it can provide a handler for the `textDocument/semanticTokens/range` request to handle this case special. Please note that if a client also announces that it will send the `textDocument/semanticTokens/range` server should implement this request as well to allow for flicker free scrolling and semantic coloring of a minimap. + +_Request_: + +* method: `textDocument/semanticTokens/range` +* params: `SemanticTokensRangeParams` defined as follows: + +```typescript +export interface SemanticTokensRangeParams extends WorkDoneProgressParams, + PartialResultParams { + /** + * The text document. + */ + textDocument: TextDocumentIdentifier; + + /** + * The range the semantic tokens are requested for. + */ + range: Range; +} +``` + +_Response_: + +* result: `SemanticTokens | null` where `SemanticTokensDelta` +* partial result: `SemanticTokensPartialResult` +* error: code and message set in case an exception happens during the 'textDocument/semanticTokens/range' request + +**Requesting a refresh of all semantic tokens** + +The `workspace/semanticTokens/refresh` request is sent from the server to the client. Servers can use it to ask clients to refresh the editors for which this server provides semantic tokens. As a result the client should ask the server to recompute the semantic tokens for these editors. This is useful if a server detects a project wide configuration change which requires a re-calculation of all semantic tokens. Note that the client still has the freedom to delay the re-calculation of the semantic tokens if for example an editor is currently not visible. + +_Client Capability_: + +* property name (optional): `workspace.semanticTokens` +* property type: `SemanticTokensWorkspaceClientCapabilities` defined as follows: + +```typescript +export interface SemanticTokensWorkspaceClientCapabilities { + /** + * Whether the client implementation supports a refresh request sent from + * the server to the client. + * + * Note that this event is global and will force the client to refresh all + * semantic tokens currently shown. It should be used with absolute care + * and is useful for situation where a server for example detect a project + * wide change that requires such a calculation. + */ + refreshSupport?: boolean; +} +``` + +_Request_: + +* method: `workspace/semanticTokens/refresh` +* params: none + +_Response_: + +* result: void +* error: code and message set in case an exception happens during the 'workspace/semanticTokens/refresh' request + +#### Linked Editing Range(:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +The linked editing request is sent from the client to the server to return for a given position in a document the range of the symbol at the position and all ranges that have the same content. Optionally a word pattern can be returned to describe valid contents. A rename to one of the ranges can be applied to all other ranges if the new content is valid. If no result-specific word pattern is provided, the word pattern from the client's language configuration is used. + +_Client Capabilities_: + +* property name (optional): `textDocument.linkedEditingRange` +* property type: `LinkedEditingRangeClientCapabilities` defined as follows: + +```typescript +export interface LinkedEditingRangeClientCapabilities { + /** + * Whether implementation supports dynamic registration. + * If this is set to `true` the client supports the new + * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` + * return value for the corresponding server capability as well. + */ + dynamicRegistration?: boolean; +} +``` + +_Server Capability_: + +* property name (optional): `linkedEditingRangeProvider` +* property type: `boolean` \| `LinkedEditingRangeOptions` \| `LinkedEditingRangeRegistrationOptions` defined as follows: + +```typescript +export interface LinkedEditingRangeOptions extends WorkDoneProgressOptions { +} +``` + +_Registration Options_: `LinkedEditingRangeRegistrationOptions` defined as follows: + +```typescript +export interface LinkedEditingRangeRegistrationOptions extends + TextDocumentRegistrationOptions, LinkedEditingRangeOptions, + StaticRegistrationOptions { +} +``` + +_Request_: + +* method: `textDocument/linkedEditingRange` +* params: `LinkedEditingRangeParams` defined as follows: + +```typescript +export interface LinkedEditingRangeParams extends TextDocumentPositionParams, + WorkDoneProgressParams { +} +``` + +_Response_: + +* result: `LinkedEditingRanges` \| `null` defined as follows: + +```typescript +export interface LinkedEditingRanges { + /** + * A list of ranges that can be renamed together. The ranges must have + * identical length and contain identical text content. The ranges cannot overlap. + */ + ranges: Range[]; + + /** + * An optional word pattern (regular expression) that describes valid contents for + * the given ranges. If no pattern is provided, the client configuration's word + * pattern will be used. + */ + wordPattern?: string; +} +``` +* error: code and message set in case an exception happens during the 'textDocument/linkedEditingRange' request + +#### Monikers (:leftwards_arrow_with_hook:) + +> *Since version 3.16.0* + +Language Server Index Format (LSIF) introduced the concept of symbol monikers to help associate symbols across different indexes. This request adds capability for LSP server implementations to provide the same symbol moniker information given a text document position. Clients can utilize this method to get the moniker at the current location in a file user is editing and do further code navigation queries in other services that rely on LSIF indexes and link symbols together. + +The `textDocument/moniker` request is sent from the client to the server to get the symbol monikers for a given text document position. An array of Moniker types is returned as response to indicate possible monikers at the given location. If no monikers can be calculated, an empty array or `null` should be returned. + +_Client Capabilities_: + +* property name (optional): `textDocument.moniker` +* property type: `MonikerClientCapabilities` defined as follows: + +```typescript +interface MonikerClientCapabilities { + /** + * Whether implementation supports dynamic registration. If this is set to + * `true` the client supports the new `(TextDocumentRegistrationOptions & + * StaticRegistrationOptions)` return value for the corresponding server + * capability as well. + */ + dynamicRegistration?: boolean; +} +``` + +_Server Capability_: + +* property name (optional): `monikerProvider` +* property type: `boolean | MonikerOptions | MonikerRegistrationOptions` is defined as follows: + +```typescript +export interface MonikerOptions extends WorkDoneProgressOptions { +} +``` + +_Registration Options_: `MonikerRegistrationOptions` defined as follows: + +```typescript +export interface MonikerRegistrationOptions extends + TextDocumentRegistrationOptions, MonikerOptions { +} +``` + +_Request_: + +* method: `textDocument/moniker` +* params: `MonikerParams` defined as follows: + +```typescript +export interface MonikerParams extends TextDocumentPositionParams, + WorkDoneProgressParams, PartialResultParams { +} +``` + +_Response_: + +* result: `Moniker[] | null` +* partial result: `Moniker[]` +* error: code and message set in case an exception happens during the 'textDocument/moniker' request + +`Moniker` is defined as follows: + +```typescript +/** + * Moniker uniqueness level to define scope of the moniker. + */ +export enum UniquenessLevel { + /** + * The moniker is only unique inside a document + */ + document = 'document', + + /** + * The moniker is unique inside a project for which a dump got created + */ + project = 'project', + + /** + * The moniker is unique inside the group to which a project belongs + */ + group = 'group', + + /** + * The moniker is unique inside the moniker scheme. + */ + scheme = 'scheme', + + /** + * The moniker is globally unique + */ + global = 'global' +} + +/** + * The moniker kind. + */ +export enum MonikerKind { + /** + * The moniker represent a symbol that is imported into a project + */ + import = 'import', + + /** + * The moniker represents a symbol that is exported from a project + */ + export = 'export', + + /** + * The moniker represents a symbol that is local to a project (e.g. a local + * variable of a function, a class not visible outside the project, ...) + */ + local = 'local' +} + +/** + * Moniker definition to match LSIF 0.5 moniker definition. + */ +export interface Moniker { + /** + * The scheme of the moniker. For example tsc or .Net + */ + scheme: string; + + /** + * The identifier of the moniker. The value is opaque in LSIF however + * schema owners are allowed to define the structure if they want. + */ + identifier: string; + + /** + * The scope in which the moniker is unique + */ + unique: UniquenessLevel; + + /** + * The moniker kind if known. + */ + kind?: MonikerKind; +} +``` + +##### Notes + +Server implementations of this method should ensure that the moniker calculation matches to those used in the corresponding LSIF implementation to ensure symbols can be associated correctly across IDE sessions and LSIF indexes. + ### Implementation considerations Language servers usually run in a separate process and client communicate with them in an asynchronous fashion. Additionally clients usually allow users to interact with the source code even if request results are pending. We recommend the following implementation pattern to avoid that clients apply outdated response results: @@ -5812,8 +8092,42 @@ Language servers usually run in a separate process and client communicate with t - if servers end up in an inconsistent state they should log this to the client using the `window/logMessage` request. If they can't recover from this the best they can do right now is to exit themselves. We are considering an [extension to the protocol](https://github.com/Microsoft/language-server-protocol/issues/646) that allows servers to request a restart on the client side. - if a client notices that a server exits unexpectedly, it should try to restart the server. However clients should be careful not to restart a crashing server endlessly. VS Code, for example, doesn't restart a server which has crashed 5 times in the last 180 seconds. +Servers usually support different communication channels (e.g. stdio, pipes, ...). To easy the usage of servers in different clients it is highly recommended that a server implementation supports the following command line arguments to pick the communication channel: + +- **stdio**: uses stdio as the communication channel. +- **pipe**: use pipes (Windows) or socket files (Linux, Mac) as the communication channel. The pipe / socket file name is passed as the next arg or with `--pipe=`. +- **socket**: uses a socket as the communication channel. The port is passed as next arg or with `--port=`. +- **node-ipc**: use node IPC communication between the client and the server. This is only support if both client and server run under node. + ### Change Log +#### 3.16.0 (xx/xx/xxxx) + +* Add support for tracing. +* Add semantic token support. +* Add call hierarchy support. +* Add client capability for resolving text edits on completion items. +* Add support for client default behavior on renames. +* Add support for insert and replace ranges on `CompletionItem`. +* Add support for diagnostic code descriptions. +* Add support for document symbol provider label. +* Add support for tags on `SymbolInformation` and `DocumentSymbol`. +* Add support for moniker request method. +* Add support for code action `data` property. +* Add support for code action `disabled` property. +* Add support for code action resolve request. +* Add support for diagnostic `data` property. +* Add support for signature information `activeParameter` property. +* Add support for `workspace/didCreateFiles` notifications and `workspace/willCreateFiles` requests. +* Add support for `workspace/didRenameFiles` notifications and `workspace/willRenameFiles` requests. +* Add support for `workspace/didDeleteFiles` notifications and `workspace/willDeleteFiles` requests. +* Add client capability to signal whether the client normalizes line endings. +* Add support to preserve additional attributes on `MessageActionItem`. +* Add support to provide the clients locale in the initialize call. +* Add support for opening and showing a document in the client user interface. +* Add support for linked editing. +* Add support for change annotations in text edits as well as in create file, rename file and delete file operations. + #### 3.15.0 (01/14/2020) * Add generic progress reporting support. diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart index 31045987209..fa9d47be284 100644 --- a/pkg/analysis_server/tool/lsp_spec/markdown.dart +++ b/pkg/analysis_server/tool/lsp_spec/markdown.dart @@ -6,7 +6,7 @@ final _methodNamesPattern = RegExp( r'''_(?:Notification|Request):?_:?(?:\r?\n)+\* method: ['`](.*?)[`'],?\r?\n''', multiLine: true); final _typeScriptBlockPattern = - RegExp(r'\B```typescript([\S\s]*?)\n```', multiLine: true); + RegExp(r'\B```typescript([\S\s]*?)\n\s*```', multiLine: true); List extractMethodNames(String spec) { return _methodNamesPattern diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart index 44f29f83298..f0a54e83aa0 100644 --- a/pkg/analysis_server/tool/lsp_spec/typescript.dart +++ b/pkg/analysis_server/tool/lsp_spec/typescript.dart @@ -76,6 +76,7 @@ String getImprovedType(String interfaceName, String fieldName) { 'Diagnostic': { 'severity': 'DiagnosticSeverity', 'code': 'String', + 'data': 'object', }, 'TextDocumentSyncOptions': { 'change': 'TextDocumentSyncKind', @@ -89,6 +90,10 @@ String getImprovedType(String interfaceName, String fieldName) { 'CompletionItem': { 'kind': 'CompletionItemKind', 'data': 'CompletionItemResolutionInfo', + 'textEdit': 'TextEdit', + }, + 'CallHierarchyItem': { + 'data': 'object', }, 'DocumentHighlight': { 'kind': 'DocumentHighlightKind', diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart index 9e9d8149779..c657cab77b4 100644 --- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart +++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart @@ -287,6 +287,9 @@ class Parser { /// Ensures the next token is [type] and moves to the next, throwing [message] /// if not. Token _consume(TokenType type, String message) { + // Skip over any inline comments when looking for a specific token. + _match([TokenType.COMMENT]); + if (_check(type)) { return _advance(); }