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 44 namespace clang { 45 namespace clangd { 46 47 enum 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. 63 class LSPError : public llvm::ErrorInfo<LSPError> { 64 public: 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 80 bool fromJSON(const llvm::json::Value &, SymbolID &, llvm::json::Path); 81 llvm::json::Value toJSON(const SymbolID &); 82 83 // URI in "file" scheme for a file. 84 struct 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(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 121 private: 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. 128 llvm::json::Value toJSON(const URIForFile &U); 129 bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path); 130 131 struct TextDocumentIdentifier { 132 /// The text document's URI. 133 URIForFile uri; 134 }; 135 llvm::json::Value toJSON(const TextDocumentIdentifier &); 136 bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &, 137 llvm::json::Path); 138 139 struct 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 }; 152 llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &); 153 bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &, 154 llvm::json::Path); 155 156 struct 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(LHS.line, LHS.character) == 167 std::tie(RHS.line, 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(LHS.line, LHS.character) < 174 std::tie(RHS.line, RHS.character); 175 } 176 friend bool operator<=(const Position &LHS, const Position &RHS) { 177 return std::tie(LHS.line, LHS.character) <= 178 std::tie(RHS.line, RHS.character); 179 } 180 }; 181 bool fromJSON(const llvm::json::Value &, Position &, llvm::json::Path); 182 llvm::json::Value toJSON(const Position &); 183 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Position &); 184 185 struct 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(LHS.start, LHS.end) == std::tie(RHS.start, 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(LHS.start, LHS.end) < std::tie(RHS.start, 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 }; 207 bool fromJSON(const llvm::json::Value &, Range &, llvm::json::Path); 208 llvm::json::Value toJSON(const Range &); 209 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Range &); 210 211 struct 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(LHS.uri, LHS.range) < std::tie(RHS.uri, RHS.range); 226 } 227 }; 228 llvm::json::Value toJSON(const Location &); 229 llvm::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`. 233 struct 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 }; 238 llvm::json::Value toJSON(const ReferenceLocation &); 239 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ReferenceLocation &); 240 241 using ChangeAnnotationIdentifier = std::string; 242 // A combination of a LSP standard TextEdit and AnnotatedTextEdit. 243 struct 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 }; 256 inline bool operator==(const TextEdit &L, const TextEdit &R) { 257 return std::tie(L.newText, L.range, L.annotationId) == 258 std::tie(R.newText, R.range, L.annotationId); 259 } 260 bool fromJSON(const llvm::json::Value &, TextEdit &, llvm::json::Path); 261 llvm::json::Value toJSON(const TextEdit &); 262 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &); 263 264 struct 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 }; 277 bool fromJSON(const llvm::json::Value &, ChangeAnnotation &, llvm::json::Path); 278 llvm::json::Value toJSON(const ChangeAnnotation &); 279 280 struct 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 }; 288 bool fromJSON(const llvm::json::Value &, TextDocumentEdit &, llvm::json::Path); 289 llvm::json::Value toJSON(const TextDocumentEdit &); 290 291 struct 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 }; 307 bool fromJSON(const llvm::json::Value &, TextDocumentItem &, llvm::json::Path); 308 309 enum class TraceLevel { 310 Off = 0, 311 Messages = 1, 312 Verbose = 2, 313 }; 314 bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path); 315 316 struct NoParams {}; 317 inline llvm::json::Value toJSON(const NoParams &) { return nullptr; } 318 inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) { 319 return true; 320 } 321 using InitializedParams = NoParams; 322 323 /// Defines how the host (editor) should sync document changes to the language 324 /// server. 325 enum 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. 338 enum 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 }; 366 bool fromJSON(const llvm::json::Value &, CompletionItemKind &, 367 llvm::json::Path); 368 constexpr auto CompletionItemKindMin = 369 static_cast<size_t>(CompletionItemKind::Text); 370 constexpr auto CompletionItemKindMax = 371 static_cast<size_t>(CompletionItemKind::TypeParameter); 372 using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>; 373 bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &, 374 llvm::json::Path); 375 CompletionItemKind 376 adjustKindToCapability(CompletionItemKind Kind, 377 CompletionItemKindBitset &SupportedCompletionItemKinds); 378 379 /// A symbol kind. 380 enum 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 }; 408 bool fromJSON(const llvm::json::Value &, SymbolKind &, llvm::json::Path); 409 constexpr auto SymbolKindMin = static_cast<size_t>(SymbolKind::File); 410 constexpr auto SymbolKindMax = static_cast<size_t>(SymbolKind::TypeParameter); 411 using SymbolKindBitset = std::bitset<SymbolKindMax + 1>; 412 bool fromJSON(const llvm::json::Value &, SymbolKindBitset &, llvm::json::Path); 413 SymbolKind 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 420 SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind); 421 422 // Determines the encoding used to measure offsets and lengths of source in LSP. 423 enum 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 }; 433 llvm::json::Value toJSON(const OffsetEncoding &); 434 bool fromJSON(const llvm::json::Value &, OffsetEncoding &, llvm::json::Path); 435 llvm::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`. 439 enum class MarkupKind { 440 PlainText, 441 Markdown, 442 }; 443 bool fromJSON(const llvm::json::Value &, MarkupKind &, llvm::json::Path); 444 llvm::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. 449 struct 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 }; 571 bool 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. 577 struct ClangdCompileCommand { 578 std::string workingDirectory; 579 std::vector<std::string> compilationCommand; 580 }; 581 bool 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`. 587 struct 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 }; 592 bool 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`. 597 struct 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 }; 611 bool fromJSON(const llvm::json::Value &, InitializationOptions &, 612 llvm::json::Path); 613 614 struct 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 }; 646 bool fromJSON(const llvm::json::Value &, InitializeParams &, llvm::json::Path); 647 648 struct WorkDoneProgressCreateParams { 649 /// The token to be used to report progress. 650 llvm::json::Value token = nullptr; 651 }; 652 llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P); 653 654 template <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 }; 661 template <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. 666 struct 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 }; 689 llvm::json::Value toJSON(const WorkDoneProgressBegin &); 690 691 /// Reporting progress is done using the following payload. 692 struct 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 }; 721 llvm::json::Value toJSON(const WorkDoneProgressReport &); 722 // 723 /// Signals the end of progress reporting. 724 struct WorkDoneProgressEnd { 725 /// Optional, a final message indicating to for example indicate the outcome 726 /// of the operation. 727 std::optional<std::string> message; 728 }; 729 llvm::json::Value toJSON(const WorkDoneProgressEnd &); 730 731 enum 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 }; 741 llvm::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. 745 struct ShowMessageParams { 746 /// The message type. 747 MessageType type = MessageType::Info; 748 /// The actual message. 749 std::string message; 750 }; 751 llvm::json::Value toJSON(const ShowMessageParams &); 752 753 struct DidOpenTextDocumentParams { 754 /// The document that was opened. 755 TextDocumentItem textDocument; 756 }; 757 bool fromJSON(const llvm::json::Value &, DidOpenTextDocumentParams &, 758 llvm::json::Path); 759 760 struct DidCloseTextDocumentParams { 761 /// The document that was closed. 762 TextDocumentIdentifier textDocument; 763 }; 764 bool fromJSON(const llvm::json::Value &, DidCloseTextDocumentParams &, 765 llvm::json::Path); 766 767 struct DidSaveTextDocumentParams { 768 /// The document that was saved. 769 TextDocumentIdentifier textDocument; 770 }; 771 bool fromJSON(const llvm::json::Value &, DidSaveTextDocumentParams &, 772 llvm::json::Path); 773 774 struct 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 }; 784 bool fromJSON(const llvm::json::Value &, TextDocumentContentChangeEvent &, 785 llvm::json::Path); 786 787 struct 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 }; 808 bool fromJSON(const llvm::json::Value &, DidChangeTextDocumentParams &, 809 llvm::json::Path); 810 811 enum 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 }; 819 bool fromJSON(const llvm::json::Value &E, FileChangeType &Out, 820 llvm::json::Path); 821 822 struct FileEvent { 823 /// The file's URI. 824 URIForFile uri; 825 /// The change type. 826 FileChangeType type = FileChangeType::Created; 827 }; 828 bool fromJSON(const llvm::json::Value &, FileEvent &, llvm::json::Path); 829 830 struct DidChangeWatchedFilesParams { 831 /// The actual file events. 832 std::vector<FileEvent> changes; 833 }; 834 bool fromJSON(const llvm::json::Value &, DidChangeWatchedFilesParams &, 835 llvm::json::Path); 836 837 struct DidChangeConfigurationParams { 838 ConfigurationSettings settings; 839 }; 840 bool 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 851 struct DocumentRangeFormattingParams { 852 /// The document to format. 853 TextDocumentIdentifier textDocument; 854 855 /// The range to format 856 Range range; 857 }; 858 bool fromJSON(const llvm::json::Value &, DocumentRangeFormattingParams &, 859 llvm::json::Path); 860 861 struct DocumentOnTypeFormattingParams { 862 /// The document to format. 863 TextDocumentIdentifier textDocument; 864 865 /// The position at which this request was sent. 866 Position position; 867 868 /// The character that has been typed. 869 std::string ch; 870 }; 871 bool fromJSON(const llvm::json::Value &, DocumentOnTypeFormattingParams &, 872 llvm::json::Path); 873 874 struct DocumentFormattingParams { 875 /// The document to format. 876 TextDocumentIdentifier textDocument; 877 }; 878 bool fromJSON(const llvm::json::Value &, DocumentFormattingParams &, 879 llvm::json::Path); 880 881 struct DocumentSymbolParams { 882 // The text document to find symbols in. 883 TextDocumentIdentifier textDocument; 884 }; 885 bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &, 886 llvm::json::Path); 887 888 /// Represents a related message and source code location for a diagnostic. 889 /// This should be used to point to code locations that cause or related to a 890 /// diagnostics, e.g when duplicating a symbol in a scope. 891 struct DiagnosticRelatedInformation { 892 /// The location of this related diagnostic information. 893 Location location; 894 /// The message of this related diagnostic information. 895 std::string message; 896 }; 897 llvm::json::Value toJSON(const DiagnosticRelatedInformation &); 898 899 enum DiagnosticTag { 900 /// Unused or unnecessary code. 901 /// 902 /// Clients are allowed to render diagnostics with this tag faded out instead 903 /// of having an error squiggle. 904 Unnecessary = 1, 905 /// Deprecated or obsolete code. 906 /// 907 /// Clients are allowed to rendered diagnostics with this tag strike through. 908 Deprecated = 2, 909 }; 910 llvm::json::Value toJSON(DiagnosticTag Tag); 911 912 /// Structure to capture a description for an error code. 913 struct CodeDescription { 914 /// An URI to open with more information about the diagnostic error. 915 std::string href; 916 }; 917 llvm::json::Value toJSON(const CodeDescription &); 918 919 struct CodeAction; 920 struct Diagnostic { 921 /// The range at which the message applies. 922 Range range; 923 924 /// The diagnostic's severity. Can be omitted. If omitted it is up to the 925 /// client to interpret diagnostics as error, warning, info or hint. 926 int severity = 0; 927 928 /// The diagnostic's code. Can be omitted. 929 std::string code; 930 931 /// An optional property to describe the error code. 932 std::optional<CodeDescription> codeDescription; 933 934 /// A human-readable string describing the source of this 935 /// diagnostic, e.g. 'typescript' or 'super lint'. 936 std::string source; 937 938 /// The diagnostic's message. 939 std::string message; 940 941 /// Additional metadata about the diagnostic. 942 llvm::SmallVector<DiagnosticTag, 1> tags; 943 944 /// An array of related diagnostic information, e.g. when symbol-names within 945 /// a scope collide all definitions can be marked via this property. 946 std::optional<std::vector<DiagnosticRelatedInformation>> relatedInformation; 947 948 /// The diagnostic's category. Can be omitted. 949 /// An LSP extension that's used to send the name of the category over to the 950 /// client. The category typically describes the compilation stage during 951 /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue". 952 std::optional<std::string> category; 953 954 /// Clangd extension: code actions related to this diagnostic. 955 /// Only with capability textDocument.publishDiagnostics.codeActionsInline. 956 /// (These actions can also be obtained using textDocument/codeAction). 957 std::optional<std::vector<CodeAction>> codeActions; 958 959 /// A data entry field that is preserved between a 960 /// `textDocument/publishDiagnostics` notification 961 /// and `textDocument/codeAction` request. 962 /// Mutating users should associate their data with a unique key they can use 963 /// to retrieve later on. 964 llvm::json::Object data; 965 }; 966 llvm::json::Value toJSON(const Diagnostic &); 967 968 bool fromJSON(const llvm::json::Value &, Diagnostic &, llvm::json::Path); 969 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Diagnostic &); 970 971 struct PublishDiagnosticsParams { 972 /// The URI for which diagnostic information is reported. 973 URIForFile uri; 974 /// An array of diagnostic information items. 975 std::vector<Diagnostic> diagnostics; 976 /// The version number of the document the diagnostics are published for. 977 std::optional<int64_t> version; 978 }; 979 llvm::json::Value toJSON(const PublishDiagnosticsParams &); 980 981 struct CodeActionContext { 982 /// An array of diagnostics known on the client side overlapping the range 983 /// provided to the `textDocument/codeAction` request. They are provided so 984 /// that the server knows which errors are currently presented to the user for 985 /// the given range. There is no guarantee that these accurately reflect the 986 /// error state of the resource. The primary parameter to compute code actions 987 /// is the provided range. 988 std::vector<Diagnostic> diagnostics; 989 990 /// Requested kind of actions to return. 991 /// 992 /// Actions not of this kind are filtered out by the client before being 993 /// shown. So servers can omit computing them. 994 std::vector<std::string> only; 995 }; 996 bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path); 997 998 struct CodeActionParams { 999 /// The document in which the command was invoked. 1000 TextDocumentIdentifier textDocument; 1001 1002 /// The range for which the command was invoked. 1003 Range range; 1004 1005 /// Context carrying additional information. 1006 CodeActionContext context; 1007 }; 1008 bool fromJSON(const llvm::json::Value &, CodeActionParams &, llvm::json::Path); 1009 1010 /// The edit should either provide changes or documentChanges. If the client 1011 /// can handle versioned document edits and if documentChanges are present, 1012 /// the latter are preferred over changes. 1013 struct WorkspaceEdit { 1014 /// Holds changes to existing resources. 1015 std::optional<std::map<std::string, std::vector<TextEdit>>> changes; 1016 /// Versioned document edits. 1017 /// 1018 /// If a client neither supports `documentChanges` nor 1019 /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s 1020 /// using the `changes` property are supported. 1021 std::optional<std::vector<TextDocumentEdit>> documentChanges; 1022 1023 /// A map of change annotations that can be referenced in 1024 /// AnnotatedTextEdit. 1025 std::map<std::string, ChangeAnnotation> changeAnnotations; 1026 }; 1027 bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path); 1028 llvm::json::Value toJSON(const WorkspaceEdit &WE); 1029 1030 /// Arguments for the 'applyTweak' command. The server sends these commands as a 1031 /// response to the textDocument/codeAction request. The client can later send a 1032 /// command back to the server if the user requests to execute a particular code 1033 /// tweak. 1034 struct TweakArgs { 1035 /// A file provided by the client on a textDocument/codeAction request. 1036 URIForFile file; 1037 /// A selection provided by the client on a textDocument/codeAction request. 1038 Range selection; 1039 /// ID of the tweak that should be executed. Corresponds to Tweak::id(). 1040 std::string tweakID; 1041 }; 1042 bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path); 1043 llvm::json::Value toJSON(const TweakArgs &A); 1044 1045 struct ExecuteCommandParams { 1046 /// The identifier of the actual command handler. 1047 std::string command; 1048 1049 // This is `arguments?: []any` in LSP. 1050 // All clangd's commands accept a single argument (or none => null). 1051 llvm::json::Value argument = nullptr; 1052 }; 1053 bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &, 1054 llvm::json::Path); 1055 1056 struct Command : public ExecuteCommandParams { 1057 std::string title; 1058 }; 1059 llvm::json::Value toJSON(const Command &C); 1060 1061 /// A code action represents a change that can be performed in code, e.g. to fix 1062 /// a problem or to refactor code. 1063 /// 1064 /// A CodeAction must set either `edit` and/or a `command`. If both are 1065 /// supplied, the `edit` is applied first, then the `command` is executed. 1066 struct CodeAction { 1067 /// A short, human-readable, title for this code action. 1068 std::string title; 1069 1070 /// The kind of the code action. 1071 /// Used to filter code actions. 1072 std::optional<std::string> kind; 1073 const static llvm::StringLiteral QUICKFIX_KIND; 1074 const static llvm::StringLiteral REFACTOR_KIND; 1075 const static llvm::StringLiteral INFO_KIND; 1076 1077 /// The diagnostics that this code action resolves. 1078 std::optional<std::vector<Diagnostic>> diagnostics; 1079 1080 /// Marks this as a preferred action. Preferred actions are used by the 1081 /// `auto fix` command and can be targeted by keybindings. 1082 /// A quick fix should be marked preferred if it properly addresses the 1083 /// underlying error. A refactoring should be marked preferred if it is the 1084 /// most reasonable choice of actions to take. 1085 bool isPreferred = false; 1086 1087 /// The workspace edit this code action performs. 1088 std::optional<WorkspaceEdit> edit; 1089 1090 /// A command this code action executes. If a code action provides an edit 1091 /// and a command, first the edit is executed and then the command. 1092 std::optional<Command> command; 1093 }; 1094 llvm::json::Value toJSON(const CodeAction &); 1095 1096 /// Represents programming constructs like variables, classes, interfaces etc. 1097 /// that appear in a document. Document symbols can be hierarchical and they 1098 /// have two ranges: one that encloses its definition and one that points to its 1099 /// most interesting range, e.g. the range of an identifier. 1100 struct DocumentSymbol { 1101 /// The name of this symbol. 1102 std::string name; 1103 1104 /// More detail for this symbol, e.g the signature of a function. 1105 std::string detail; 1106 1107 /// The kind of this symbol. 1108 SymbolKind kind; 1109 1110 /// Indicates if this symbol is deprecated. 1111 bool deprecated = false; 1112 1113 /// The range enclosing this symbol not including leading/trailing whitespace 1114 /// but everything else like comments. This information is typically used to 1115 /// determine if the clients cursor is inside the symbol to reveal in the 1116 /// symbol in the UI. 1117 Range range; 1118 1119 /// The range that should be selected and revealed when this symbol is being 1120 /// picked, e.g the name of a function. Must be contained by the `range`. 1121 Range selectionRange; 1122 1123 /// Children of this symbol, e.g. properties of a class. 1124 std::vector<DocumentSymbol> children; 1125 }; 1126 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S); 1127 llvm::json::Value toJSON(const DocumentSymbol &S); 1128 1129 /// Represents information about programming constructs like variables, classes, 1130 /// interfaces etc. 1131 struct SymbolInformation { 1132 /// The name of this symbol. 1133 std::string name; 1134 1135 /// The kind of this symbol. 1136 SymbolKind kind; 1137 1138 /// The location of this symbol. 1139 Location location; 1140 1141 /// The name of the symbol containing this symbol. 1142 std::string containerName; 1143 1144 /// The score that clangd calculates to rank the returned symbols. 1145 /// This excludes the fuzzy-matching score between `name` and the query. 1146 /// (Specifically, the last ::-separated component). 1147 /// This can be used to re-rank results as the user types, using client-side 1148 /// fuzzy-matching (that score should be multiplied with this one). 1149 /// This is a clangd extension, set only for workspace/symbol responses. 1150 std::optional<float> score; 1151 }; 1152 llvm::json::Value toJSON(const SymbolInformation &); 1153 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &); 1154 1155 /// Represents information about identifier. 1156 /// This is returned from textDocument/symbolInfo, which is a clangd extension. 1157 struct SymbolDetails { 1158 std::string name; 1159 1160 std::string containerName; 1161 1162 /// Unified Symbol Resolution identifier 1163 /// This is an opaque string uniquely identifying a symbol. 1164 /// Unlike SymbolID, it is variable-length and somewhat human-readable. 1165 /// It is a common representation across several clang tools. 1166 /// (See USRGeneration.h) 1167 std::string USR; 1168 1169 SymbolID ID; 1170 1171 std::optional<Location> declarationRange; 1172 1173 std::optional<Location> definitionRange; 1174 }; 1175 llvm::json::Value toJSON(const SymbolDetails &); 1176 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &); 1177 bool operator==(const SymbolDetails &, const SymbolDetails &); 1178 1179 /// The parameters of a Workspace Symbol Request. 1180 struct WorkspaceSymbolParams { 1181 /// A query string to filter symbols by. 1182 /// Clients may send an empty string here to request all the symbols. 1183 std::string query; 1184 1185 /// Max results to return, overriding global default. 0 means no limit. 1186 /// Clangd extension. 1187 std::optional<int> limit; 1188 }; 1189 bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &, 1190 llvm::json::Path); 1191 1192 struct ApplyWorkspaceEditParams { 1193 WorkspaceEdit edit; 1194 }; 1195 llvm::json::Value toJSON(const ApplyWorkspaceEditParams &); 1196 1197 struct ApplyWorkspaceEditResponse { 1198 bool applied = true; 1199 std::optional<std::string> failureReason; 1200 }; 1201 bool fromJSON(const llvm::json::Value &, ApplyWorkspaceEditResponse &, 1202 llvm::json::Path); 1203 1204 struct TextDocumentPositionParams { 1205 /// The text document. 1206 TextDocumentIdentifier textDocument; 1207 1208 /// The position inside the text document. 1209 Position position; 1210 }; 1211 bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &, 1212 llvm::json::Path); 1213 1214 enum class CompletionTriggerKind { 1215 /// Completion was triggered by typing an identifier (24x7 code 1216 /// complete), manual invocation (e.g Ctrl+Space) or via API. 1217 Invoked = 1, 1218 /// Completion was triggered by a trigger character specified by 1219 /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`. 1220 TriggerCharacter = 2, 1221 /// Completion was re-triggered as the current completion list is incomplete. 1222 TriggerTriggerForIncompleteCompletions = 3 1223 }; 1224 1225 struct CompletionContext { 1226 /// How the completion was triggered. 1227 CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked; 1228 /// The trigger character (a single character) that has trigger code complete. 1229 /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` 1230 std::string triggerCharacter; 1231 }; 1232 bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path); 1233 1234 struct CompletionParams : TextDocumentPositionParams { 1235 CompletionContext context; 1236 1237 /// Max results to return, overriding global default. 0 means no limit. 1238 /// Clangd extension. 1239 std::optional<int> limit; 1240 }; 1241 bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path); 1242 1243 struct MarkupContent { 1244 MarkupKind kind = MarkupKind::PlainText; 1245 std::string value; 1246 }; 1247 llvm::json::Value toJSON(const MarkupContent &MC); 1248 1249 struct Hover { 1250 /// The hover's content 1251 MarkupContent contents; 1252 1253 /// An optional range is a range inside a text document 1254 /// that is used to visualize a hover, e.g. by changing the background color. 1255 std::optional<Range> range; 1256 }; 1257 llvm::json::Value toJSON(const Hover &H); 1258 1259 /// Defines whether the insert text in a completion item should be interpreted 1260 /// as plain text or a snippet. 1261 enum class InsertTextFormat { 1262 Missing = 0, 1263 /// The primary text to be inserted is treated as a plain string. 1264 PlainText = 1, 1265 /// The primary text to be inserted is treated as a snippet. 1266 /// 1267 /// A snippet can define tab stops and placeholders with `$1`, `$2` 1268 /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end 1269 /// of the snippet. Placeholders with equal identifiers are linked, that is 1270 /// typing in one will update others too. 1271 /// 1272 /// See also: 1273 /// https://github.com/Microsoft/vscode/blob/main/src/vs/editor/contrib/snippet/snippet.md 1274 Snippet = 2, 1275 }; 1276 1277 /// Additional details for a completion item label. 1278 struct CompletionItemLabelDetails { 1279 /// An optional string which is rendered less prominently directly after label 1280 /// without any spacing. Should be used for function signatures or type 1281 /// annotations. 1282 std::string detail; 1283 1284 /// An optional string which is rendered less prominently after 1285 /// CompletionItemLabelDetails.detail. Should be used for fully qualified 1286 /// names or file path. 1287 std::string description; 1288 }; 1289 llvm::json::Value toJSON(const CompletionItemLabelDetails &); 1290 1291 struct CompletionItem { 1292 /// The label of this completion item. By default also the text that is 1293 /// inserted when selecting this completion. 1294 std::string label; 1295 1296 /// Additional details for the label. 1297 std::optional<CompletionItemLabelDetails> labelDetails; 1298 1299 /// The kind of this completion item. Based of the kind an icon is chosen by 1300 /// the editor. 1301 CompletionItemKind kind = CompletionItemKind::Missing; 1302 1303 /// A human-readable string with additional information about this item, like 1304 /// type or symbol information. 1305 std::string detail; 1306 1307 /// A human-readable string that represents a doc-comment. 1308 std::optional<MarkupContent> documentation; 1309 1310 /// A string that should be used when comparing this item with other items. 1311 /// When `falsy` the label is used. 1312 std::string sortText; 1313 1314 /// A string that should be used when filtering a set of completion items. 1315 /// When `falsy` the label is used. 1316 std::string filterText; 1317 1318 /// A string that should be inserted to a document when selecting this 1319 /// completion. When `falsy` the label is used. 1320 std::string insertText; 1321 1322 /// The format of the insert text. The format applies to both the `insertText` 1323 /// property and the `newText` property of a provided `textEdit`. 1324 InsertTextFormat insertTextFormat = InsertTextFormat::Missing; 1325 1326 /// An edit which is applied to a document when selecting this completion. 1327 /// When an edit is provided `insertText` is ignored. 1328 /// 1329 /// Note: The range of the edit must be a single line range and it must 1330 /// contain the position at which completion has been requested. 1331 std::optional<TextEdit> textEdit; 1332 1333 /// An optional array of additional text edits that are applied when selecting 1334 /// this completion. Edits must not overlap with the main edit nor with 1335 /// themselves. 1336 std::vector<TextEdit> additionalTextEdits; 1337 1338 /// Indicates if this item is deprecated. 1339 bool deprecated = false; 1340 1341 /// The score that clangd calculates to rank the returned completions. 1342 /// This excludes the fuzzy-match between `filterText` and the partial word. 1343 /// This can be used to re-rank results as the user types, using client-side 1344 /// fuzzy-matching (that score should be multiplied with this one). 1345 /// This is a clangd extension. 1346 float score = 0.f; 1347 1348 // TODO: Add custom commitCharacters for some of the completion items. For 1349 // example, it makes sense to use () only for the functions. 1350 // TODO(krasimir): The following optional fields defined by the language 1351 // server protocol are unsupported: 1352 // 1353 // data?: any - A data entry field that is preserved on a completion item 1354 // between a completion and a completion resolve request. 1355 }; 1356 llvm::json::Value toJSON(const CompletionItem &); 1357 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &); 1358 1359 /// Remove the labelDetails field (for clients that don't support it). 1360 /// Places the information into other fields of the completion item. 1361 void removeCompletionLabelDetails(CompletionItem &); 1362 1363 bool operator<(const CompletionItem &, const CompletionItem &); 1364 1365 /// Represents a collection of completion items to be presented in the editor. 1366 struct CompletionList { 1367 /// The list is not complete. Further typing should result in recomputing the 1368 /// list. 1369 bool isIncomplete = false; 1370 1371 /// The completion items. 1372 std::vector<CompletionItem> items; 1373 }; 1374 llvm::json::Value toJSON(const CompletionList &); 1375 1376 /// A single parameter of a particular signature. 1377 struct ParameterInformation { 1378 1379 /// The label of this parameter. Ignored when labelOffsets is set. 1380 std::string labelString; 1381 1382 /// Inclusive start and exclusive end offsets withing the containing signature 1383 /// label. 1384 /// Offsets are computed by lspLength(), which counts UTF-16 code units by 1385 /// default but that can be overriden, see its documentation for details. 1386 std::optional<std::pair<unsigned, unsigned>> labelOffsets; 1387 1388 /// The documentation of this parameter. Optional. 1389 std::string documentation; 1390 }; 1391 llvm::json::Value toJSON(const ParameterInformation &); 1392 1393 /// Represents the signature of something callable. 1394 struct SignatureInformation { 1395 1396 /// The label of this signature. Mandatory. 1397 std::string label; 1398 1399 /// The documentation of this signature. Optional. 1400 MarkupContent documentation; 1401 1402 /// The parameters of this signature. 1403 std::vector<ParameterInformation> parameters; 1404 }; 1405 llvm::json::Value toJSON(const SignatureInformation &); 1406 llvm::raw_ostream &operator<<(llvm::raw_ostream &, 1407 const SignatureInformation &); 1408 1409 /// Represents the signature of a callable. 1410 struct SignatureHelp { 1411 1412 /// The resulting signatures. 1413 std::vector<SignatureInformation> signatures; 1414 1415 /// The active signature. 1416 int activeSignature = 0; 1417 1418 /// The active parameter of the active signature. 1419 int activeParameter = 0; 1420 1421 /// Position of the start of the argument list, including opening paren. e.g. 1422 /// foo("first arg", "second arg", 1423 /// ^-argListStart ^-cursor 1424 /// This is a clangd-specific extension, it is only available via C++ API and 1425 /// not currently serialized for the LSP. 1426 Position argListStart; 1427 }; 1428 llvm::json::Value toJSON(const SignatureHelp &); 1429 1430 struct RenameParams { 1431 /// The document that was opened. 1432 TextDocumentIdentifier textDocument; 1433 1434 /// The position at which this request was sent. 1435 Position position; 1436 1437 /// The new name of the symbol. 1438 std::string newName; 1439 }; 1440 bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path); 1441 llvm::json::Value toJSON(const RenameParams &); 1442 1443 struct PrepareRenameResult { 1444 /// Range of the string to rename. 1445 Range range; 1446 /// Placeholder text to use in the editor if non-empty. 1447 std::string placeholder; 1448 }; 1449 llvm::json::Value toJSON(const PrepareRenameResult &PRR); 1450 1451 enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 }; 1452 1453 /// A document highlight is a range inside a text document which deserves 1454 /// special attention. Usually a document highlight is visualized by changing 1455 /// the background color of its range. 1456 1457 struct DocumentHighlight { 1458 /// The range this highlight applies to. 1459 Range range; 1460 1461 /// The highlight kind, default is DocumentHighlightKind.Text. 1462 DocumentHighlightKind kind = DocumentHighlightKind::Text; 1463 1464 friend bool operator<(const DocumentHighlight &LHS, 1465 const DocumentHighlight &RHS) { 1466 int LHSKind = static_cast<int>(LHS.kind); 1467 int RHSKind = static_cast<int>(RHS.kind); 1468 return std::tie(LHS.range, LHSKind) < std::tie(RHS.range, RHSKind); 1469 } 1470 1471 friend bool operator==(const DocumentHighlight &LHS, 1472 const DocumentHighlight &RHS) { 1473 return LHS.kind == RHS.kind && LHS.range == RHS.range; 1474 } 1475 }; 1476 llvm::json::Value toJSON(const DocumentHighlight &DH); 1477 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &); 1478 1479 enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 }; 1480 bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out, 1481 llvm::json::Path); 1482 1483 /// The type hierarchy params is an extension of the 1484 /// `TextDocumentPositionsParams` with optional properties which can be used to 1485 /// eagerly resolve the item when requesting from the server. 1486 struct TypeHierarchyPrepareParams : public TextDocumentPositionParams { 1487 /// The hierarchy levels to resolve. `0` indicates no level. 1488 /// This is a clangd extension. 1489 int resolve = 0; 1490 1491 /// The direction of the hierarchy levels to resolve. 1492 /// This is a clangd extension. 1493 TypeHierarchyDirection direction = TypeHierarchyDirection::Parents; 1494 }; 1495 bool fromJSON(const llvm::json::Value &, TypeHierarchyPrepareParams &, 1496 llvm::json::Path); 1497 1498 struct TypeHierarchyItem { 1499 /// The name of this item. 1500 std::string name; 1501 1502 /// The kind of this item. 1503 SymbolKind kind; 1504 1505 /// More detail for this item, e.g. the signature of a function. 1506 std::optional<std::string> detail; 1507 1508 /// The resource identifier of this item. 1509 URIForFile uri; 1510 1511 /// The range enclosing this symbol not including leading/trailing whitespace 1512 /// but everything else, e.g. comments and code. 1513 Range range; 1514 1515 /// The range that should be selected and revealed when this symbol is being 1516 /// picked, e.g. the name of a function. Must be contained by the `range`. 1517 Range selectionRange; 1518 1519 /// Used to resolve a client provided item back. 1520 struct ResolveParams { 1521 SymbolID symbolID; 1522 /// std::nullopt means parents aren't resolved and empty is no parents. 1523 std::optional<std::vector<ResolveParams>> parents; 1524 }; 1525 /// A data entry field that is preserved between a type hierarchy prepare and 1526 /// supertypes or subtypes requests. It could also be used to identify the 1527 /// type hierarchy in the server, helping improve the performance on resolving 1528 /// supertypes and subtypes. 1529 ResolveParams data; 1530 1531 /// `true` if the hierarchy item is deprecated. Otherwise, `false`. 1532 /// This is a clangd exntesion. 1533 bool deprecated = false; 1534 1535 /// This is a clangd exntesion. 1536 std::optional<std::vector<TypeHierarchyItem>> parents; 1537 1538 /// If this type hierarchy item is resolved, it contains the direct children 1539 /// of the current item. Could be empty if the item does not have any 1540 /// descendants. If not defined, the children have not been resolved. 1541 /// This is a clangd exntesion. 1542 std::optional<std::vector<TypeHierarchyItem>> children; 1543 }; 1544 llvm::json::Value toJSON(const TypeHierarchyItem::ResolveParams &); 1545 bool fromJSON(const TypeHierarchyItem::ResolveParams &); 1546 llvm::json::Value toJSON(const TypeHierarchyItem &); 1547 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &); 1548 bool fromJSON(const llvm::json::Value &, TypeHierarchyItem &, llvm::json::Path); 1549 1550 /// Parameters for the `typeHierarchy/resolve` request. 1551 struct ResolveTypeHierarchyItemParams { 1552 /// The item to resolve. 1553 TypeHierarchyItem item; 1554 1555 /// The hierarchy levels to resolve. `0` indicates no level. 1556 int resolve; 1557 1558 /// The direction of the hierarchy levels to resolve. 1559 TypeHierarchyDirection direction; 1560 }; 1561 bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &, 1562 llvm::json::Path); 1563 1564 enum class SymbolTag { Deprecated = 1 }; 1565 llvm::json::Value toJSON(SymbolTag); 1566 1567 /// The parameter of a `textDocument/prepareCallHierarchy` request. 1568 struct CallHierarchyPrepareParams : public TextDocumentPositionParams {}; 1569 1570 /// Represents programming constructs like functions or constructors 1571 /// in the context of call hierarchy. 1572 struct CallHierarchyItem { 1573 /// The name of this item. 1574 std::string name; 1575 1576 /// The kind of this item. 1577 SymbolKind kind; 1578 1579 /// Tags for this item. 1580 std::vector<SymbolTag> tags; 1581 1582 /// More detaill for this item, e.g. the signature of a function. 1583 std::string detail; 1584 1585 /// The resource identifier of this item. 1586 URIForFile uri; 1587 1588 /// The range enclosing this symbol not including leading / trailing 1589 /// whitespace but everything else, e.g. comments and code. 1590 Range range; 1591 1592 /// The range that should be selected and revealed when this symbol 1593 /// is being picked, e.g. the name of a function. 1594 /// Must be contained by `Rng`. 1595 Range selectionRange; 1596 1597 /// An optional 'data' field, which can be used to identify a call 1598 /// hierarchy item in an incomingCalls or outgoingCalls request. 1599 std::string data; 1600 }; 1601 llvm::json::Value toJSON(const CallHierarchyItem &); 1602 bool fromJSON(const llvm::json::Value &, CallHierarchyItem &, llvm::json::Path); 1603 1604 /// The parameter of a `callHierarchy/incomingCalls` request. 1605 struct CallHierarchyIncomingCallsParams { 1606 CallHierarchyItem item; 1607 }; 1608 bool fromJSON(const llvm::json::Value &, CallHierarchyIncomingCallsParams &, 1609 llvm::json::Path); 1610 1611 /// Represents an incoming call, e.g. a caller of a method or constructor. 1612 struct CallHierarchyIncomingCall { 1613 /// The item that makes the call. 1614 CallHierarchyItem from; 1615 1616 /// The range at which the calls appear. 1617 /// This is relative to the caller denoted by `From`. 1618 std::vector<Range> fromRanges; 1619 }; 1620 llvm::json::Value toJSON(const CallHierarchyIncomingCall &); 1621 1622 /// The parameter of a `callHierarchy/outgoingCalls` request. 1623 struct CallHierarchyOutgoingCallsParams { 1624 CallHierarchyItem item; 1625 }; 1626 bool fromJSON(const llvm::json::Value &, CallHierarchyOutgoingCallsParams &, 1627 llvm::json::Path); 1628 1629 /// Represents an outgoing call, e.g. calling a getter from a method or 1630 /// a method from a constructor etc. 1631 struct CallHierarchyOutgoingCall { 1632 /// The item that is called. 1633 CallHierarchyItem to; 1634 1635 /// The range at which this item is called. 1636 /// This is the range relative to the caller, and not `To`. 1637 std::vector<Range> fromRanges; 1638 }; 1639 llvm::json::Value toJSON(const CallHierarchyOutgoingCall &); 1640 1641 /// A parameter literal used in inlay hint requests. 1642 struct InlayHintsParams { 1643 /// The text document. 1644 TextDocumentIdentifier textDocument; 1645 1646 /// The visible document range for which inlay hints should be computed. 1647 /// 1648 /// std::nullopt is a clangd extension, which hints for computing hints on the 1649 /// whole file. 1650 std::optional<Range> range; 1651 }; 1652 bool fromJSON(const llvm::json::Value &, InlayHintsParams &, llvm::json::Path); 1653 1654 /// Inlay hint kinds. 1655 enum class InlayHintKind { 1656 /// An inlay hint that for a type annotation. 1657 /// 1658 /// An example of a type hint is a hint in this position: 1659 /// auto var ^ = expr; 1660 /// which shows the deduced type of the variable. 1661 Type = 1, 1662 1663 /// An inlay hint that is for a parameter. 1664 /// 1665 /// An example of a parameter hint is a hint in this position: 1666 /// func(^arg); 1667 /// which shows the name of the corresponding parameter. 1668 Parameter = 2, 1669 1670 /// A hint before an element of an aggregate braced initializer list, 1671 /// indicating what it is initializing. 1672 /// Pair{^1, ^2}; 1673 /// Uses designator syntax, e.g. `.first:`. 1674 /// This is a clangd extension. 1675 Designator = 3, 1676 1677 /// A hint after function, type or namespace definition, indicating the 1678 /// defined symbol name of the definition. 1679 /// 1680 /// An example of a decl name hint in this position: 1681 /// void func() { 1682 /// } ^ 1683 /// Uses comment-like syntax like "// func". 1684 /// This is a clangd extension. 1685 BlockEnd = 4, 1686 1687 /// An inlay hint that is for a default argument. 1688 /// 1689 /// An example of a parameter hint for a default argument: 1690 /// void foo(bool A = true); 1691 /// foo(^); 1692 /// Adds an inlay hint "A: true". 1693 /// This is a clangd extension. 1694 DefaultArgument = 6, 1695 1696 /// Other ideas for hints that are not currently implemented: 1697 /// 1698 /// * Chaining hints, showing the types of intermediate expressions 1699 /// in a chain of function calls. 1700 /// * Hints indicating implicit conversions or implicit constructor calls. 1701 }; 1702 llvm::json::Value toJSON(const InlayHintKind &); 1703 1704 /// An inlay hint label part allows for interactive and composite labels 1705 /// of inlay hints. 1706 struct InlayHintLabelPart { 1707 1708 InlayHintLabelPart() = default; 1709 1710 InlayHintLabelPart(std::string value, 1711 std::optional<Location> location = std::nullopt) 1712 : value(std::move(value)), location(std::move(location)) {} 1713 1714 /// The value of this label part. 1715 std::string value; 1716 1717 /// The tooltip text when you hover over this label part. Depending on 1718 /// the client capability `inlayHint.resolveSupport`, clients might resolve 1719 /// this property late using the resolve request. 1720 std::optional<MarkupContent> tooltip; 1721 1722 /// An optional source code location that represents this 1723 /// label part. 1724 /// 1725 /// The editor will use this location for the hover and for code navigation 1726 /// features: This part will become a clickable link that resolves to the 1727 /// definition of the symbol at the given location (not necessarily the 1728 /// location itself), it shows the hover that shows at the given location, 1729 /// and it shows a context menu with further code navigation commands. 1730 /// 1731 /// Depending on the client capability `inlayHint.resolveSupport` clients 1732 /// might resolve this property late using the resolve request. 1733 std::optional<Location> location; 1734 1735 /// An optional command for this label part. 1736 /// 1737 /// Depending on the client capability `inlayHint.resolveSupport` clients 1738 /// might resolve this property late using the resolve request. 1739 std::optional<Command> command; 1740 }; 1741 llvm::json::Value toJSON(const InlayHintLabelPart &); 1742 bool operator==(const InlayHintLabelPart &, const InlayHintLabelPart &); 1743 bool operator<(const InlayHintLabelPart &, const InlayHintLabelPart &); 1744 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const InlayHintLabelPart &); 1745 1746 /// Inlay hint information. 1747 struct InlayHint { 1748 /// The position of this hint. 1749 Position position; 1750 1751 /// The label of this hint. A human readable string or an array of 1752 /// InlayHintLabelPart label parts. 1753 /// 1754 /// *Note* that neither the string nor the label part can be empty. 1755 std::vector<InlayHintLabelPart> label; 1756 1757 /// The kind of this hint. Can be omitted in which case the client should fall 1758 /// back to a reasonable default. 1759 InlayHintKind kind; 1760 1761 /// Render padding before the hint. 1762 /// 1763 /// Note: Padding should use the editor's background color, not the 1764 /// background color of the hint itself. That means padding can be used 1765 /// to visually align/separate an inlay hint. 1766 bool paddingLeft = false; 1767 1768 /// Render padding after the hint. 1769 /// 1770 /// Note: Padding should use the editor's background color, not the 1771 /// background color of the hint itself. That means padding can be used 1772 /// to visually align/separate an inlay hint. 1773 bool paddingRight = false; 1774 1775 /// The range of source code to which the hint applies. 1776 /// 1777 /// For example, a parameter hint may have the argument as its range. 1778 /// The range allows clients more flexibility of when/how to display the hint. 1779 /// This is an (unserialized) clangd extension. 1780 Range range; 1781 1782 /// Join the label[].value together. 1783 std::string joinLabels() const; 1784 }; 1785 llvm::json::Value toJSON(const InlayHint &); 1786 bool operator==(const InlayHint &, const InlayHint &); 1787 bool operator<(const InlayHint &, const InlayHint &); 1788 llvm::raw_ostream &operator<<(llvm::raw_ostream &, InlayHintKind); 1789 1790 struct ReferenceContext { 1791 /// Include the declaration of the current symbol. 1792 bool includeDeclaration = false; 1793 }; 1794 1795 struct ReferenceParams : public TextDocumentPositionParams { 1796 ReferenceContext context; 1797 }; 1798 bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path); 1799 1800 /// Clangd extension: indicates the current state of the file in clangd, 1801 /// sent from server via the `textDocument/clangd.fileStatus` notification. 1802 struct FileStatus { 1803 /// The text document's URI. 1804 URIForFile uri; 1805 /// The human-readable string presents the current state of the file, can be 1806 /// shown in the UI (e.g. status bar). 1807 std::string state; 1808 // FIXME: add detail messages. 1809 }; 1810 llvm::json::Value toJSON(const FileStatus &); 1811 1812 /// Specifies a single semantic token in the document. 1813 /// This struct is not part of LSP, which just encodes lists of tokens as 1814 /// arrays of numbers directly. 1815 struct SemanticToken { 1816 /// token line number, relative to the previous token 1817 unsigned deltaLine = 0; 1818 /// token start character, relative to the previous token 1819 /// (relative to 0 or the previous token's start if they are on the same line) 1820 unsigned deltaStart = 0; 1821 /// the length of the token. A token cannot be multiline 1822 unsigned length = 0; 1823 /// will be looked up in `SemanticTokensLegend.tokenTypes` 1824 unsigned tokenType = 0; 1825 /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` 1826 unsigned tokenModifiers = 0; 1827 }; 1828 bool operator==(const SemanticToken &, const SemanticToken &); 1829 1830 /// A versioned set of tokens. 1831 struct SemanticTokens { 1832 // An optional result id. If provided and clients support delta updating 1833 // the client will include the result id in the next semantic token request. 1834 // A server can then instead of computing all semantic tokens again simply 1835 // send a delta. 1836 std::string resultId; 1837 1838 /// The actual tokens. 1839 std::vector<SemanticToken> tokens; // encoded as a flat integer array. 1840 }; 1841 llvm::json::Value toJSON(const SemanticTokens &); 1842 1843 /// Body of textDocument/semanticTokens/full request. 1844 struct SemanticTokensParams { 1845 /// The text document. 1846 TextDocumentIdentifier textDocument; 1847 }; 1848 bool fromJSON(const llvm::json::Value &, SemanticTokensParams &, 1849 llvm::json::Path); 1850 1851 /// Body of textDocument/semanticTokens/full/delta request. 1852 /// Requests the changes in semantic tokens since a previous response. 1853 struct SemanticTokensDeltaParams { 1854 /// The text document. 1855 TextDocumentIdentifier textDocument; 1856 /// The previous result id. 1857 std::string previousResultId; 1858 }; 1859 bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R, 1860 llvm::json::Path); 1861 1862 /// Describes a replacement of a contiguous range of semanticTokens. 1863 struct SemanticTokensEdit { 1864 // LSP specifies `start` and `deleteCount` which are relative to the array 1865 // encoding of the previous tokens. 1866 // We use token counts instead, and translate when serializing this struct. 1867 unsigned startToken = 0; 1868 unsigned deleteTokens = 0; 1869 std::vector<SemanticToken> tokens; // encoded as a flat integer array 1870 }; 1871 llvm::json::Value toJSON(const SemanticTokensEdit &); 1872 1873 /// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of 1874 /// textDocument/semanticTokens/full/delta. 1875 struct SemanticTokensOrDelta { 1876 std::string resultId; 1877 /// Set if we computed edits relative to a previous set of tokens. 1878 std::optional<std::vector<SemanticTokensEdit>> edits; 1879 /// Set if we computed a fresh set of tokens. 1880 std::optional<std::vector<SemanticToken>> tokens; // encoded as integer array 1881 }; 1882 llvm::json::Value toJSON(const SemanticTokensOrDelta &); 1883 1884 /// Parameters for the inactive regions (server-side) push notification. 1885 /// This is a clangd extension. 1886 struct InactiveRegionsParams { 1887 /// The textdocument these inactive regions belong to. 1888 TextDocumentIdentifier TextDocument; 1889 /// The inactive regions that should be sent. 1890 std::vector<Range> InactiveRegions; 1891 }; 1892 llvm::json::Value toJSON(const InactiveRegionsParams &InactiveRegions); 1893 1894 struct SelectionRangeParams { 1895 /// The text document. 1896 TextDocumentIdentifier textDocument; 1897 1898 /// The positions inside the text document. 1899 std::vector<Position> positions; 1900 }; 1901 bool fromJSON(const llvm::json::Value &, SelectionRangeParams &, 1902 llvm::json::Path); 1903 1904 struct SelectionRange { 1905 /** 1906 * The range of this selection range. 1907 */ 1908 Range range; 1909 /** 1910 * The parent selection range containing this range. Therefore `parent.range` 1911 * must contain `this.range`. 1912 */ 1913 std::unique_ptr<SelectionRange> parent; 1914 }; 1915 llvm::json::Value toJSON(const SelectionRange &); 1916 1917 /// Parameters for the document link request. 1918 struct DocumentLinkParams { 1919 /// The document to provide document links for. 1920 TextDocumentIdentifier textDocument; 1921 }; 1922 bool fromJSON(const llvm::json::Value &, DocumentLinkParams &, 1923 llvm::json::Path); 1924 1925 /// A range in a text document that links to an internal or external resource, 1926 /// like another text document or a web site. 1927 struct DocumentLink { 1928 /// The range this link applies to. 1929 Range range; 1930 1931 /// The uri this link points to. If missing a resolve request is sent later. 1932 URIForFile target; 1933 1934 // TODO(forster): The following optional fields defined by the language 1935 // server protocol are unsupported: 1936 // 1937 // data?: any - A data entry field that is preserved on a document link 1938 // between a DocumentLinkRequest and a 1939 // DocumentLinkResolveRequest. 1940 1941 friend bool operator==(const DocumentLink &LHS, const DocumentLink &RHS) { 1942 return LHS.range == RHS.range && LHS.target == RHS.target; 1943 } 1944 1945 friend bool operator!=(const DocumentLink &LHS, const DocumentLink &RHS) { 1946 return !(LHS == RHS); 1947 } 1948 }; 1949 llvm::json::Value toJSON(const DocumentLink &DocumentLink); 1950 1951 // FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support 1952 // per-line-folding editors. 1953 struct FoldingRangeParams { 1954 TextDocumentIdentifier textDocument; 1955 }; 1956 bool fromJSON(const llvm::json::Value &, FoldingRangeParams &, 1957 llvm::json::Path); 1958 1959 /// Stores information about a region of code that can be folded. 1960 struct FoldingRange { 1961 unsigned startLine = 0; 1962 unsigned startCharacter; 1963 unsigned endLine = 0; 1964 unsigned endCharacter; 1965 1966 const static llvm::StringLiteral REGION_KIND; 1967 const static llvm::StringLiteral COMMENT_KIND; 1968 const static llvm::StringLiteral IMPORT_KIND; 1969 std::string kind; 1970 }; 1971 llvm::json::Value toJSON(const FoldingRange &Range); 1972 1973 /// Keys starting with an underscore(_) represent leaves, e.g. _total or _self 1974 /// for memory usage of whole subtree or only that specific node in bytes. All 1975 /// other keys represents children. An example: 1976 /// { 1977 /// "_self": 0, 1978 /// "_total": 8, 1979 /// "child1": { 1980 /// "_self": 4, 1981 /// "_total": 4, 1982 /// } 1983 /// "child2": { 1984 /// "_self": 2, 1985 /// "_total": 4, 1986 /// "child_deep": { 1987 /// "_self": 2, 1988 /// "_total": 2, 1989 /// } 1990 /// } 1991 /// } 1992 llvm::json::Value toJSON(const MemoryTree &MT); 1993 1994 /// Payload for textDocument/ast request. 1995 /// This request is a clangd extension. 1996 struct ASTParams { 1997 /// The text document. 1998 TextDocumentIdentifier textDocument; 1999 2000 /// The position of the node to be dumped. 2001 /// The highest-level node that entirely contains the range will be returned. 2002 /// If no range is given, the root translation unit node will be returned. 2003 std::optional<Range> range; 2004 }; 2005 bool fromJSON(const llvm::json::Value &, ASTParams &, llvm::json::Path); 2006 2007 /// Simplified description of a clang AST node. 2008 /// This is clangd's internal representation of C++ code. 2009 struct ASTNode { 2010 /// The general kind of node, such as "expression" 2011 /// Corresponds to the base AST node type such as Expr. 2012 std::string role; 2013 /// The specific kind of node this is, such as "BinaryOperator". 2014 /// This is usually a concrete node class (with Expr etc suffix dropped). 2015 /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind). 2016 std::string kind; 2017 /// Brief additional information, such as "||" for the particular operator. 2018 /// The information included depends on the node kind, and may be empty. 2019 std::string detail; 2020 /// A one-line dump of detailed information about the node. 2021 /// This includes role/kind/description information, but is rather cryptic. 2022 /// It is similar to the output from `clang -Xclang -ast-dump`. 2023 /// May be empty for certain types of nodes. 2024 std::string arcana; 2025 /// The range of the original source file covered by this node. 2026 /// May be missing for implicit nodes, or those created by macro expansion. 2027 std::optional<Range> range; 2028 /// Nodes nested within this one, such as the operands of a BinaryOperator. 2029 std::vector<ASTNode> children; 2030 }; 2031 llvm::json::Value toJSON(const ASTNode &); 2032 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &); 2033 2034 } // namespace clangd 2035 } // namespace clang 2036 2037 namespace llvm { 2038 2039 template <> struct DenseMapInfo<clang::clangd::Range> { 2040 using Range = clang::clangd::Range; 2041 static inline Range getEmptyKey() { 2042 static clang::clangd::Position Tomb{-1, -1}; 2043 static Range R{Tomb, Tomb}; 2044 return R; 2045 } 2046 static inline Range getTombstoneKey() { 2047 static clang::clangd::Position Tomb{-2, -2}; 2048 static Range R{Tomb, Tomb}; 2049 return R; 2050 } 2051 static unsigned getHashValue(const Range &Val) { 2052 return llvm::hash_combine(Val.start.line, Val.start.character, Val.end.line, 2053 Val.end.character); 2054 } 2055 static bool isEqual(const Range &LHS, const Range &RHS) { 2056 return std::tie(LHS.start, LHS.end) == std::tie(RHS.start, RHS.end); 2057 } 2058 }; 2059 2060 template <> struct format_provider<clang::clangd::Position> { 2061 static void format(const clang::clangd::Position &Pos, raw_ostream &OS, 2062 StringRef Style) { 2063 assert(Style.empty() && "style modifiers for this type are not supported"); 2064 OS << Pos; 2065 } 2066 }; 2067 } // namespace llvm 2068 2069 // NOLINTEND(readability-identifier-naming) 2070 2071 #endif 2072