1//===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains structs based on the LSP specification at
10// https://github.com/Microsoft/language-server-protocol/blob/main/protocol.md
11//
12// This is not meant to be a complete implementation, new interfaces are added
13// when they're needed.
14//
15// Each struct has a toJSON and fromJSON function, that converts between
16// the struct and a JSON representation. (See JSON.h)
17//
18// Some structs also have operator<< serialization. This is for debugging and
19// tests, and is not generally machine-readable.
20//
21//===----------------------------------------------------------------------===//
22
23#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
24#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
25
26#include "URI.h"
27#include "index/SymbolID.h"
28#include "support/MemoryTree.h"
29#include "clang/Index/IndexSymbol.h"
30#include "llvm/ADT/SmallVector.h"
31#include "llvm/Support/JSON.h"
32#include "llvm/Support/raw_ostream.h"
33#include <bitset>
34#include <memory>
35#include <optional>
36#include <string>
37#include <vector>
38
39// This file is using the LSP syntax for identifier names which is different
40// from the LLVM coding standard. To avoid the clang-tidy warnings, we're
41// disabling one check here.
42// NOLINTBEGIN(readability-identifier-naming)
43
44namespace clang {
45namespace clangd {
46
47enum class ErrorCode {
48 // Defined by JSON RPC.
49 ParseError = -32700,
50 InvalidRequest = -32600,
51 MethodNotFound = -32601,
52 InvalidParams = -32602,
53 InternalError = -32603,
54
55 ServerNotInitialized = -32002,
56 UnknownErrorCode = -32001,
57
58 // Defined by the protocol.
59 RequestCancelled = -32800,
60 ContentModified = -32801,
61};
62// Models an LSP error as an llvm::Error.
63class LSPError : public llvm::ErrorInfo<LSPError> {
64public:
65 std::string Message;
66 ErrorCode Code;
67 static char ID;
68
69 LSPError(std::string Message, ErrorCode Code)
70 : Message(std::move(Message)), Code(Code) {}
71
72 void log(llvm::raw_ostream &OS) const override {
73 OS << int(Code) << ": " << Message;
74 }
75 std::error_code convertToErrorCode() const override {
76 return llvm::inconvertibleErrorCode();
77 }
78};
79
80bool fromJSON(const llvm::json::Value &, SymbolID &, llvm::json::Path);
81llvm::json::Value toJSON(const SymbolID &);
82
83// URI in "file" scheme for a file.
84struct URIForFile {
85 URIForFile() = default;
86
87 /// Canonicalizes \p AbsPath via URI.
88 ///
89 /// File paths in URIForFile can come from index or local AST. Path from
90 /// index goes through URI transformation, and the final path is resolved by
91 /// URI scheme and could potentially be different from the original path.
92 /// Hence, we do the same transformation for all paths.
93 ///
94 /// Files can be referred to by several paths (e.g. in the presence of links).
95 /// Which one we prefer may depend on where we're coming from. \p TUPath is a
96 /// hint, and should usually be the main entrypoint file we're processing.
97 static URIForFile canonicalize(llvm::StringRef AbsPath,
98 llvm::StringRef TUPath);
99
100 static llvm::Expected<URIForFile> fromURI(const URI &U,
101 llvm::StringRef HintPath);
102
103 /// Retrieves absolute path to the file.
104 llvm::StringRef file() const { return File; }
105
106 explicit operator bool() const { return !File.empty(); }
107 std::string uri() const { return URI::createFile(AbsolutePath: File).toString(); }
108
109 friend bool operator==(const URIForFile &LHS, const URIForFile &RHS) {
110 return LHS.File == RHS.File;
111 }
112
113 friend bool operator!=(const URIForFile &LHS, const URIForFile &RHS) {
114 return !(LHS == RHS);
115 }
116
117 friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) {
118 return LHS.File < RHS.File;
119 }
120
121private:
122 explicit URIForFile(std::string &&File) : File(std::move(File)) {}
123
124 std::string File;
125};
126
127/// Serialize/deserialize \p URIForFile to/from a string URI.
128llvm::json::Value toJSON(const URIForFile &U);
129bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path);
130
131struct TextDocumentIdentifier {
132 /// The text document's URI.
133 URIForFile uri;
134};
135llvm::json::Value toJSON(const TextDocumentIdentifier &);
136bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &,
137 llvm::json::Path);
138
139struct VersionedTextDocumentIdentifier : public TextDocumentIdentifier {
140 /// The version number of this document. If a versioned text document
141 /// identifier is sent from the server to the client and the file is not open
142 /// in the editor (the server has not received an open notification before)
143 /// the server can send `null` to indicate that the version is known and the
144 /// content on disk is the master (as speced with document content ownership).
145 ///
146 /// The version number of a document will increase after each change,
147 /// including undo/redo. The number doesn't need to be consecutive.
148 ///
149 /// clangd extension: versions are optional, and synthesized if missing.
150 std::optional<std::int64_t> version;
151};
152llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &);
153bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &,
154 llvm::json::Path);
155
156struct Position {
157 /// Line position in a document (zero-based).
158 int line = 0;
159
160 /// Character offset on a line in a document (zero-based).
161 /// WARNING: this is in UTF-16 codepoints, not bytes or characters!
162 /// Use the functions in SourceCode.h to construct/interpret Positions.
163 int character = 0;
164
165 friend bool operator==(const Position &LHS, const Position &RHS) {
166 return std::tie(args: LHS.line, args: LHS.character) ==
167 std::tie(args: RHS.line, args: RHS.character);
168 }
169 friend bool operator!=(const Position &LHS, const Position &RHS) {
170 return !(LHS == RHS);
171 }
172 friend bool operator<(const Position &LHS, const Position &RHS) {
173 return std::tie(args: LHS.line, args: LHS.character) <
174 std::tie(args: RHS.line, args: RHS.character);
175 }
176 friend bool operator<=(const Position &LHS, const Position &RHS) {
177 return std::tie(args: LHS.line, args: LHS.character) <=
178 std::tie(args: RHS.line, args: RHS.character);
179 }
180};
181bool fromJSON(const llvm::json::Value &, Position &, llvm::json::Path);
182llvm::json::Value toJSON(const Position &);
183llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Position &);
184
185struct Range {
186 /// The range's start position.
187 Position start;
188
189 /// The range's end position.
190 Position end;
191
192 friend bool operator==(const Range &LHS, const Range &RHS) {
193 return std::tie(args: LHS.start, args: LHS.end) == std::tie(args: RHS.start, args: RHS.end);
194 }
195 friend bool operator!=(const Range &LHS, const Range &RHS) {
196 return !(LHS == RHS);
197 }
198 friend bool operator<(const Range &LHS, const Range &RHS) {
199 return std::tie(args: LHS.start, args: LHS.end) < std::tie(args: RHS.start, args: RHS.end);
200 }
201
202 bool contains(Position Pos) const { return start <= Pos && Pos < end; }
203 bool contains(Range Rng) const {
204 return start <= Rng.start && Rng.end <= end;
205 }
206};
207bool fromJSON(const llvm::json::Value &, Range &, llvm::json::Path);
208llvm::json::Value toJSON(const Range &);
209llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Range &);
210
211struct Location {
212 /// The text document's URI.
213 URIForFile uri;
214 Range range;
215
216 friend bool operator==(const Location &LHS, const Location &RHS) {
217 return LHS.uri == RHS.uri && LHS.range == RHS.range;
218 }
219
220 friend bool operator!=(const Location &LHS, const Location &RHS) {
221 return !(LHS == RHS);
222 }
223
224 friend bool operator<(const Location &LHS, const Location &RHS) {
225 return std::tie(args: LHS.uri, args: LHS.range) < std::tie(args: RHS.uri, args: RHS.range);
226 }
227};
228llvm::json::Value toJSON(const Location &);
229llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Location &);
230
231/// Extends Locations returned by textDocument/references with extra info.
232/// This is a clangd extension: LSP uses `Location`.
233struct ReferenceLocation : Location {
234 /// clangd extension: contains the name of the function or class in which the
235 /// reference occurs
236 std::optional<std::string> containerName;
237};
238llvm::json::Value toJSON(const ReferenceLocation &);
239llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ReferenceLocation &);
240
241using ChangeAnnotationIdentifier = std::string;
242// A combination of a LSP standard TextEdit and AnnotatedTextEdit.
243struct TextEdit {
244 /// The range of the text document to be manipulated. To insert
245 /// text into a document create a range where start === end.
246 Range range;
247
248 /// The string to be inserted. For delete operations use an
249 /// empty string.
250 std::string newText;
251
252 /// The actual annotation identifier (optional)
253 /// If empty, then this field is nullopt.
254 ChangeAnnotationIdentifier annotationId = "";
255};
256inline bool operator==(const TextEdit &L, const TextEdit &R) {
257 return std::tie(args: L.newText, args: L.range, args: L.annotationId) ==
258 std::tie(args: R.newText, args: R.range, args: L.annotationId);
259}
260bool fromJSON(const llvm::json::Value &, TextEdit &, llvm::json::Path);
261llvm::json::Value toJSON(const TextEdit &);
262llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &);
263
264struct ChangeAnnotation {
265 /// A human-readable string describing the actual change. The string
266 /// is rendered prominent in the user interface.
267 std::string label;
268
269 /// A flag which indicates that user confirmation is needed
270 /// before applying the change.
271 std::optional<bool> needsConfirmation;
272
273 /// A human-readable string which is rendered less prominent in
274 /// the user interface.
275 std::string description;
276};
277bool fromJSON(const llvm::json::Value &, ChangeAnnotation &, llvm::json::Path);
278llvm::json::Value toJSON(const ChangeAnnotation &);
279
280struct TextDocumentEdit {
281 /// The text document to change.
282 VersionedTextDocumentIdentifier textDocument;
283
284 /// The edits to be applied.
285 /// FIXME: support the AnnotatedTextEdit variant.
286 std::vector<TextEdit> edits;
287};
288bool fromJSON(const llvm::json::Value &, TextDocumentEdit &, llvm::json::Path);
289llvm::json::Value toJSON(const TextDocumentEdit &);
290
291struct TextDocumentItem {
292 /// The text document's URI.
293 URIForFile uri;
294
295 /// The text document's language identifier.
296 std::string languageId;
297
298 /// The version number of this document (it will strictly increase after each
299 /// change, including undo/redo.
300 ///
301 /// clangd extension: versions are optional, and synthesized if missing.
302 std::optional<int64_t> version;
303
304 /// The content of the opened text document.
305 std::string text;
306};
307bool fromJSON(const llvm::json::Value &, TextDocumentItem &, llvm::json::Path);
308
309enum class TraceLevel {
310 Off = 0,
311 Messages = 1,
312 Verbose = 2,
313};
314bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path);
315
316struct NoParams {};
317inline llvm::json::Value toJSON(const NoParams &) { return nullptr; }
318inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) {
319 return true;
320}
321using InitializedParams = NoParams;
322
323/// Defines how the host (editor) should sync document changes to the language
324/// server.
325enum class TextDocumentSyncKind {
326 /// Documents should not be synced at all.
327 None = 0,
328
329 /// Documents are synced by always sending the full content of the document.
330 Full = 1,
331
332 /// Documents are synced by sending the full content on open. After that
333 /// only incremental updates to the document are send.
334 Incremental = 2,
335};
336
337/// The kind of a completion entry.
338enum class CompletionItemKind {
339 Missing = 0,
340 Text = 1,
341 Method = 2,
342 Function = 3,
343 Constructor = 4,
344 Field = 5,
345 Variable = 6,
346 Class = 7,
347 Interface = 8,
348 Module = 9,
349 Property = 10,
350 Unit = 11,
351 Value = 12,
352 Enum = 13,
353 Keyword = 14,
354 Snippet = 15,
355 Color = 16,
356 File = 17,
357 Reference = 18,
358 Folder = 19,
359 EnumMember = 20,
360 Constant = 21,
361 Struct = 22,
362 Event = 23,
363 Operator = 24,
364 TypeParameter = 25,
365};
366bool fromJSON(const llvm::json::Value &, CompletionItemKind &,
367 llvm::json::Path);
368constexpr auto CompletionItemKindMin =
369 static_cast<size_t>(CompletionItemKind::Text);
370constexpr auto CompletionItemKindMax =
371 static_cast<size_t>(CompletionItemKind::TypeParameter);
372using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>;
373bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &,
374 llvm::json::Path);
375CompletionItemKind
376adjustKindToCapability(CompletionItemKind Kind,
377 CompletionItemKindBitset &SupportedCompletionItemKinds);
378
379/// A symbol kind.
380enum class SymbolKind {
381 File = 1,
382 Module = 2,
383 Namespace = 3,
384 Package = 4,
385 Class = 5,
386 Method = 6,
387 Property = 7,
388 Field = 8,
389 Constructor = 9,
390 Enum = 10,
391 Interface = 11,
392 Function = 12,
393 Variable = 13,
394 Constant = 14,
395 String = 15,
396 Number = 16,
397 Boolean = 17,
398 Array = 18,
399 Object = 19,
400 Key = 20,
401 Null = 21,
402 EnumMember = 22,
403 Struct = 23,
404 Event = 24,
405 Operator = 25,
406 TypeParameter = 26
407};
408bool fromJSON(const llvm::json::Value &, SymbolKind &, llvm::json::Path);
409constexpr auto SymbolKindMin = static_cast<size_t>(SymbolKind::File);
410constexpr auto SymbolKindMax = static_cast<size_t>(SymbolKind::TypeParameter);
411using SymbolKindBitset = std::bitset<SymbolKindMax + 1>;
412bool fromJSON(const llvm::json::Value &, SymbolKindBitset &, llvm::json::Path);
413SymbolKind adjustKindToCapability(SymbolKind Kind,
414 SymbolKindBitset &supportedSymbolKinds);
415
416// Convert a index::SymbolKind to clangd::SymbolKind (LSP)
417// Note, some are not perfect matches and should be improved when this LSP
418// issue is addressed:
419// https://github.com/Microsoft/language-server-protocol/issues/344
420SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind);
421
422// Determines the encoding used to measure offsets and lengths of source in LSP.
423enum class OffsetEncoding {
424 // Any string is legal on the wire. Unrecognized encodings parse as this.
425 UnsupportedEncoding,
426 // Length counts code units of UTF-16 encoded text. (Standard LSP behavior).
427 UTF16,
428 // Length counts bytes of UTF-8 encoded text. (Clangd extension).
429 UTF8,
430 // Length counts codepoints in unicode text. (Clangd extension).
431 UTF32,
432};
433llvm::json::Value toJSON(const OffsetEncoding &);
434bool fromJSON(const llvm::json::Value &, OffsetEncoding &, llvm::json::Path);
435llvm::raw_ostream &operator<<(llvm::raw_ostream &, OffsetEncoding);
436
437// Describes the content type that a client supports in various result literals
438// like `Hover`, `ParameterInfo` or `CompletionItem`.
439enum class MarkupKind {
440 PlainText,
441 Markdown,
442};
443bool fromJSON(const llvm::json::Value &, MarkupKind &, llvm::json::Path);
444llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind);
445
446// This struct doesn't mirror LSP!
447// The protocol defines deeply nested structures for client capabilities.
448// Instead of mapping them all, this just parses out the bits we care about.
449struct ClientCapabilities {
450 /// The supported set of SymbolKinds for workspace/symbol.
451 /// workspace.symbol.symbolKind.valueSet
452 std::optional<SymbolKindBitset> WorkspaceSymbolKinds;
453
454 /// Whether the client accepts diagnostics with codeActions attached inline.
455 /// This is a clangd extension.
456 /// textDocument.publishDiagnostics.codeActionsInline.
457 bool DiagnosticFixes = false;
458
459 /// Whether the client accepts diagnostics with related locations.
460 /// textDocument.publishDiagnostics.relatedInformation.
461 bool DiagnosticRelatedInformation = false;
462
463 /// Whether the client accepts diagnostics with category attached to it
464 /// using the "category" extension.
465 /// textDocument.publishDiagnostics.categorySupport
466 bool DiagnosticCategory = false;
467
468 /// Client supports snippets as insert text.
469 /// textDocument.completion.completionItem.snippetSupport
470 bool CompletionSnippets = false;
471
472 /// Client supports completions with additionalTextEdit near the cursor.
473 /// This is a clangd extension. (LSP says this is for unrelated text only).
474 /// textDocument.completion.editsNearCursor
475 bool CompletionFixes = false;
476
477 /// Client supports displaying a container string for results of
478 /// textDocument/reference (clangd extension)
479 /// textDocument.references.container
480 bool ReferenceContainer = false;
481
482 /// Client supports hierarchical document symbols.
483 /// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport
484 bool HierarchicalDocumentSymbol = false;
485
486 /// Client supports signature help.
487 /// textDocument.signatureHelp
488 bool HasSignatureHelp = false;
489
490 /// Client signals that it only supports folding complete lines.
491 /// Client will ignore specified `startCharacter` and `endCharacter`
492 /// properties in a FoldingRange.
493 /// textDocument.foldingRange.lineFoldingOnly
494 bool LineFoldingOnly = false;
495
496 /// Client supports processing label offsets instead of a simple label string.
497 /// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
498 bool OffsetsInSignatureHelp = false;
499
500 /// The documentation format that should be used for
501 /// textDocument/signatureHelp.
502 /// textDocument.signatureHelp.signatureInformation.documentationFormat
503 MarkupKind SignatureHelpDocumentationFormat = MarkupKind::PlainText;
504
505 /// The supported set of CompletionItemKinds for textDocument/completion.
506 /// textDocument.completion.completionItemKind.valueSet
507 std::optional<CompletionItemKindBitset> CompletionItemKinds;
508
509 /// The documentation format that should be used for textDocument/completion.
510 /// textDocument.completion.completionItem.documentationFormat
511 MarkupKind CompletionDocumentationFormat = MarkupKind::PlainText;
512
513 /// The client has support for completion item label details.
514 /// textDocument.completion.completionItem.labelDetailsSupport.
515 bool CompletionLabelDetail = false;
516
517 /// Client supports CodeAction return value for textDocument/codeAction.
518 /// textDocument.codeAction.codeActionLiteralSupport.
519 bool CodeActionStructure = false;
520
521 /// Client advertises support for the semanticTokens feature.
522 /// We support the textDocument/semanticTokens request in any case.
523 /// textDocument.semanticTokens
524 bool SemanticTokens = false;
525 /// Client supports Theia semantic highlighting extension.
526 /// https://github.com/microsoft/vscode-languageserver-node/pull/367
527 /// clangd no longer supports this, we detect it just to log a warning.
528 /// textDocument.semanticHighlightingCapabilities.semanticHighlighting
529 bool TheiaSemanticHighlighting = false;
530
531 /// Supported encodings for LSP character offsets. (clangd extension).
532 std::optional<std::vector<OffsetEncoding>> offsetEncoding;
533
534 /// The content format that should be used for Hover requests.
535 /// textDocument.hover.contentEncoding
536 MarkupKind HoverContentFormat = MarkupKind::PlainText;
537
538 /// The client supports testing for validity of rename operations
539 /// before execution.
540 bool RenamePrepareSupport = false;
541
542 /// The client supports progress notifications.
543 /// window.workDoneProgress
544 bool WorkDoneProgress = false;
545
546 /// The client supports implicit $/progress work-done progress streams,
547 /// without a preceding window/workDoneProgress/create.
548 /// This is a clangd extension.
549 /// window.implicitWorkDoneProgressCreate
550 bool ImplicitProgressCreation = false;
551
552 /// Whether the client claims to cancel stale requests.
553 /// general.staleRequestSupport.cancel
554 bool CancelsStaleRequests = false;
555
556 /// Whether the client implementation supports a refresh request sent from the
557 /// server to the client.
558 bool SemanticTokenRefreshSupport = false;
559
560 /// The client supports versioned document changes for WorkspaceEdit.
561 bool DocumentChanges = false;
562
563 /// The client supports change annotations on text edits,
564 bool ChangeAnnotation = false;
565
566 /// Whether the client supports the textDocument/inactiveRegions
567 /// notification. This is a clangd extension.
568 /// textDocument.inactiveRegionsCapabilities.inactiveRegions
569 bool InactiveRegions = false;
570};
571bool fromJSON(const llvm::json::Value &, ClientCapabilities &,
572 llvm::json::Path);
573
574/// Clangd extension that's used in the 'compilationDatabaseChanges' in
575/// workspace/didChangeConfiguration to record updates to the in-memory
576/// compilation database.
577struct ClangdCompileCommand {
578 std::string workingDirectory;
579 std::vector<std::string> compilationCommand;
580};
581bool fromJSON(const llvm::json::Value &, ClangdCompileCommand &,
582 llvm::json::Path);
583
584/// Clangd extension: parameters configurable at any time, via the
585/// `workspace/didChangeConfiguration` notification.
586/// LSP defines this type as `any`.
587struct ConfigurationSettings {
588 // Changes to the in-memory compilation database.
589 // The key of the map is a file name.
590 std::map<std::string, ClangdCompileCommand> compilationDatabaseChanges;
591};
592bool fromJSON(const llvm::json::Value &, ConfigurationSettings &,
593 llvm::json::Path);
594
595/// Clangd extension: parameters configurable at `initialize` time.
596/// LSP defines this type as `any`.
597struct InitializationOptions {
598 // What we can change through the didChangeConfiguration request, we can
599 // also set through the initialize request (initializationOptions field).
600 ConfigurationSettings ConfigSettings;
601
602 std::optional<std::string> compilationDatabasePath;
603 // Additional flags to be included in the "fallback command" used when
604 // the compilation database doesn't describe an opened file.
605 // The command used will be approximately `clang $FILE $fallbackFlags`.
606 std::vector<std::string> fallbackFlags;
607
608 /// Clients supports show file status for textDocument/clangd.fileStatus.
609 bool FileStatus = false;
610};
611bool fromJSON(const llvm::json::Value &, InitializationOptions &,
612 llvm::json::Path);
613
614struct InitializeParams {
615 /// The process Id of the parent process that started
616 /// the server. Is null if the process has not been started by another
617 /// process. If the parent process is not alive then the server should exit
618 /// (see exit notification) its process.
619 std::optional<int> processId;
620
621 /// The rootPath of the workspace. Is null
622 /// if no folder is open.
623 ///
624 /// @deprecated in favour of rootUri.
625 std::optional<std::string> rootPath;
626
627 /// The rootUri of the workspace. Is null if no
628 /// folder is open. If both `rootPath` and `rootUri` are set
629 /// `rootUri` wins.
630 std::optional<URIForFile> rootUri;
631
632 // User provided initialization options.
633 // initializationOptions?: any;
634
635 /// The capabilities provided by the client (editor or tool)
636 ClientCapabilities capabilities;
637 /// The same data as capabilities, but not parsed (to expose to modules).
638 llvm::json::Object rawCapabilities;
639
640 /// The initial trace setting. If omitted trace is disabled ('off').
641 std::optional<TraceLevel> trace;
642
643 /// User-provided initialization options.
644 InitializationOptions initializationOptions;
645};
646bool fromJSON(const llvm::json::Value &, InitializeParams &, llvm::json::Path);
647
648struct WorkDoneProgressCreateParams {
649 /// The token to be used to report progress.
650 llvm::json::Value token = nullptr;
651};
652llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P);
653
654template <typename T> struct ProgressParams {
655 /// The progress token provided by the client or server.
656 llvm::json::Value token = nullptr;
657
658 /// The progress data.
659 T value;
660};
661template <typename T> llvm::json::Value toJSON(const ProgressParams<T> &P) {
662 return llvm::json::Object{{"token", P.token}, {"value", P.value}};
663}
664/// To start progress reporting a $/progress notification with the following
665/// payload must be sent.
666struct WorkDoneProgressBegin {
667 /// Mandatory title of the progress operation. Used to briefly inform about
668 /// the kind of operation being performed.
669 ///
670 /// Examples: "Indexing" or "Linking dependencies".
671 std::string title;
672
673 /// Controls if a cancel button should show to allow the user to cancel the
674 /// long-running operation. Clients that don't support cancellation are
675 /// allowed to ignore the setting.
676 bool cancellable = false;
677
678 /// Optional progress percentage to display (value 100 is considered 100%).
679 /// If not provided infinite progress is assumed and clients are allowed
680 /// to ignore the `percentage` value in subsequent in report notifications.
681 ///
682 /// The value should be steadily rising. Clients are free to ignore values
683 /// that are not following this rule.
684 ///
685 /// Clangd implementation note: we only send nonzero percentages in
686 /// the WorkProgressReport. 'true' here means percentages will be used.
687 bool percentage = false;
688};
689llvm::json::Value toJSON(const WorkDoneProgressBegin &);
690
691/// Reporting progress is done using the following payload.
692struct WorkDoneProgressReport {
693 /// Mandatory title of the progress operation. Used to briefly inform about
694 /// the kind of operation being performed.
695 ///
696 /// Examples: "Indexing" or "Linking dependencies".
697 std::string title;
698
699 /// Controls enablement state of a cancel button. This property is only valid
700 /// if a cancel button got requested in the `WorkDoneProgressStart` payload.
701 ///
702 /// Clients that don't support cancellation or don't support control
703 /// the button's enablement state are allowed to ignore the setting.
704 std::optional<bool> cancellable;
705
706 /// Optional, more detailed associated progress message. Contains
707 /// complementary information to the `title`.
708 ///
709 /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
710 /// If unset, the previous progress message (if any) is still valid.
711 std::optional<std::string> message;
712
713 /// Optional progress percentage to display (value 100 is considered 100%).
714 /// If not provided infinite progress is assumed and clients are allowed
715 /// to ignore the `percentage` value in subsequent in report notifications.
716 ///
717 /// The value should be steadily rising. Clients are free to ignore values
718 /// that are not following this rule.
719 std::optional<unsigned> percentage;
720};
721llvm::json::Value toJSON(const WorkDoneProgressReport &);
722//
723/// Signals the end of progress reporting.
724struct WorkDoneProgressEnd {
725 /// Optional, a final message indicating to for example indicate the outcome
726 /// of the operation.
727 std::optional<std::string> message;
728};
729llvm::json::Value toJSON(const WorkDoneProgressEnd &);
730
731enum class MessageType {
732 /// An error message.
733 Error = 1,
734 /// A warning message.
735 Warning = 2,
736 /// An information message.
737 Info = 3,
738 /// A log message.
739 Log = 4,
740};
741llvm::json::Value toJSON(const MessageType &);
742
743/// The show message notification is sent from a server to a client to ask the
744/// client to display a particular message in the user interface.
745struct ShowMessageParams {
746 /// The message type.
747 MessageType type = MessageType::Info;
748 /// The actual message.
749 std::string message;
750};
751llvm::json::Value toJSON(const ShowMessageParams &);
752
753struct DidOpenTextDocumentParams {
754 /// The document that was opened.
755 TextDocumentItem textDocument;
756};
757bool fromJSON(const llvm::json::Value &, DidOpenTextDocumentParams &,
758 llvm::json::Path);
759
760struct DidCloseTextDocumentParams {
761 /// The document that was closed.
762 TextDocumentIdentifier textDocument;
763};
764bool fromJSON(const llvm::json::Value &, DidCloseTextDocumentParams &,
765 llvm::json::Path);
766
767struct DidSaveTextDocumentParams {
768 /// The document that was saved.
769 TextDocumentIdentifier textDocument;
770};
771bool fromJSON(const llvm::json::Value &, DidSaveTextDocumentParams &,
772 llvm::json::Path);
773
774struct TextDocumentContentChangeEvent {
775 /// The range of the document that changed.
776 std::optional<Range> range;
777
778 /// The length of the range that got replaced.
779 std::optional<int> rangeLength;
780
781 /// The new text of the range/document.
782 std::string text;
783};
784bool fromJSON(const llvm::json::Value &, TextDocumentContentChangeEvent &,
785 llvm::json::Path);
786
787struct DidChangeTextDocumentParams {
788 /// The document that did change. The version number points
789 /// to the version after all provided content changes have
790 /// been applied.
791 VersionedTextDocumentIdentifier textDocument;
792
793 /// The actual content changes.
794 std::vector<TextDocumentContentChangeEvent> contentChanges;
795
796 /// Forces diagnostics to be generated, or to not be generated, for this
797 /// version of the file. If not set, diagnostics are eventually consistent:
798 /// either they will be provided for this version or some subsequent one.
799 /// This is a clangd extension.
800 std::optional<bool> wantDiagnostics;
801
802 /// Force a complete rebuild of the file, ignoring all cached state. Slow!
803 /// This is useful to defeat clangd's assumption that missing headers will
804 /// stay missing.
805 /// This is a clangd extension.
806 bool forceRebuild = false;
807};
808bool fromJSON(const llvm::json::Value &, DidChangeTextDocumentParams &,
809 llvm::json::Path);
810
811enum class FileChangeType {
812 /// The file got created.
813 Created = 1,
814 /// The file got changed.
815 Changed = 2,
816 /// The file got deleted.
817 Deleted = 3
818};
819bool fromJSON(const llvm::json::Value &E, FileChangeType &Out,
820 llvm::json::Path);
821
822struct FileEvent {
823 /// The file's URI.
824 URIForFile uri;
825 /// The change type.
826 FileChangeType type = FileChangeType::Created;
827};
828bool fromJSON(const llvm::json::Value &, FileEvent &, llvm::json::Path);
829
830struct DidChangeWatchedFilesParams {
831 /// The actual file events.
832 std::vector<FileEvent> changes;
833};
834bool fromJSON(const llvm::json::Value &, DidChangeWatchedFilesParams &,
835 llvm::json::Path);
836
837struct DidChangeConfigurationParams {
838 ConfigurationSettings settings;
839};
840bool fromJSON(const llvm::json::Value &, DidChangeConfigurationParams &,
841 llvm::json::Path);
842
843// Note: we do not parse FormattingOptions for *FormattingParams.
844// In general, we use a clang-format style detected from common mechanisms
845// (.clang-format files and the -fallback-style flag).
846// It would be possible to override these with FormatOptions, but:
847// - the protocol makes FormatOptions mandatory, so many clients set them to
848// useless values, and we can't tell when to respect them
849// - we also format in other places, where FormatOptions aren't available.
850
851struct DocumentRangeFormattingParams {
852 /// The document to format.
853 TextDocumentIdentifier textDocument;
854
855 /// The range to format
856 Range range;
857};
858bool fromJSON(const llvm::json::Value &, DocumentRangeFormattingParams &,
859 llvm::json::Path);
860
861struct DocumentRangesFormattingParams {
862 /// The document to format.
863 TextDocumentIdentifier textDocument;
864
865 /// The list of ranges to format
866 std::vector<Range> ranges;
867};
868bool fromJSON(const llvm::json::Value &, DocumentRangesFormattingParams &,
869 llvm::json::Path);
870
871struct DocumentOnTypeFormattingParams {
872 /// The document to format.
873 TextDocumentIdentifier textDocument;
874
875 /// The position at which this request was sent.
876 Position position;
877
878 /// The character that has been typed.
879 std::string ch;
880};
881bool fromJSON(const llvm::json::Value &, DocumentOnTypeFormattingParams &,
882 llvm::json::Path);
883
884struct DocumentFormattingParams {
885 /// The document to format.
886 TextDocumentIdentifier textDocument;
887};
888bool fromJSON(const llvm::json::Value &, DocumentFormattingParams &,
889 llvm::json::Path);
890
891struct DocumentSymbolParams {
892 // The text document to find symbols in.
893 TextDocumentIdentifier textDocument;
894};
895bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &,
896 llvm::json::Path);
897
898/// Represents a related message and source code location for a diagnostic.
899/// This should be used to point to code locations that cause or related to a
900/// diagnostics, e.g when duplicating a symbol in a scope.
901struct DiagnosticRelatedInformation {
902 /// The location of this related diagnostic information.
903 Location location;
904 /// The message of this related diagnostic information.
905 std::string message;
906};
907llvm::json::Value toJSON(const DiagnosticRelatedInformation &);
908
909enum DiagnosticTag {
910 /// Unused or unnecessary code.
911 ///
912 /// Clients are allowed to render diagnostics with this tag faded out instead
913 /// of having an error squiggle.
914 Unnecessary = 1,
915 /// Deprecated or obsolete code.
916 ///
917 /// Clients are allowed to rendered diagnostics with this tag strike through.
918 Deprecated = 2,
919};
920llvm::json::Value toJSON(DiagnosticTag Tag);
921
922/// Structure to capture a description for an error code.
923struct CodeDescription {
924 /// An URI to open with more information about the diagnostic error.
925 std::string href;
926};
927llvm::json::Value toJSON(const CodeDescription &);
928
929struct CodeAction;
930struct Diagnostic {
931 /// The range at which the message applies.
932 Range range;
933
934 /// The diagnostic's severity. Can be omitted. If omitted it is up to the
935 /// client to interpret diagnostics as error, warning, info or hint.
936 int severity = 0;
937
938 /// The diagnostic's code. Can be omitted.
939 std::string code;
940
941 /// An optional property to describe the error code.
942 std::optional<CodeDescription> codeDescription;
943
944 /// A human-readable string describing the source of this
945 /// diagnostic, e.g. 'typescript' or 'super lint'.
946 std::string source;
947
948 /// The diagnostic's message.
949 std::string message;
950
951 /// Additional metadata about the diagnostic.
952 llvm::SmallVector<DiagnosticTag, 1> tags;
953
954 /// An array of related diagnostic information, e.g. when symbol-names within
955 /// a scope collide all definitions can be marked via this property.
956 std::optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
957
958 /// The diagnostic's category. Can be omitted.
959 /// An LSP extension that's used to send the name of the category over to the
960 /// client. The category typically describes the compilation stage during
961 /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue".
962 std::optional<std::string> category;
963
964 /// Clangd extension: code actions related to this diagnostic.
965 /// Only with capability textDocument.publishDiagnostics.codeActionsInline.
966 /// (These actions can also be obtained using textDocument/codeAction).
967 std::optional<std::vector<CodeAction>> codeActions;
968
969 /// A data entry field that is preserved between a
970 /// `textDocument/publishDiagnostics` notification
971 /// and `textDocument/codeAction` request.
972 /// Mutating users should associate their data with a unique key they can use
973 /// to retrieve later on.
974 llvm::json::Object data;
975};
976llvm::json::Value toJSON(const Diagnostic &);
977
978bool fromJSON(const llvm::json::Value &, Diagnostic &, llvm::json::Path);
979llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Diagnostic &);
980
981struct PublishDiagnosticsParams {
982 /// The URI for which diagnostic information is reported.
983 URIForFile uri;
984 /// An array of diagnostic information items.
985 std::vector<Diagnostic> diagnostics;
986 /// The version number of the document the diagnostics are published for.
987 std::optional<int64_t> version;
988};
989llvm::json::Value toJSON(const PublishDiagnosticsParams &);
990
991struct CodeActionContext {
992 /// An array of diagnostics known on the client side overlapping the range
993 /// provided to the `textDocument/codeAction` request. They are provided so
994 /// that the server knows which errors are currently presented to the user for
995 /// the given range. There is no guarantee that these accurately reflect the
996 /// error state of the resource. The primary parameter to compute code actions
997 /// is the provided range.
998 std::vector<Diagnostic> diagnostics;
999
1000 /// Requested kind of actions to return.
1001 ///
1002 /// Actions not of this kind are filtered out by the client before being
1003 /// shown. So servers can omit computing them.
1004 std::vector<std::string> only;
1005};
1006bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path);
1007
1008struct CodeActionParams {
1009 /// The document in which the command was invoked.
1010 TextDocumentIdentifier textDocument;
1011
1012 /// The range for which the command was invoked.
1013 Range range;
1014
1015 /// Context carrying additional information.
1016 CodeActionContext context;
1017};
1018bool fromJSON(const llvm::json::Value &, CodeActionParams &, llvm::json::Path);
1019
1020/// The edit should either provide changes or documentChanges. If the client
1021/// can handle versioned document edits and if documentChanges are present,
1022/// the latter are preferred over changes.
1023struct WorkspaceEdit {
1024 /// Holds changes to existing resources.
1025 std::optional<std::map<std::string, std::vector<TextEdit>>> changes;
1026 /// Versioned document edits.
1027 ///
1028 /// If a client neither supports `documentChanges` nor
1029 /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
1030 /// using the `changes` property are supported.
1031 std::optional<std::vector<TextDocumentEdit>> documentChanges;
1032
1033 /// A map of change annotations that can be referenced in
1034 /// AnnotatedTextEdit.
1035 std::map<std::string, ChangeAnnotation> changeAnnotations;
1036};
1037bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path);
1038llvm::json::Value toJSON(const WorkspaceEdit &WE);
1039
1040/// Arguments for the 'applyTweak' command. The server sends these commands as a
1041/// response to the textDocument/codeAction request. The client can later send a
1042/// command back to the server if the user requests to execute a particular code
1043/// tweak.
1044struct TweakArgs {
1045 /// A file provided by the client on a textDocument/codeAction request.
1046 URIForFile file;
1047 /// A selection provided by the client on a textDocument/codeAction request.
1048 Range selection;
1049 /// ID of the tweak that should be executed. Corresponds to Tweak::id().
1050 std::string tweakID;
1051};
1052bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path);
1053llvm::json::Value toJSON(const TweakArgs &A);
1054
1055struct ExecuteCommandParams {
1056 /// The identifier of the actual command handler.
1057 std::string command;
1058
1059 // This is `arguments?: []any` in LSP.
1060 // All clangd's commands accept a single argument (or none => null).
1061 llvm::json::Value argument = nullptr;
1062};
1063bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &,
1064 llvm::json::Path);
1065
1066struct Command : public ExecuteCommandParams {
1067 std::string title;
1068};
1069llvm::json::Value toJSON(const Command &C);
1070
1071/// A code action represents a change that can be performed in code, e.g. to fix
1072/// a problem or to refactor code.
1073///
1074/// A CodeAction must set either `edit` and/or a `command`. If both are
1075/// supplied, the `edit` is applied first, then the `command` is executed.
1076struct CodeAction {
1077 /// A short, human-readable, title for this code action.
1078 std::string title;
1079
1080 /// The kind of the code action.
1081 /// Used to filter code actions.
1082 std::optional<std::string> kind;
1083 const static llvm::StringLiteral QUICKFIX_KIND;
1084 const static llvm::StringLiteral REFACTOR_KIND;
1085 const static llvm::StringLiteral INFO_KIND;
1086
1087 /// The diagnostics that this code action resolves.
1088 std::optional<std::vector<Diagnostic>> diagnostics;
1089
1090 /// Marks this as a preferred action. Preferred actions are used by the
1091 /// `auto fix` command and can be targeted by keybindings.
1092 /// A quick fix should be marked preferred if it properly addresses the
1093 /// underlying error. A refactoring should be marked preferred if it is the
1094 /// most reasonable choice of actions to take.
1095 bool isPreferred = false;
1096
1097 /// The workspace edit this code action performs.
1098 std::optional<WorkspaceEdit> edit;
1099
1100 /// A command this code action executes. If a code action provides an edit
1101 /// and a command, first the edit is executed and then the command.
1102 std::optional<Command> command;
1103};
1104llvm::json::Value toJSON(const CodeAction &);
1105
1106/// Represents programming constructs like variables, classes, interfaces etc.
1107/// that appear in a document. Document symbols can be hierarchical and they
1108/// have two ranges: one that encloses its definition and one that points to its
1109/// most interesting range, e.g. the range of an identifier.
1110struct DocumentSymbol {
1111 /// The name of this symbol.
1112 std::string name;
1113
1114 /// More detail for this symbol, e.g the signature of a function.
1115 std::string detail;
1116
1117 /// The kind of this symbol.
1118 SymbolKind kind;
1119
1120 /// Indicates if this symbol is deprecated.
1121 bool deprecated = false;
1122
1123 /// The range enclosing this symbol not including leading/trailing whitespace
1124 /// but everything else like comments. This information is typically used to
1125 /// determine if the clients cursor is inside the symbol to reveal in the
1126 /// symbol in the UI.
1127 Range range;
1128
1129 /// The range that should be selected and revealed when this symbol is being
1130 /// picked, e.g the name of a function. Must be contained by the `range`.
1131 Range selectionRange;
1132
1133 /// Children of this symbol, e.g. properties of a class.
1134 std::vector<DocumentSymbol> children;
1135};
1136llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S);
1137llvm::json::Value toJSON(const DocumentSymbol &S);
1138
1139/// Represents information about programming constructs like variables, classes,
1140/// interfaces etc.
1141struct SymbolInformation {
1142 /// The name of this symbol.
1143 std::string name;
1144
1145 /// The kind of this symbol.
1146 SymbolKind kind;
1147
1148 /// The location of this symbol.
1149 Location location;
1150
1151 /// The name of the symbol containing this symbol.
1152 std::string containerName;
1153
1154 /// The score that clangd calculates to rank the returned symbols.
1155 /// This excludes the fuzzy-matching score between `name` and the query.
1156 /// (Specifically, the last ::-separated component).
1157 /// This can be used to re-rank results as the user types, using client-side
1158 /// fuzzy-matching (that score should be multiplied with this one).
1159 /// This is a clangd extension, set only for workspace/symbol responses.
1160 std::optional<float> score;
1161};
1162llvm::json::Value toJSON(const SymbolInformation &);
1163llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);
1164
1165/// Represents information about identifier.
1166/// This is returned from textDocument/symbolInfo, which is a clangd extension.
1167struct SymbolDetails {
1168 std::string name;
1169
1170 std::string containerName;
1171
1172 /// Unified Symbol Resolution identifier
1173 /// This is an opaque string uniquely identifying a symbol.
1174 /// Unlike SymbolID, it is variable-length and somewhat human-readable.
1175 /// It is a common representation across several clang tools.
1176 /// (See USRGeneration.h)
1177 std::string USR;
1178
1179 SymbolID ID;
1180
1181 std::optional<Location> declarationRange;
1182
1183 std::optional<Location> definitionRange;
1184};
1185llvm::json::Value toJSON(const SymbolDetails &);
1186llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
1187bool operator==(const SymbolDetails &, const SymbolDetails &);
1188
1189/// The parameters of a Workspace Symbol Request.
1190struct WorkspaceSymbolParams {
1191 /// A query string to filter symbols by.
1192 /// Clients may send an empty string here to request all the symbols.
1193 std::string query;
1194
1195 /// Max results to return, overriding global default. 0 means no limit.
1196 /// Clangd extension.
1197 std::optional<int> limit;
1198};
1199bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &,
1200 llvm::json::Path);
1201
1202struct ApplyWorkspaceEditParams {
1203 WorkspaceEdit edit;
1204};
1205llvm::json::Value toJSON(const ApplyWorkspaceEditParams &);
1206
1207struct ApplyWorkspaceEditResponse {
1208 bool applied = true;
1209 std::optional<std::string> failureReason;
1210};
1211bool fromJSON(const llvm::json::Value &, ApplyWorkspaceEditResponse &,
1212 llvm::json::Path);
1213
1214struct TextDocumentPositionParams {
1215 /// The text document.
1216 TextDocumentIdentifier textDocument;
1217
1218 /// The position inside the text document.
1219 Position position;
1220};
1221bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &,
1222 llvm::json::Path);
1223
1224enum class CompletionTriggerKind {
1225 /// Completion was triggered by typing an identifier (24x7 code
1226 /// complete), manual invocation (e.g Ctrl+Space) or via API.
1227 Invoked = 1,
1228 /// Completion was triggered by a trigger character specified by
1229 /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
1230 TriggerCharacter = 2,
1231 /// Completion was re-triggered as the current completion list is incomplete.
1232 TriggerTriggerForIncompleteCompletions = 3
1233};
1234
1235struct CompletionContext {
1236 /// How the completion was triggered.
1237 CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
1238 /// The trigger character (a single character) that has trigger code complete.
1239 /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
1240 std::string triggerCharacter;
1241};
1242bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path);
1243
1244struct CompletionParams : TextDocumentPositionParams {
1245 CompletionContext context;
1246
1247 /// Max results to return, overriding global default. 0 means no limit.
1248 /// Clangd extension.
1249 std::optional<int> limit;
1250};
1251bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path);
1252
1253struct MarkupContent {
1254 MarkupKind kind = MarkupKind::PlainText;
1255 std::string value;
1256};
1257llvm::json::Value toJSON(const MarkupContent &MC);
1258
1259struct Hover {
1260 /// The hover's content
1261 MarkupContent contents;
1262
1263 /// An optional range is a range inside a text document
1264 /// that is used to visualize a hover, e.g. by changing the background color.
1265 std::optional<Range> range;
1266};
1267llvm::json::Value toJSON(const Hover &H);
1268
1269/// Defines whether the insert text in a completion item should be interpreted
1270/// as plain text or a snippet.
1271enum class InsertTextFormat {
1272 Missing = 0,
1273 /// The primary text to be inserted is treated as a plain string.
1274 PlainText = 1,
1275 /// The primary text to be inserted is treated as a snippet.
1276 ///
1277 /// A snippet can define tab stops and placeholders with `$1`, `$2`
1278 /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end
1279 /// of the snippet. Placeholders with equal identifiers are linked, that is
1280 /// typing in one will update others too.
1281 ///
1282 /// See also:
1283 /// https://github.com/Microsoft/vscode/blob/main/src/vs/editor/contrib/snippet/snippet.md
1284 Snippet = 2,
1285};
1286
1287/// Additional details for a completion item label.
1288struct CompletionItemLabelDetails {
1289 /// An optional string which is rendered less prominently directly after label
1290 /// without any spacing. Should be used for function signatures or type
1291 /// annotations.
1292 std::string detail;
1293
1294 /// An optional string which is rendered less prominently after
1295 /// CompletionItemLabelDetails.detail. Should be used for fully qualified
1296 /// names or file path.
1297 std::string description;
1298};
1299llvm::json::Value toJSON(const CompletionItemLabelDetails &);
1300
1301struct CompletionItem {
1302 /// The label of this completion item. By default also the text that is
1303 /// inserted when selecting this completion.
1304 std::string label;
1305
1306 /// Additional details for the label.
1307 std::optional<CompletionItemLabelDetails> labelDetails;
1308
1309 /// The kind of this completion item. Based of the kind an icon is chosen by
1310 /// the editor.
1311 CompletionItemKind kind = CompletionItemKind::Missing;
1312
1313 /// A human-readable string with additional information about this item, like
1314 /// type or symbol information.
1315 std::string detail;
1316
1317 /// A human-readable string that represents a doc-comment.
1318 std::optional<MarkupContent> documentation;
1319
1320 /// A string that should be used when comparing this item with other items.
1321 /// When `falsy` the label is used.
1322 std::string sortText;
1323
1324 /// A string that should be used when filtering a set of completion items.
1325 /// When `falsy` the label is used.
1326 std::string filterText;
1327
1328 /// A string that should be inserted to a document when selecting this
1329 /// completion. When `falsy` the label is used.
1330 std::string insertText;
1331
1332 /// The format of the insert text. The format applies to both the `insertText`
1333 /// property and the `newText` property of a provided `textEdit`.
1334 InsertTextFormat insertTextFormat = InsertTextFormat::Missing;
1335
1336 /// An edit which is applied to a document when selecting this completion.
1337 /// When an edit is provided `insertText` is ignored.
1338 ///
1339 /// Note: The range of the edit must be a single line range and it must
1340 /// contain the position at which completion has been requested.
1341 std::optional<TextEdit> textEdit;
1342
1343 /// An optional array of additional text edits that are applied when selecting
1344 /// this completion. Edits must not overlap with the main edit nor with
1345 /// themselves.
1346 std::vector<TextEdit> additionalTextEdits;
1347
1348 /// Indicates if this item is deprecated.
1349 bool deprecated = false;
1350
1351 /// The score that clangd calculates to rank the returned completions.
1352 /// This excludes the fuzzy-match between `filterText` and the partial word.
1353 /// This can be used to re-rank results as the user types, using client-side
1354 /// fuzzy-matching (that score should be multiplied with this one).
1355 /// This is a clangd extension.
1356 float score = 0.f;
1357
1358 // TODO: Add custom commitCharacters for some of the completion items. For
1359 // example, it makes sense to use () only for the functions.
1360 // TODO(krasimir): The following optional fields defined by the language
1361 // server protocol are unsupported:
1362 //
1363 // data?: any - A data entry field that is preserved on a completion item
1364 // between a completion and a completion resolve request.
1365};
1366llvm::json::Value toJSON(const CompletionItem &);
1367llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &);
1368
1369/// Remove the labelDetails field (for clients that don't support it).
1370/// Places the information into other fields of the completion item.
1371void removeCompletionLabelDetails(CompletionItem &);
1372
1373bool operator<(const CompletionItem &, const CompletionItem &);
1374
1375/// Represents a collection of completion items to be presented in the editor.
1376struct CompletionList {
1377 /// The list is not complete. Further typing should result in recomputing the
1378 /// list.
1379 bool isIncomplete = false;
1380
1381 /// The completion items.
1382 std::vector<CompletionItem> items;
1383};
1384llvm::json::Value toJSON(const CompletionList &);
1385
1386/// A single parameter of a particular signature.
1387struct ParameterInformation {
1388
1389 /// The label of this parameter. Ignored when labelOffsets is set.
1390 std::string labelString;
1391
1392 /// Inclusive start and exclusive end offsets withing the containing signature
1393 /// label.
1394 /// Offsets are computed by lspLength(), which counts UTF-16 code units by
1395 /// default but that can be overriden, see its documentation for details.
1396 std::optional<std::pair<unsigned, unsigned>> labelOffsets;
1397
1398 /// The documentation of this parameter. Optional.
1399 std::string documentation;
1400};
1401llvm::json::Value toJSON(const ParameterInformation &);
1402
1403/// Represents the signature of something callable.
1404struct SignatureInformation {
1405
1406 /// The label of this signature. Mandatory.
1407 std::string label;
1408
1409 /// The documentation of this signature. Optional.
1410 MarkupContent documentation;
1411
1412 /// The parameters of this signature.
1413 std::vector<ParameterInformation> parameters;
1414};
1415llvm::json::Value toJSON(const SignatureInformation &);
1416llvm::raw_ostream &operator<<(llvm::raw_ostream &,
1417 const SignatureInformation &);
1418
1419/// Represents the signature of a callable.
1420struct SignatureHelp {
1421
1422 /// The resulting signatures.
1423 std::vector<SignatureInformation> signatures;
1424
1425 /// The active signature.
1426 int activeSignature = 0;
1427
1428 /// The active parameter of the active signature.
1429 int activeParameter = 0;
1430
1431 /// Position of the start of the argument list, including opening paren. e.g.
1432 /// foo("first arg", "second arg",
1433 /// ^-argListStart ^-cursor
1434 /// This is a clangd-specific extension, it is only available via C++ API and
1435 /// not currently serialized for the LSP.
1436 Position argListStart;
1437};
1438llvm::json::Value toJSON(const SignatureHelp &);
1439
1440struct RenameParams {
1441 /// The document that was opened.
1442 TextDocumentIdentifier textDocument;
1443
1444 /// The position at which this request was sent.
1445 Position position;
1446
1447 /// The new name of the symbol.
1448 std::string newName;
1449};
1450bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);
1451llvm::json::Value toJSON(const RenameParams &);
1452
1453struct PrepareRenameResult {
1454 /// Range of the string to rename.
1455 Range range;
1456 /// Placeholder text to use in the editor if non-empty.
1457 std::string placeholder;
1458};
1459llvm::json::Value toJSON(const PrepareRenameResult &PRR);
1460
1461enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 };
1462
1463/// A document highlight is a range inside a text document which deserves
1464/// special attention. Usually a document highlight is visualized by changing
1465/// the background color of its range.
1466
1467struct DocumentHighlight {
1468 /// The range this highlight applies to.
1469 Range range;
1470
1471 /// The highlight kind, default is DocumentHighlightKind.Text.
1472 DocumentHighlightKind kind = DocumentHighlightKind::Text;
1473
1474 friend bool operator<(const DocumentHighlight &LHS,
1475 const DocumentHighlight &RHS) {
1476 int LHSKind = static_cast<int>(LHS.kind);
1477 int RHSKind = static_cast<int>(RHS.kind);
1478 return std::tie(args: LHS.range, args&: LHSKind) < std::tie(args: RHS.range, args&: RHSKind);
1479 }
1480
1481 friend bool operator==(const DocumentHighlight &LHS,
1482 const DocumentHighlight &RHS) {
1483 return LHS.kind == RHS.kind && LHS.range == RHS.range;
1484 }
1485};
1486llvm::json::Value toJSON(const DocumentHighlight &DH);
1487llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &);
1488
1489enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 };
1490bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out,
1491 llvm::json::Path);
1492
1493/// The type hierarchy params is an extension of the
1494/// `TextDocumentPositionsParams` with optional properties which can be used to
1495/// eagerly resolve the item when requesting from the server.
1496struct TypeHierarchyPrepareParams : public TextDocumentPositionParams {
1497 /// The hierarchy levels to resolve. `0` indicates no level.
1498 /// This is a clangd extension.
1499 int resolve = 0;
1500
1501 /// The direction of the hierarchy levels to resolve.
1502 /// This is a clangd extension.
1503 TypeHierarchyDirection direction = TypeHierarchyDirection::Parents;
1504};
1505bool fromJSON(const llvm::json::Value &, TypeHierarchyPrepareParams &,
1506 llvm::json::Path);
1507
1508struct TypeHierarchyItem {
1509 /// The name of this item.
1510 std::string name;
1511
1512 /// The kind of this item.
1513 SymbolKind kind;
1514
1515 /// More detail for this item, e.g. the signature of a function.
1516 std::optional<std::string> detail;
1517
1518 /// The resource identifier of this item.
1519 URIForFile uri;
1520
1521 /// The range enclosing this symbol not including leading/trailing whitespace
1522 /// but everything else, e.g. comments and code.
1523 Range range;
1524
1525 /// The range that should be selected and revealed when this symbol is being
1526 /// picked, e.g. the name of a function. Must be contained by the `range`.
1527 Range selectionRange;
1528
1529 /// Used to resolve a client provided item back.
1530 struct ResolveParams {
1531 SymbolID symbolID;
1532 /// std::nullopt means parents aren't resolved and empty is no parents.
1533 std::optional<std::vector<ResolveParams>> parents;
1534 };
1535 /// A data entry field that is preserved between a type hierarchy prepare and
1536 /// supertypes or subtypes requests. It could also be used to identify the
1537 /// type hierarchy in the server, helping improve the performance on resolving
1538 /// supertypes and subtypes.
1539 ResolveParams data;
1540
1541 /// `true` if the hierarchy item is deprecated. Otherwise, `false`.
1542 /// This is a clangd exntesion.
1543 bool deprecated = false;
1544
1545 /// This is a clangd exntesion.
1546 std::optional<std::vector<TypeHierarchyItem>> parents;
1547
1548 /// If this type hierarchy item is resolved, it contains the direct children
1549 /// of the current item. Could be empty if the item does not have any
1550 /// descendants. If not defined, the children have not been resolved.
1551 /// This is a clangd exntesion.
1552 std::optional<std::vector<TypeHierarchyItem>> children;
1553};
1554llvm::json::Value toJSON(const TypeHierarchyItem::ResolveParams &);
1555bool fromJSON(const TypeHierarchyItem::ResolveParams &);
1556llvm::json::Value toJSON(const TypeHierarchyItem &);
1557llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &);
1558bool fromJSON(const llvm::json::Value &, TypeHierarchyItem &, llvm::json::Path);
1559
1560/// Parameters for the `typeHierarchy/resolve` request.
1561struct ResolveTypeHierarchyItemParams {
1562 /// The item to resolve.
1563 TypeHierarchyItem item;
1564
1565 /// The hierarchy levels to resolve. `0` indicates no level.
1566 int resolve;
1567
1568 /// The direction of the hierarchy levels to resolve.
1569 TypeHierarchyDirection direction;
1570};
1571bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &,
1572 llvm::json::Path);
1573
1574enum class SymbolTag { Deprecated = 1 };
1575llvm::json::Value toJSON(SymbolTag);
1576
1577/// The parameter of a `textDocument/prepareCallHierarchy` request.
1578struct CallHierarchyPrepareParams : public TextDocumentPositionParams {};
1579
1580/// Represents programming constructs like functions or constructors
1581/// in the context of call hierarchy.
1582struct CallHierarchyItem {
1583 /// The name of this item.
1584 std::string name;
1585
1586 /// The kind of this item.
1587 SymbolKind kind;
1588
1589 /// Tags for this item.
1590 std::vector<SymbolTag> tags;
1591
1592 /// More detaill for this item, e.g. the signature of a function.
1593 std::string detail;
1594
1595 /// The resource identifier of this item.
1596 URIForFile uri;
1597
1598 /// The range enclosing this symbol not including leading / trailing
1599 /// whitespace but everything else, e.g. comments and code.
1600 Range range;
1601
1602 /// The range that should be selected and revealed when this symbol
1603 /// is being picked, e.g. the name of a function.
1604 /// Must be contained by `Rng`.
1605 Range selectionRange;
1606
1607 /// An optional 'data' field, which can be used to identify a call
1608 /// hierarchy item in an incomingCalls or outgoingCalls request.
1609 std::string data;
1610};
1611llvm::json::Value toJSON(const CallHierarchyItem &);
1612bool fromJSON(const llvm::json::Value &, CallHierarchyItem &, llvm::json::Path);
1613
1614/// The parameter of a `callHierarchy/incomingCalls` request.
1615struct CallHierarchyIncomingCallsParams {
1616 CallHierarchyItem item;
1617};
1618bool fromJSON(const llvm::json::Value &, CallHierarchyIncomingCallsParams &,
1619 llvm::json::Path);
1620
1621/// Represents an incoming call, e.g. a caller of a method or constructor.
1622struct CallHierarchyIncomingCall {
1623 /// The item that makes the call.
1624 CallHierarchyItem from;
1625
1626 /// The range at which the calls appear.
1627 /// This is relative to the caller denoted by `From`.
1628 std::vector<Range> fromRanges;
1629};
1630llvm::json::Value toJSON(const CallHierarchyIncomingCall &);
1631
1632/// The parameter of a `callHierarchy/outgoingCalls` request.
1633struct CallHierarchyOutgoingCallsParams {
1634 CallHierarchyItem item;
1635};
1636bool fromJSON(const llvm::json::Value &, CallHierarchyOutgoingCallsParams &,
1637 llvm::json::Path);
1638
1639/// Represents an outgoing call, e.g. calling a getter from a method or
1640/// a method from a constructor etc.
1641struct CallHierarchyOutgoingCall {
1642 /// The item that is called.
1643 CallHierarchyItem to;
1644
1645 /// The range at which this item is called.
1646 /// This is the range relative to the caller, and not `To`.
1647 std::vector<Range> fromRanges;
1648};
1649llvm::json::Value toJSON(const CallHierarchyOutgoingCall &);
1650
1651/// A parameter literal used in inlay hint requests.
1652struct InlayHintsParams {
1653 /// The text document.
1654 TextDocumentIdentifier textDocument;
1655
1656 /// The visible document range for which inlay hints should be computed.
1657 ///
1658 /// std::nullopt is a clangd extension, which hints for computing hints on the
1659 /// whole file.
1660 std::optional<Range> range;
1661};
1662bool fromJSON(const llvm::json::Value &, InlayHintsParams &, llvm::json::Path);
1663
1664/// Inlay hint kinds.
1665enum class InlayHintKind {
1666 /// An inlay hint that for a type annotation.
1667 ///
1668 /// An example of a type hint is a hint in this position:
1669 /// auto var ^ = expr;
1670 /// which shows the deduced type of the variable.
1671 Type = 1,
1672
1673 /// An inlay hint that is for a parameter.
1674 ///
1675 /// An example of a parameter hint is a hint in this position:
1676 /// func(^arg);
1677 /// which shows the name of the corresponding parameter.
1678 Parameter = 2,
1679
1680 /// A hint before an element of an aggregate braced initializer list,
1681 /// indicating what it is initializing.
1682 /// Pair{^1, ^2};
1683 /// Uses designator syntax, e.g. `.first:`.
1684 /// This is a clangd extension.
1685 Designator = 3,
1686
1687 /// A hint after function, type or namespace definition, indicating the
1688 /// defined symbol name of the definition.
1689 ///
1690 /// An example of a decl name hint in this position:
1691 /// void func() {
1692 /// } ^
1693 /// Uses comment-like syntax like "// func".
1694 /// This is a clangd extension.
1695 BlockEnd = 4,
1696
1697 /// An inlay hint that is for a default argument.
1698 ///
1699 /// An example of a parameter hint for a default argument:
1700 /// void foo(bool A = true);
1701 /// foo(^);
1702 /// Adds an inlay hint "A: true".
1703 /// This is a clangd extension.
1704 DefaultArgument = 6,
1705
1706 /// Other ideas for hints that are not currently implemented:
1707 ///
1708 /// * Chaining hints, showing the types of intermediate expressions
1709 /// in a chain of function calls.
1710 /// * Hints indicating implicit conversions or implicit constructor calls.
1711};
1712llvm::json::Value toJSON(const InlayHintKind &);
1713
1714/// An inlay hint label part allows for interactive and composite labels
1715/// of inlay hints.
1716struct InlayHintLabelPart {
1717
1718 InlayHintLabelPart() = default;
1719
1720 InlayHintLabelPart(std::string value,
1721 std::optional<Location> location = std::nullopt)
1722 : value(std::move(value)), location(std::move(location)) {}
1723
1724 /// The value of this label part.
1725 std::string value;
1726
1727 /// The tooltip text when you hover over this label part. Depending on
1728 /// the client capability `inlayHint.resolveSupport`, clients might resolve
1729 /// this property late using the resolve request.
1730 std::optional<MarkupContent> tooltip;
1731
1732 /// An optional source code location that represents this
1733 /// label part.
1734 ///
1735 /// The editor will use this location for the hover and for code navigation
1736 /// features: This part will become a clickable link that resolves to the
1737 /// definition of the symbol at the given location (not necessarily the
1738 /// location itself), it shows the hover that shows at the given location,
1739 /// and it shows a context menu with further code navigation commands.
1740 ///
1741 /// Depending on the client capability `inlayHint.resolveSupport` clients
1742 /// might resolve this property late using the resolve request.
1743 std::optional<Location> location;
1744
1745 /// An optional command for this label part.
1746 ///
1747 /// Depending on the client capability `inlayHint.resolveSupport` clients
1748 /// might resolve this property late using the resolve request.
1749 std::optional<Command> command;
1750};
1751llvm::json::Value toJSON(const InlayHintLabelPart &);
1752bool operator==(const InlayHintLabelPart &, const InlayHintLabelPart &);
1753bool operator<(const InlayHintLabelPart &, const InlayHintLabelPart &);
1754llvm::raw_ostream &operator<<(llvm::raw_ostream &, const InlayHintLabelPart &);
1755
1756/// Inlay hint information.
1757struct InlayHint {
1758 /// The position of this hint.
1759 Position position;
1760
1761 /// The label of this hint. A human readable string or an array of
1762 /// InlayHintLabelPart label parts.
1763 ///
1764 /// *Note* that neither the string nor the label part can be empty.
1765 std::vector<InlayHintLabelPart> label;
1766
1767 /// The kind of this hint. Can be omitted in which case the client should fall
1768 /// back to a reasonable default.
1769 InlayHintKind kind;
1770
1771 /// Render padding before the hint.
1772 ///
1773 /// Note: Padding should use the editor's background color, not the
1774 /// background color of the hint itself. That means padding can be used
1775 /// to visually align/separate an inlay hint.
1776 bool paddingLeft = false;
1777
1778 /// Render padding after the hint.
1779 ///
1780 /// Note: Padding should use the editor's background color, not the
1781 /// background color of the hint itself. That means padding can be used
1782 /// to visually align/separate an inlay hint.
1783 bool paddingRight = false;
1784
1785 /// The range of source code to which the hint applies.
1786 ///
1787 /// For example, a parameter hint may have the argument as its range.
1788 /// The range allows clients more flexibility of when/how to display the hint.
1789 /// This is an (unserialized) clangd extension.
1790 Range range;
1791
1792 /// Join the label[].value together.
1793 std::string joinLabels() const;
1794};
1795llvm::json::Value toJSON(const InlayHint &);
1796bool operator==(const InlayHint &, const InlayHint &);
1797bool operator<(const InlayHint &, const InlayHint &);
1798llvm::raw_ostream &operator<<(llvm::raw_ostream &, InlayHintKind);
1799
1800struct ReferenceContext {
1801 /// Include the declaration of the current symbol.
1802 bool includeDeclaration = false;
1803};
1804
1805struct ReferenceParams : public TextDocumentPositionParams {
1806 ReferenceContext context;
1807};
1808bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path);
1809
1810/// Clangd extension: indicates the current state of the file in clangd,
1811/// sent from server via the `textDocument/clangd.fileStatus` notification.
1812struct FileStatus {
1813 /// The text document's URI.
1814 URIForFile uri;
1815 /// The human-readable string presents the current state of the file, can be
1816 /// shown in the UI (e.g. status bar).
1817 std::string state;
1818 // FIXME: add detail messages.
1819};
1820llvm::json::Value toJSON(const FileStatus &);
1821
1822/// Specifies a single semantic token in the document.
1823/// This struct is not part of LSP, which just encodes lists of tokens as
1824/// arrays of numbers directly.
1825struct SemanticToken {
1826 /// token line number, relative to the previous token
1827 unsigned deltaLine = 0;
1828 /// token start character, relative to the previous token
1829 /// (relative to 0 or the previous token's start if they are on the same line)
1830 unsigned deltaStart = 0;
1831 /// the length of the token. A token cannot be multiline
1832 unsigned length = 0;
1833 /// will be looked up in `SemanticTokensLegend.tokenTypes`
1834 unsigned tokenType = 0;
1835 /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
1836 unsigned tokenModifiers = 0;
1837};
1838bool operator==(const SemanticToken &, const SemanticToken &);
1839
1840/// A versioned set of tokens.
1841struct SemanticTokens {
1842 // An optional result id. If provided and clients support delta updating
1843 // the client will include the result id in the next semantic token request.
1844 // A server can then instead of computing all semantic tokens again simply
1845 // send a delta.
1846 std::string resultId;
1847
1848 /// The actual tokens.
1849 std::vector<SemanticToken> tokens; // encoded as a flat integer array.
1850};
1851llvm::json::Value toJSON(const SemanticTokens &);
1852
1853/// Body of textDocument/semanticTokens/full request.
1854struct SemanticTokensParams {
1855 /// The text document.
1856 TextDocumentIdentifier textDocument;
1857};
1858bool fromJSON(const llvm::json::Value &, SemanticTokensParams &,
1859 llvm::json::Path);
1860
1861/// Body of textDocument/semanticTokens/full/delta request.
1862/// Requests the changes in semantic tokens since a previous response.
1863struct SemanticTokensDeltaParams {
1864 /// The text document.
1865 TextDocumentIdentifier textDocument;
1866 /// The previous result id.
1867 std::string previousResultId;
1868};
1869bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R,
1870 llvm::json::Path);
1871
1872/// Describes a replacement of a contiguous range of semanticTokens.
1873struct SemanticTokensEdit {
1874 // LSP specifies `start` and `deleteCount` which are relative to the array
1875 // encoding of the previous tokens.
1876 // We use token counts instead, and translate when serializing this struct.
1877 unsigned startToken = 0;
1878 unsigned deleteTokens = 0;
1879 std::vector<SemanticToken> tokens; // encoded as a flat integer array
1880};
1881llvm::json::Value toJSON(const SemanticTokensEdit &);
1882
1883/// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of
1884/// textDocument/semanticTokens/full/delta.
1885struct SemanticTokensOrDelta {
1886 std::string resultId;
1887 /// Set if we computed edits relative to a previous set of tokens.
1888 std::optional<std::vector<SemanticTokensEdit>> edits;
1889 /// Set if we computed a fresh set of tokens.
1890 std::optional<std::vector<SemanticToken>> tokens; // encoded as integer array
1891};
1892llvm::json::Value toJSON(const SemanticTokensOrDelta &);
1893
1894/// Parameters for the inactive regions (server-side) push notification.
1895/// This is a clangd extension.
1896struct InactiveRegionsParams {
1897 /// The textdocument these inactive regions belong to.
1898 TextDocumentIdentifier TextDocument;
1899 /// The inactive regions that should be sent.
1900 std::vector<Range> InactiveRegions;
1901};
1902llvm::json::Value toJSON(const InactiveRegionsParams &InactiveRegions);
1903
1904struct SelectionRangeParams {
1905 /// The text document.
1906 TextDocumentIdentifier textDocument;
1907
1908 /// The positions inside the text document.
1909 std::vector<Position> positions;
1910};
1911bool fromJSON(const llvm::json::Value &, SelectionRangeParams &,
1912 llvm::json::Path);
1913
1914struct SelectionRange {
1915 /**
1916 * The range of this selection range.
1917 */
1918 Range range;
1919 /**
1920 * The parent selection range containing this range. Therefore `parent.range`
1921 * must contain `this.range`.
1922 */
1923 std::unique_ptr<SelectionRange> parent;
1924};
1925llvm::json::Value toJSON(const SelectionRange &);
1926
1927/// Parameters for the document link request.
1928struct DocumentLinkParams {
1929 /// The document to provide document links for.
1930 TextDocumentIdentifier textDocument;
1931};
1932bool fromJSON(const llvm::json::Value &, DocumentLinkParams &,
1933 llvm::json::Path);
1934
1935/// A range in a text document that links to an internal or external resource,
1936/// like another text document or a web site.
1937struct DocumentLink {
1938 /// The range this link applies to.
1939 Range range;
1940
1941 /// The uri this link points to. If missing a resolve request is sent later.
1942 URIForFile target;
1943
1944 // TODO(forster): The following optional fields defined by the language
1945 // server protocol are unsupported:
1946 //
1947 // data?: any - A data entry field that is preserved on a document link
1948 // between a DocumentLinkRequest and a
1949 // DocumentLinkResolveRequest.
1950
1951 friend bool operator==(const DocumentLink &LHS, const DocumentLink &RHS) {
1952 return LHS.range == RHS.range && LHS.target == RHS.target;
1953 }
1954
1955 friend bool operator!=(const DocumentLink &LHS, const DocumentLink &RHS) {
1956 return !(LHS == RHS);
1957 }
1958};
1959llvm::json::Value toJSON(const DocumentLink &DocumentLink);
1960
1961// FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support
1962// per-line-folding editors.
1963struct FoldingRangeParams {
1964 TextDocumentIdentifier textDocument;
1965};
1966bool fromJSON(const llvm::json::Value &, FoldingRangeParams &,
1967 llvm::json::Path);
1968
1969/// Stores information about a region of code that can be folded.
1970struct FoldingRange {
1971 unsigned startLine = 0;
1972 unsigned startCharacter;
1973 unsigned endLine = 0;
1974 unsigned endCharacter;
1975
1976 const static llvm::StringLiteral REGION_KIND;
1977 const static llvm::StringLiteral COMMENT_KIND;
1978 const static llvm::StringLiteral IMPORT_KIND;
1979 std::string kind;
1980};
1981llvm::json::Value toJSON(const FoldingRange &Range);
1982
1983/// Keys starting with an underscore(_) represent leaves, e.g. _total or _self
1984/// for memory usage of whole subtree or only that specific node in bytes. All
1985/// other keys represents children. An example:
1986/// {
1987/// "_self": 0,
1988/// "_total": 8,
1989/// "child1": {
1990/// "_self": 4,
1991/// "_total": 4,
1992/// }
1993/// "child2": {
1994/// "_self": 2,
1995/// "_total": 4,
1996/// "child_deep": {
1997/// "_self": 2,
1998/// "_total": 2,
1999/// }
2000/// }
2001/// }
2002llvm::json::Value toJSON(const MemoryTree &MT);
2003
2004/// Payload for textDocument/ast request.
2005/// This request is a clangd extension.
2006struct ASTParams {
2007 /// The text document.
2008 TextDocumentIdentifier textDocument;
2009
2010 /// The position of the node to be dumped.
2011 /// The highest-level node that entirely contains the range will be returned.
2012 /// If no range is given, the root translation unit node will be returned.
2013 std::optional<Range> range;
2014};
2015bool fromJSON(const llvm::json::Value &, ASTParams &, llvm::json::Path);
2016
2017/// Simplified description of a clang AST node.
2018/// This is clangd's internal representation of C++ code.
2019struct ASTNode {
2020 /// The general kind of node, such as "expression"
2021 /// Corresponds to the base AST node type such as Expr.
2022 std::string role;
2023 /// The specific kind of node this is, such as "BinaryOperator".
2024 /// This is usually a concrete node class (with Expr etc suffix dropped).
2025 /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind).
2026 std::string kind;
2027 /// Brief additional information, such as "||" for the particular operator.
2028 /// The information included depends on the node kind, and may be empty.
2029 std::string detail;
2030 /// A one-line dump of detailed information about the node.
2031 /// This includes role/kind/description information, but is rather cryptic.
2032 /// It is similar to the output from `clang -Xclang -ast-dump`.
2033 /// May be empty for certain types of nodes.
2034 std::string arcana;
2035 /// The range of the original source file covered by this node.
2036 /// May be missing for implicit nodes, or those created by macro expansion.
2037 std::optional<Range> range;
2038 /// Nodes nested within this one, such as the operands of a BinaryOperator.
2039 std::vector<ASTNode> children;
2040};
2041llvm::json::Value toJSON(const ASTNode &);
2042llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &);
2043
2044} // namespace clangd
2045} // namespace clang
2046
2047namespace llvm {
2048
2049template <> struct DenseMapInfo<clang::clangd::Range> {
2050 using Range = clang::clangd::Range;
2051 static inline Range getEmptyKey() {
2052 static clang::clangd::Position Tomb{.line: -1, .character: -1};
2053 static Range R{.start: Tomb, .end: Tomb};
2054 return R;
2055 }
2056 static inline Range getTombstoneKey() {
2057 static clang::clangd::Position Tomb{.line: -2, .character: -2};
2058 static Range R{.start: Tomb, .end: Tomb};
2059 return R;
2060 }
2061 static unsigned getHashValue(const Range &Val) {
2062 return llvm::hash_combine(args: Val.start.line, args: Val.start.character, args: Val.end.line,
2063 args: Val.end.character);
2064 }
2065 static bool isEqual(const Range &LHS, const Range &RHS) {
2066 return std::tie(args: LHS.start, args: LHS.end) == std::tie(args: RHS.start, args: RHS.end);
2067 }
2068};
2069
2070template <> struct format_provider<clang::clangd::Position> {
2071 static void format(const clang::clangd::Position &Pos, raw_ostream &OS,
2072 StringRef Style) {
2073 assert(Style.empty() && "style modifiers for this type are not supported");
2074 OS << Pos;
2075 }
2076};
2077} // namespace llvm
2078
2079// NOLINTEND(readability-identifier-naming)
2080
2081#endif
2082

source code of clang-tools-extra/clangd/Protocol.h