| //===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains structs based on the LSP specification at |
| // https://github.com/Microsoft/language-server-protocol/blob/main/protocol.md |
| // |
| // This is not meant to be a complete implementation, new interfaces are added |
| // when they're needed. |
| // |
| // Each struct has a toJSON and fromJSON function, that converts between |
| // the struct and a JSON representation. (See JSON.h) |
| // |
| // Some structs also have operator<< serialization. This is for debugging and |
| // tests, and is not generally machine-readable. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H |
| #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H |
| |
| #include "URI.h" |
| #include "index/SymbolID.h" |
| #include "support/MemoryTree.h" |
| #include "clang/Index/IndexSymbol.h" |
| #include "llvm/ADT/Optional.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/Support/JSON.h" |
| #include "llvm/Support/raw_ostream.h" |
| #include <bitset> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| // This file is using the LSP syntax for identifier names which is different |
| // from the LLVM coding standard. To avoid the clang-tidy warnings, we're |
| // disabling one check here. |
| // NOLINTBEGIN(readability-identifier-naming) |
| |
| namespace clang { |
| namespace clangd { |
| |
| enum class ErrorCode { |
| // Defined by JSON RPC. |
| ParseError = -32700, |
| InvalidRequest = -32600, |
| MethodNotFound = -32601, |
| InvalidParams = -32602, |
| InternalError = -32603, |
| |
| ServerNotInitialized = -32002, |
| UnknownErrorCode = -32001, |
| |
| // Defined by the protocol. |
| RequestCancelled = -32800, |
| ContentModified = -32801, |
| }; |
| // Models an LSP error as an llvm::Error. |
| class LSPError : public llvm::ErrorInfo<LSPError> { |
| public: |
| std::string Message; |
| ErrorCode Code; |
| static char ID; |
| |
| LSPError(std::string Message, ErrorCode Code) |
| : Message(std::move(Message)), Code(Code) {} |
| |
| void log(llvm::raw_ostream &OS) const override { |
| OS << int(Code) << ": " << Message; |
| } |
| std::error_code convertToErrorCode() const override { |
| return llvm::inconvertibleErrorCode(); |
| } |
| }; |
| |
| // URI in "file" scheme for a file. |
| struct URIForFile { |
| URIForFile() = default; |
| |
| /// Canonicalizes \p AbsPath via URI. |
| /// |
| /// File paths in URIForFile can come from index or local AST. Path from |
| /// index goes through URI transformation, and the final path is resolved by |
| /// URI scheme and could potentially be different from the original path. |
| /// Hence, we do the same transformation for all paths. |
| /// |
| /// Files can be referred to by several paths (e.g. in the presence of links). |
| /// Which one we prefer may depend on where we're coming from. \p TUPath is a |
| /// hint, and should usually be the main entrypoint file we're processing. |
| static URIForFile canonicalize(llvm::StringRef AbsPath, |
| llvm::StringRef TUPath); |
| |
| static llvm::Expected<URIForFile> fromURI(const URI &U, |
| llvm::StringRef HintPath); |
| |
| /// Retrieves absolute path to the file. |
| llvm::StringRef file() const { return File; } |
| |
| explicit operator bool() const { return !File.empty(); } |
| std::string uri() const { return URI::createFile(File).toString(); } |
| |
| friend bool operator==(const URIForFile &LHS, const URIForFile &RHS) { |
| return LHS.File == RHS.File; |
| } |
| |
| friend bool operator!=(const URIForFile &LHS, const URIForFile &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) { |
| return LHS.File < RHS.File; |
| } |
| |
| private: |
| explicit URIForFile(std::string &&File) : File(std::move(File)) {} |
| |
| std::string File; |
| }; |
| |
| /// Serialize/deserialize \p URIForFile to/from a string URI. |
| llvm::json::Value toJSON(const URIForFile &U); |
| bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path); |
| |
| struct TextDocumentIdentifier { |
| /// The text document's URI. |
| URIForFile uri; |
| }; |
| llvm::json::Value toJSON(const TextDocumentIdentifier &); |
| bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &, |
| llvm::json::Path); |
| |
| struct VersionedTextDocumentIdentifier : public TextDocumentIdentifier { |
| /// The version number of this document. If a versioned text document |
| /// identifier is sent from the server to the client and the file is not open |
| /// in the editor (the server has not received an open notification before) |
| /// the server can send `null` to indicate that the version is known and the |
| /// content on disk is the master (as speced with document content ownership). |
| /// |
| /// The version number of a document will increase after each change, |
| /// including undo/redo. The number doesn't need to be consecutive. |
| /// |
| /// clangd extension: versions are optional, and synthesized if missing. |
| llvm::Optional<std::int64_t> version; |
| }; |
| llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &); |
| bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &, |
| llvm::json::Path); |
| |
| struct Position { |
| /// Line position in a document (zero-based). |
| int line = 0; |
| |
| /// Character offset on a line in a document (zero-based). |
| /// WARNING: this is in UTF-16 codepoints, not bytes or characters! |
| /// Use the functions in SourceCode.h to construct/interpret Positions. |
| int character = 0; |
| |
| friend bool operator==(const Position &LHS, const Position &RHS) { |
| return std::tie(LHS.line, LHS.character) == |
| std::tie(RHS.line, RHS.character); |
| } |
| friend bool operator!=(const Position &LHS, const Position &RHS) { |
| return !(LHS == RHS); |
| } |
| friend bool operator<(const Position &LHS, const Position &RHS) { |
| return std::tie(LHS.line, LHS.character) < |
| std::tie(RHS.line, RHS.character); |
| } |
| friend bool operator<=(const Position &LHS, const Position &RHS) { |
| return std::tie(LHS.line, LHS.character) <= |
| std::tie(RHS.line, RHS.character); |
| } |
| }; |
| bool fromJSON(const llvm::json::Value &, Position &, llvm::json::Path); |
| llvm::json::Value toJSON(const Position &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Position &); |
| |
| struct Range { |
| /// The range's start position. |
| Position start; |
| |
| /// The range's end position. |
| Position end; |
| |
| friend bool operator==(const Range &LHS, const Range &RHS) { |
| return std::tie(LHS.start, LHS.end) == std::tie(RHS.start, RHS.end); |
| } |
| friend bool operator!=(const Range &LHS, const Range &RHS) { |
| return !(LHS == RHS); |
| } |
| friend bool operator<(const Range &LHS, const Range &RHS) { |
| return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end); |
| } |
| |
| bool contains(Position Pos) const { return start <= Pos && Pos < end; } |
| bool contains(Range Rng) const { |
| return start <= Rng.start && Rng.end <= end; |
| } |
| }; |
| bool fromJSON(const llvm::json::Value &, Range &, llvm::json::Path); |
| llvm::json::Value toJSON(const Range &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Range &); |
| |
| struct Location { |
| /// The text document's URI. |
| URIForFile uri; |
| Range range; |
| |
| friend bool operator==(const Location &LHS, const Location &RHS) { |
| return LHS.uri == RHS.uri && LHS.range == RHS.range; |
| } |
| |
| friend bool operator!=(const Location &LHS, const Location &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| friend bool operator<(const Location &LHS, const Location &RHS) { |
| return std::tie(LHS.uri, LHS.range) < std::tie(RHS.uri, RHS.range); |
| } |
| }; |
| llvm::json::Value toJSON(const Location &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Location &); |
| |
| struct TextEdit { |
| /// The range of the text document to be manipulated. To insert |
| /// text into a document create a range where start === end. |
| Range range; |
| |
| /// The string to be inserted. For delete operations use an |
| /// empty string. |
| std::string newText; |
| }; |
| inline bool operator==(const TextEdit &L, const TextEdit &R) { |
| return std::tie(L.newText, L.range) == std::tie(R.newText, R.range); |
| } |
| bool fromJSON(const llvm::json::Value &, TextEdit &, llvm::json::Path); |
| llvm::json::Value toJSON(const TextEdit &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &); |
| |
| struct TextDocumentItem { |
| /// The text document's URI. |
| URIForFile uri; |
| |
| /// The text document's language identifier. |
| std::string languageId; |
| |
| /// The version number of this document (it will strictly increase after each |
| /// change, including undo/redo. |
| /// |
| /// clangd extension: versions are optional, and synthesized if missing. |
| llvm::Optional<int64_t> version; |
| |
| /// The content of the opened text document. |
| std::string text; |
| }; |
| bool fromJSON(const llvm::json::Value &, TextDocumentItem &, llvm::json::Path); |
| |
| enum class TraceLevel { |
| Off = 0, |
| Messages = 1, |
| Verbose = 2, |
| }; |
| bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path); |
| |
| struct NoParams {}; |
| inline llvm::json::Value toJSON(const NoParams &) { return nullptr; } |
| inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) { |
| return true; |
| } |
| using InitializedParams = NoParams; |
| |
| /// Defines how the host (editor) should sync document changes to the language |
| /// server. |
| enum class TextDocumentSyncKind { |
| /// Documents should not be synced at all. |
| None = 0, |
| |
| /// Documents are synced by always sending the full content of the document. |
| Full = 1, |
| |
| /// Documents are synced by sending the full content on open. After that |
| /// only incremental updates to the document are send. |
| Incremental = 2, |
| }; |
| |
| /// The kind of a completion entry. |
| enum class CompletionItemKind { |
| Missing = 0, |
| Text = 1, |
| Method = 2, |
| Function = 3, |
| Constructor = 4, |
| Field = 5, |
| Variable = 6, |
| Class = 7, |
| Interface = 8, |
| Module = 9, |
| Property = 10, |
| Unit = 11, |
| Value = 12, |
| Enum = 13, |
| Keyword = 14, |
| Snippet = 15, |
| Color = 16, |
| File = 17, |
| Reference = 18, |
| Folder = 19, |
| EnumMember = 20, |
| Constant = 21, |
| Struct = 22, |
| Event = 23, |
| Operator = 24, |
| TypeParameter = 25, |
| }; |
| bool fromJSON(const llvm::json::Value &, CompletionItemKind &, |
| llvm::json::Path); |
| constexpr auto CompletionItemKindMin = |
| static_cast<size_t>(CompletionItemKind::Text); |
| constexpr auto CompletionItemKindMax = |
| static_cast<size_t>(CompletionItemKind::TypeParameter); |
| using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>; |
| bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &, |
| llvm::json::Path); |
| CompletionItemKind |
| adjustKindToCapability(CompletionItemKind Kind, |
| CompletionItemKindBitset &SupportedCompletionItemKinds); |
| |
| /// A symbol kind. |
| enum class SymbolKind { |
| File = 1, |
| Module = 2, |
| Namespace = 3, |
| Package = 4, |
| Class = 5, |
| Method = 6, |
| Property = 7, |
| Field = 8, |
| Constructor = 9, |
| Enum = 10, |
| Interface = 11, |
| Function = 12, |
| Variable = 13, |
| Constant = 14, |
| String = 15, |
| Number = 16, |
| Boolean = 17, |
| Array = 18, |
| Object = 19, |
| Key = 20, |
| Null = 21, |
| EnumMember = 22, |
| Struct = 23, |
| Event = 24, |
| Operator = 25, |
| TypeParameter = 26 |
| }; |
| bool fromJSON(const llvm::json::Value &, SymbolKind &, llvm::json::Path); |
| constexpr auto SymbolKindMin = static_cast<size_t>(SymbolKind::File); |
| constexpr auto SymbolKindMax = static_cast<size_t>(SymbolKind::TypeParameter); |
| using SymbolKindBitset = std::bitset<SymbolKindMax + 1>; |
| bool fromJSON(const llvm::json::Value &, SymbolKindBitset &, llvm::json::Path); |
| SymbolKind adjustKindToCapability(SymbolKind Kind, |
| SymbolKindBitset &supportedSymbolKinds); |
| |
| // Convert a index::SymbolKind to clangd::SymbolKind (LSP) |
| // Note, some are not perfect matches and should be improved when this LSP |
| // issue is addressed: |
| // https://github.com/Microsoft/language-server-protocol/issues/344 |
| SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind); |
| |
| // Determines the encoding used to measure offsets and lengths of source in LSP. |
| enum class OffsetEncoding { |
| // Any string is legal on the wire. Unrecognized encodings parse as this. |
| UnsupportedEncoding, |
| // Length counts code units of UTF-16 encoded text. (Standard LSP behavior). |
| UTF16, |
| // Length counts bytes of UTF-8 encoded text. (Clangd extension). |
| UTF8, |
| // Length counts codepoints in unicode text. (Clangd extension). |
| UTF32, |
| }; |
| llvm::json::Value toJSON(const OffsetEncoding &); |
| bool fromJSON(const llvm::json::Value &, OffsetEncoding &, llvm::json::Path); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, OffsetEncoding); |
| |
| // Describes the content type that a client supports in various result literals |
| // like `Hover`, `ParameterInfo` or `CompletionItem`. |
| enum class MarkupKind { |
| PlainText, |
| Markdown, |
| }; |
| bool fromJSON(const llvm::json::Value &, MarkupKind &, llvm::json::Path); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind); |
| |
| // This struct doesn't mirror LSP! |
| // The protocol defines deeply nested structures for client capabilities. |
| // Instead of mapping them all, this just parses out the bits we care about. |
| struct ClientCapabilities { |
| /// The supported set of SymbolKinds for workspace/symbol. |
| /// workspace.symbol.symbolKind.valueSet |
| llvm::Optional<SymbolKindBitset> WorkspaceSymbolKinds; |
| |
| /// Whether the client accepts diagnostics with codeActions attached inline. |
| /// textDocument.publishDiagnostics.codeActionsInline. |
| bool DiagnosticFixes = false; |
| |
| /// Whether the client accepts diagnostics with related locations. |
| /// textDocument.publishDiagnostics.relatedInformation. |
| bool DiagnosticRelatedInformation = false; |
| |
| /// Whether the client accepts diagnostics with category attached to it |
| /// using the "category" extension. |
| /// textDocument.publishDiagnostics.categorySupport |
| bool DiagnosticCategory = false; |
| |
| /// Client supports snippets as insert text. |
| /// textDocument.completion.completionItem.snippetSupport |
| bool CompletionSnippets = false; |
| |
| /// Client supports completions with additionalTextEdit near the cursor. |
| /// This is a clangd extension. (LSP says this is for unrelated text only). |
| /// textDocument.completion.editsNearCursor |
| bool CompletionFixes = false; |
| |
| /// Client supports hierarchical document symbols. |
| /// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport |
| bool HierarchicalDocumentSymbol = false; |
| |
| /// Client supports signature help. |
| /// textDocument.signatureHelp |
| bool HasSignatureHelp = false; |
| |
| /// Client supports processing label offsets instead of a simple label string. |
| /// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport |
| bool OffsetsInSignatureHelp = false; |
| |
| /// The supported set of CompletionItemKinds for textDocument/completion. |
| /// textDocument.completion.completionItemKind.valueSet |
| llvm::Optional<CompletionItemKindBitset> CompletionItemKinds; |
| |
| /// The documentation format that should be used for textDocument/completion. |
| /// textDocument.completion.completionItem.documentationFormat |
| MarkupKind CompletionDocumentationFormat = MarkupKind::PlainText; |
| |
| /// Client supports CodeAction return value for textDocument/codeAction. |
| /// textDocument.codeAction.codeActionLiteralSupport. |
| bool CodeActionStructure = false; |
| |
| /// Client advertises support for the semanticTokens feature. |
| /// We support the textDocument/semanticTokens request in any case. |
| /// textDocument.semanticTokens |
| bool SemanticTokens = false; |
| /// Client supports Theia semantic highlighting extension. |
| /// https://github.com/microsoft/vscode-languageserver-node/pull/367 |
| /// clangd no longer supports this, we detect it just to log a warning. |
| /// textDocument.semanticHighlightingCapabilities.semanticHighlighting |
| bool TheiaSemanticHighlighting = false; |
| |
| /// Supported encodings for LSP character offsets. (clangd extension). |
| llvm::Optional<std::vector<OffsetEncoding>> offsetEncoding; |
| |
| /// The content format that should be used for Hover requests. |
| /// textDocument.hover.contentEncoding |
| MarkupKind HoverContentFormat = MarkupKind::PlainText; |
| |
| /// The client supports testing for validity of rename operations |
| /// before execution. |
| bool RenamePrepareSupport = false; |
| |
| /// The client supports progress notifications. |
| /// window.workDoneProgress |
| bool WorkDoneProgress = false; |
| |
| /// The client supports implicit $/progress work-done progress streams, |
| /// without a preceding window/workDoneProgress/create. |
| /// This is a clangd extension. |
| /// window.implicitWorkDoneProgressCreate |
| bool ImplicitProgressCreation = false; |
| |
| /// Whether the client claims to cancel stale requests. |
| /// general.staleRequestSupport.cancel |
| bool CancelsStaleRequests = false; |
| |
| /// Whether the client implementation supports a refresh request sent from the |
| /// server to the client. |
| bool SemanticTokenRefreshSupport = false; |
| }; |
| bool fromJSON(const llvm::json::Value &, ClientCapabilities &, |
| llvm::json::Path); |
| |
| /// Clangd extension that's used in the 'compilationDatabaseChanges' in |
| /// workspace/didChangeConfiguration to record updates to the in-memory |
| /// compilation database. |
| struct ClangdCompileCommand { |
| std::string workingDirectory; |
| std::vector<std::string> compilationCommand; |
| }; |
| bool fromJSON(const llvm::json::Value &, ClangdCompileCommand &, |
| llvm::json::Path); |
| |
| /// Clangd extension: parameters configurable at any time, via the |
| /// `workspace/didChangeConfiguration` notification. |
| /// LSP defines this type as `any`. |
| struct ConfigurationSettings { |
| // Changes to the in-memory compilation database. |
| // The key of the map is a file name. |
| std::map<std::string, ClangdCompileCommand> compilationDatabaseChanges; |
| }; |
| bool fromJSON(const llvm::json::Value &, ConfigurationSettings &, |
| llvm::json::Path); |
| |
| /// Clangd extension: parameters configurable at `initialize` time. |
| /// LSP defines this type as `any`. |
| struct InitializationOptions { |
| // What we can change throught the didChangeConfiguration request, we can |
| // also set through the initialize request (initializationOptions field). |
| ConfigurationSettings ConfigSettings; |
| |
| llvm::Optional<std::string> compilationDatabasePath; |
| // Additional flags to be included in the "fallback command" used when |
| // the compilation database doesn't describe an opened file. |
| // The command used will be approximately `clang $FILE $fallbackFlags`. |
| std::vector<std::string> fallbackFlags; |
| |
| /// Clients supports show file status for textDocument/clangd.fileStatus. |
| bool FileStatus = false; |
| }; |
| bool fromJSON(const llvm::json::Value &, InitializationOptions &, |
| llvm::json::Path); |
| |
| struct InitializeParams { |
| /// The process Id of the parent process that started |
| /// the server. Is null if the process has not been started by another |
| /// process. If the parent process is not alive then the server should exit |
| /// (see exit notification) its process. |
| llvm::Optional<int> processId; |
| |
| /// The rootPath of the workspace. Is null |
| /// if no folder is open. |
| /// |
| /// @deprecated in favour of rootUri. |
| llvm::Optional<std::string> rootPath; |
| |
| /// The rootUri of the workspace. Is null if no |
| /// folder is open. If both `rootPath` and `rootUri` are set |
| /// `rootUri` wins. |
| llvm::Optional<URIForFile> rootUri; |
| |
| // User provided initialization options. |
| // initializationOptions?: any; |
| |
| /// The capabilities provided by the client (editor or tool) |
| ClientCapabilities capabilities; |
| /// The same data as capabilities, but not parsed (to expose to modules). |
| llvm::json::Object rawCapabilities; |
| |
| /// The initial trace setting. If omitted trace is disabled ('off'). |
| llvm::Optional<TraceLevel> trace; |
| |
| /// User-provided initialization options. |
| InitializationOptions initializationOptions; |
| }; |
| bool fromJSON(const llvm::json::Value &, InitializeParams &, llvm::json::Path); |
| |
| struct WorkDoneProgressCreateParams { |
| /// The token to be used to report progress. |
| llvm::json::Value token = nullptr; |
| }; |
| llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P); |
| |
| template <typename T> struct ProgressParams { |
| /// The progress token provided by the client or server. |
| llvm::json::Value token = nullptr; |
| |
| /// The progress data. |
| T value; |
| }; |
| template <typename T> llvm::json::Value toJSON(const ProgressParams<T> &P) { |
| return llvm::json::Object{{"token", P.token}, {"value", P.value}}; |
| } |
| /// To start progress reporting a $/progress notification with the following |
| /// payload must be sent. |
| struct WorkDoneProgressBegin { |
| /// Mandatory title of the progress operation. Used to briefly inform about |
| /// the kind of operation being performed. |
| /// |
| /// Examples: "Indexing" or "Linking dependencies". |
| std::string title; |
| |
| /// Controls if a cancel button should show to allow the user to cancel the |
| /// long-running operation. Clients that don't support cancellation are |
| /// allowed to ignore the setting. |
| bool cancellable = false; |
| |
| /// Optional progress percentage to display (value 100 is considered 100%). |
| /// If not provided infinite progress is assumed and clients are allowed |
| /// to ignore the `percentage` value in subsequent in report notifications. |
| /// |
| /// The value should be steadily rising. Clients are free to ignore values |
| /// that are not following this rule. |
| /// |
| /// Clangd implementation note: we only send nonzero percentages in |
| /// the WorkProgressReport. 'true' here means percentages will be used. |
| bool percentage = false; |
| }; |
| llvm::json::Value toJSON(const WorkDoneProgressBegin &); |
| |
| /// Reporting progress is done using the following payload. |
| struct WorkDoneProgressReport { |
| /// Mandatory title of the progress operation. Used to briefly inform about |
| /// the kind of operation being performed. |
| /// |
| /// Examples: "Indexing" or "Linking dependencies". |
| std::string title; |
| |
| /// Controls enablement state of a cancel button. This property is only valid |
| /// if a cancel button got requested in the `WorkDoneProgressStart` payload. |
| /// |
| /// Clients that don't support cancellation or don't support control |
| /// the button's enablement state are allowed to ignore the setting. |
| llvm::Optional<bool> cancellable; |
| |
| /// Optional, more detailed associated progress message. Contains |
| /// complementary information to the `title`. |
| /// |
| /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". |
| /// If unset, the previous progress message (if any) is still valid. |
| llvm::Optional<std::string> message; |
| |
| /// Optional progress percentage to display (value 100 is considered 100%). |
| /// If not provided infinite progress is assumed and clients are allowed |
| /// to ignore the `percentage` value in subsequent in report notifications. |
| /// |
| /// The value should be steadily rising. Clients are free to ignore values |
| /// that are not following this rule. |
| llvm::Optional<unsigned> percentage; |
| }; |
| llvm::json::Value toJSON(const WorkDoneProgressReport &); |
| // |
| /// Signals the end of progress reporting. |
| struct WorkDoneProgressEnd { |
| /// Optional, a final message indicating to for example indicate the outcome |
| /// of the operation. |
| llvm::Optional<std::string> message; |
| }; |
| llvm::json::Value toJSON(const WorkDoneProgressEnd &); |
| |
| enum class MessageType { |
| /// An error message. |
| Error = 1, |
| /// A warning message. |
| Warning = 2, |
| /// An information message. |
| Info = 3, |
| /// A log message. |
| Log = 4, |
| }; |
| llvm::json::Value toJSON(const MessageType &); |
| |
| /// The show message notification is sent from a server to a client to ask the |
| /// client to display a particular message in the user interface. |
| struct ShowMessageParams { |
| /// The message type. |
| MessageType type = MessageType::Info; |
| /// The actual message. |
| std::string message; |
| }; |
| llvm::json::Value toJSON(const ShowMessageParams &); |
| |
| struct DidOpenTextDocumentParams { |
| /// The document that was opened. |
| TextDocumentItem textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidOpenTextDocumentParams &, |
| llvm::json::Path); |
| |
| struct DidCloseTextDocumentParams { |
| /// The document that was closed. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidCloseTextDocumentParams &, |
| llvm::json::Path); |
| |
| struct DidSaveTextDocumentParams { |
| /// The document that was saved. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidSaveTextDocumentParams &, |
| llvm::json::Path); |
| |
| struct TextDocumentContentChangeEvent { |
| /// The range of the document that changed. |
| llvm::Optional<Range> range; |
| |
| /// The length of the range that got replaced. |
| llvm::Optional<int> rangeLength; |
| |
| /// The new text of the range/document. |
| std::string text; |
| }; |
| bool fromJSON(const llvm::json::Value &, TextDocumentContentChangeEvent &, |
| llvm::json::Path); |
| |
| struct DidChangeTextDocumentParams { |
| /// The document that did change. The version number points |
| /// to the version after all provided content changes have |
| /// been applied. |
| VersionedTextDocumentIdentifier textDocument; |
| |
| /// The actual content changes. |
| std::vector<TextDocumentContentChangeEvent> contentChanges; |
| |
| /// Forces diagnostics to be generated, or to not be generated, for this |
| /// version of the file. If not set, diagnostics are eventually consistent: |
| /// either they will be provided for this version or some subsequent one. |
| /// This is a clangd extension. |
| llvm::Optional<bool> wantDiagnostics; |
| |
| /// Force a complete rebuild of the file, ignoring all cached state. Slow! |
| /// This is useful to defeat clangd's assumption that missing headers will |
| /// stay missing. |
| /// This is a clangd extension. |
| bool forceRebuild = false; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidChangeTextDocumentParams &, |
| llvm::json::Path); |
| |
| enum class FileChangeType { |
| /// The file got created. |
| Created = 1, |
| /// The file got changed. |
| Changed = 2, |
| /// The file got deleted. |
| Deleted = 3 |
| }; |
| bool fromJSON(const llvm::json::Value &E, FileChangeType &Out, |
| llvm::json::Path); |
| |
| struct FileEvent { |
| /// The file's URI. |
| URIForFile uri; |
| /// The change type. |
| FileChangeType type = FileChangeType::Created; |
| }; |
| bool fromJSON(const llvm::json::Value &, FileEvent &, llvm::json::Path); |
| |
| struct DidChangeWatchedFilesParams { |
| /// The actual file events. |
| std::vector<FileEvent> changes; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidChangeWatchedFilesParams &, |
| llvm::json::Path); |
| |
| struct DidChangeConfigurationParams { |
| ConfigurationSettings settings; |
| }; |
| bool fromJSON(const llvm::json::Value &, DidChangeConfigurationParams &, |
| llvm::json::Path); |
| |
| // Note: we do not parse FormattingOptions for *FormattingParams. |
| // In general, we use a clang-format style detected from common mechanisms |
| // (.clang-format files and the -fallback-style flag). |
| // It would be possible to override these with FormatOptions, but: |
| // - the protocol makes FormatOptions mandatory, so many clients set them to |
| // useless values, and we can't tell when to respect them |
| // - we also format in other places, where FormatOptions aren't available. |
| |
| struct DocumentRangeFormattingParams { |
| /// The document to format. |
| TextDocumentIdentifier textDocument; |
| |
| /// The range to format |
| Range range; |
| }; |
| bool fromJSON(const llvm::json::Value &, DocumentRangeFormattingParams &, |
| llvm::json::Path); |
| |
| struct DocumentOnTypeFormattingParams { |
| /// The document to format. |
| TextDocumentIdentifier textDocument; |
| |
| /// The position at which this request was sent. |
| Position position; |
| |
| /// The character that has been typed. |
| std::string ch; |
| }; |
| bool fromJSON(const llvm::json::Value &, DocumentOnTypeFormattingParams &, |
| llvm::json::Path); |
| |
| struct DocumentFormattingParams { |
| /// The document to format. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DocumentFormattingParams &, |
| llvm::json::Path); |
| |
| struct DocumentSymbolParams { |
| // The text document to find symbols in. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &, |
| llvm::json::Path); |
| |
| /// Represents a related message and source code location for a diagnostic. |
| /// This should be used to point to code locations that cause or related to a |
| /// diagnostics, e.g when duplicating a symbol in a scope. |
| struct DiagnosticRelatedInformation { |
| /// The location of this related diagnostic information. |
| Location location; |
| /// The message of this related diagnostic information. |
| std::string message; |
| }; |
| llvm::json::Value toJSON(const DiagnosticRelatedInformation &); |
| |
| enum DiagnosticTag { |
| /// Unused or unnecessary code. |
| /// |
| /// Clients are allowed to render diagnostics with this tag faded out instead |
| /// of having an error squiggle. |
| Unnecessary = 1, |
| /// Deprecated or obsolete code. |
| /// |
| /// Clients are allowed to rendered diagnostics with this tag strike through. |
| Deprecated = 2, |
| }; |
| llvm::json::Value toJSON(DiagnosticTag Tag); |
| |
| struct CodeAction; |
| struct Diagnostic { |
| /// The range at which the message applies. |
| Range range; |
| |
| /// The diagnostic's severity. Can be omitted. If omitted it is up to the |
| /// client to interpret diagnostics as error, warning, info or hint. |
| int severity = 0; |
| |
| /// The diagnostic's code. Can be omitted. |
| std::string code; |
| |
| /// A human-readable string describing the source of this |
| /// diagnostic, e.g. 'typescript' or 'super lint'. |
| std::string source; |
| |
| /// The diagnostic's message. |
| std::string message; |
| |
| /// Additional metadata about the diagnostic. |
| llvm::SmallVector<DiagnosticTag, 1> tags; |
| |
| /// An array of related diagnostic information, e.g. when symbol-names within |
| /// a scope collide all definitions can be marked via this property. |
| llvm::Optional<std::vector<DiagnosticRelatedInformation>> relatedInformation; |
| |
| /// The diagnostic's category. Can be omitted. |
| /// An LSP extension that's used to send the name of the category over to the |
| /// client. The category typically describes the compilation stage during |
| /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue". |
| llvm::Optional<std::string> category; |
| |
| /// Clangd extension: code actions related to this diagnostic. |
| /// Only with capability textDocument.publishDiagnostics.codeActionsInline. |
| /// (These actions can also be obtained using textDocument/codeAction). |
| llvm::Optional<std::vector<CodeAction>> codeActions; |
| |
| /// A data entry field that is preserved between a |
| /// `textDocument/publishDiagnostics` notification |
| /// and`textDocument/codeAction` request. |
| /// Mutating users should associate their data with a unique key they can use |
| /// to retrieve later on. |
| llvm::json::Object data; |
| }; |
| llvm::json::Value toJSON(const Diagnostic &); |
| |
| /// A LSP-specific comparator used to find diagnostic in a container like |
| /// std:map. |
| /// We only use the required fields of Diagnostic to do the comparison to avoid |
| /// any regression issues from LSP clients (e.g. VScode), see |
| /// https://git.io/vbr29 |
| struct LSPDiagnosticCompare { |
| bool operator()(const Diagnostic &LHS, const Diagnostic &RHS) const { |
| return std::tie(LHS.range, LHS.message) < std::tie(RHS.range, RHS.message); |
| } |
| }; |
| bool fromJSON(const llvm::json::Value &, Diagnostic &, llvm::json::Path); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Diagnostic &); |
| |
| struct PublishDiagnosticsParams { |
| /// The URI for which diagnostic information is reported. |
| URIForFile uri; |
| /// An array of diagnostic information items. |
| std::vector<Diagnostic> diagnostics; |
| /// The version number of the document the diagnostics are published for. |
| llvm::Optional<int64_t> version; |
| }; |
| llvm::json::Value toJSON(const PublishDiagnosticsParams &); |
| |
| struct CodeActionContext { |
| /// An array of diagnostics known on the client side overlapping the range |
| /// provided to the `textDocument/codeAction` request. They are provided so |
| /// that the server knows which errors are currently presented to the user for |
| /// the given range. There is no guarantee that these accurately reflect the |
| /// error state of the resource. The primary parameter to compute code actions |
| /// is the provided range. |
| std::vector<Diagnostic> diagnostics; |
| |
| /// Requested kind of actions to return. |
| /// |
| /// Actions not of this kind are filtered out by the client before being |
| /// shown. So servers can omit computing them. |
| std::vector<std::string> only; |
| }; |
| bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path); |
| |
| struct CodeActionParams { |
| /// The document in which the command was invoked. |
| TextDocumentIdentifier textDocument; |
| |
| /// The range for which the command was invoked. |
| Range range; |
| |
| /// Context carrying additional information. |
| CodeActionContext context; |
| }; |
| bool fromJSON(const llvm::json::Value &, CodeActionParams &, llvm::json::Path); |
| |
| struct WorkspaceEdit { |
| /// Holds changes to existing resources. |
| std::map<std::string, std::vector<TextEdit>> changes; |
| |
| /// Note: "documentChanges" is not currently used because currently there is |
| /// no support for versioned edits. |
| }; |
| bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path); |
| llvm::json::Value toJSON(const WorkspaceEdit &WE); |
| |
| /// Arguments for the 'applyTweak' command. The server sends these commands as a |
| /// response to the textDocument/codeAction request. The client can later send a |
| /// command back to the server if the user requests to execute a particular code |
| /// tweak. |
| struct TweakArgs { |
| /// A file provided by the client on a textDocument/codeAction request. |
| URIForFile file; |
| /// A selection provided by the client on a textDocument/codeAction request. |
| Range selection; |
| /// ID of the tweak that should be executed. Corresponds to Tweak::id(). |
| std::string tweakID; |
| }; |
| bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path); |
| llvm::json::Value toJSON(const TweakArgs &A); |
| |
| struct ExecuteCommandParams { |
| /// The identifier of the actual command handler. |
| std::string command; |
| |
| // This is `arguments?: []any` in LSP. |
| // All clangd's commands accept a single argument (or none => null). |
| llvm::json::Value argument = nullptr; |
| }; |
| bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &, |
| llvm::json::Path); |
| |
| struct Command : public ExecuteCommandParams { |
| std::string title; |
| }; |
| llvm::json::Value toJSON(const Command &C); |
| |
| /// A code action represents a change that can be performed in code, e.g. to fix |
| /// a problem or to refactor code. |
| /// |
| /// A CodeAction must set either `edit` and/or a `command`. If both are |
| /// supplied, the `edit` is applied first, then the `command` is executed. |
| struct CodeAction { |
| /// A short, human-readable, title for this code action. |
| std::string title; |
| |
| /// The kind of the code action. |
| /// Used to filter code actions. |
| llvm::Optional<std::string> kind; |
| const static llvm::StringLiteral QUICKFIX_KIND; |
| const static llvm::StringLiteral REFACTOR_KIND; |
| const static llvm::StringLiteral INFO_KIND; |
| |
| /// The diagnostics that this code action resolves. |
| llvm::Optional<std::vector<Diagnostic>> diagnostics; |
| |
| /// Marks this as a preferred action. Preferred actions are used by the |
| /// `auto fix` command and can be targeted by keybindings. |
| /// A quick fix should be marked preferred if it properly addresses the |
| /// underlying error. A refactoring should be marked preferred if it is the |
| /// most reasonable choice of actions to take. |
| bool isPreferred = false; |
| |
| /// The workspace edit this code action performs. |
| llvm::Optional<WorkspaceEdit> edit; |
| |
| /// A command this code action executes. If a code action provides an edit |
| /// and a command, first the edit is executed and then the command. |
| llvm::Optional<Command> command; |
| }; |
| llvm::json::Value toJSON(const CodeAction &); |
| |
| /// Represents programming constructs like variables, classes, interfaces etc. |
| /// that appear in a document. Document symbols can be hierarchical and they |
| /// have two ranges: one that encloses its definition and one that points to its |
| /// most interesting range, e.g. the range of an identifier. |
| struct DocumentSymbol { |
| /// The name of this symbol. |
| std::string name; |
| |
| /// More detail for this symbol, e.g the signature of a function. |
| std::string detail; |
| |
| /// The kind of this symbol. |
| SymbolKind kind; |
| |
| /// Indicates if this symbol is deprecated. |
| bool deprecated = false; |
| |
| /// The range enclosing this symbol not including leading/trailing whitespace |
| /// but everything else like comments. This information is typically used to |
| /// determine if the clients cursor is inside the symbol to reveal in the |
| /// symbol in the UI. |
| Range range; |
| |
| /// The range that should be selected and revealed when this symbol is being |
| /// picked, e.g the name of a function. Must be contained by the `range`. |
| Range selectionRange; |
| |
| /// Children of this symbol, e.g. properties of a class. |
| std::vector<DocumentSymbol> children; |
| }; |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S); |
| llvm::json::Value toJSON(const DocumentSymbol &S); |
| |
| /// Represents information about programming constructs like variables, classes, |
| /// interfaces etc. |
| struct SymbolInformation { |
| /// The name of this symbol. |
| std::string name; |
| |
| /// The kind of this symbol. |
| SymbolKind kind; |
| |
| /// The location of this symbol. |
| Location location; |
| |
| /// The name of the symbol containing this symbol. |
| std::string containerName; |
| |
| /// The score that clangd calculates to rank the returned symbols. |
| /// This excludes the fuzzy-matching score between `name` and the query. |
| /// (Specifically, the last ::-separated component). |
| /// This can be used to re-rank results as the user types, using client-side |
| /// fuzzy-matching (that score should be multiplied with this one). |
| /// This is a clangd extension, set only for workspace/symbol responses. |
| llvm::Optional<float> score; |
| }; |
| llvm::json::Value toJSON(const SymbolInformation &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &); |
| |
| /// Represents information about identifier. |
| /// This is returned from textDocument/symbolInfo, which is a clangd extension. |
| struct SymbolDetails { |
| std::string name; |
| |
| std::string containerName; |
| |
| /// Unified Symbol Resolution identifier |
| /// This is an opaque string uniquely identifying a symbol. |
| /// Unlike SymbolID, it is variable-length and somewhat human-readable. |
| /// It is a common representation across several clang tools. |
| /// (See USRGeneration.h) |
| std::string USR; |
| |
| SymbolID ID; |
| }; |
| llvm::json::Value toJSON(const SymbolDetails &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &); |
| bool operator==(const SymbolDetails &, const SymbolDetails &); |
| |
| /// The parameters of a Workspace Symbol Request. |
| struct WorkspaceSymbolParams { |
| /// A query string to filter symbols by. |
| /// Clients may send an empty string here to request all the symbols. |
| std::string query; |
| |
| /// Max results to return, overriding global default. 0 means no limit. |
| /// Clangd extension. |
| llvm::Optional<int> limit; |
| }; |
| bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &, |
| llvm::json::Path); |
| |
| struct ApplyWorkspaceEditParams { |
| WorkspaceEdit edit; |
| }; |
| llvm::json::Value toJSON(const ApplyWorkspaceEditParams &); |
| |
| struct ApplyWorkspaceEditResponse { |
| bool applied = true; |
| llvm::Optional<std::string> failureReason; |
| }; |
| bool fromJSON(const llvm::json::Value &, ApplyWorkspaceEditResponse &, |
| llvm::json::Path); |
| |
| struct TextDocumentPositionParams { |
| /// The text document. |
| TextDocumentIdentifier textDocument; |
| |
| /// The position inside the text document. |
| Position position; |
| }; |
| bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &, |
| llvm::json::Path); |
| |
| enum class CompletionTriggerKind { |
| /// Completion was triggered by typing an identifier (24x7 code |
| /// complete), manual invocation (e.g Ctrl+Space) or via API. |
| Invoked = 1, |
| /// Completion was triggered by a trigger character specified by |
| /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`. |
| TriggerCharacter = 2, |
| /// Completion was re-triggered as the current completion list is incomplete. |
| TriggerTriggerForIncompleteCompletions = 3 |
| }; |
| |
| struct CompletionContext { |
| /// How the completion was triggered. |
| CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked; |
| /// The trigger character (a single character) that has trigger code complete. |
| /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` |
| std::string triggerCharacter; |
| }; |
| bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path); |
| |
| struct CompletionParams : TextDocumentPositionParams { |
| CompletionContext context; |
| |
| /// Max results to return, overriding global default. 0 means no limit. |
| /// Clangd extension. |
| llvm::Optional<int> limit; |
| }; |
| bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path); |
| |
| struct MarkupContent { |
| MarkupKind kind = MarkupKind::PlainText; |
| std::string value; |
| }; |
| llvm::json::Value toJSON(const MarkupContent &MC); |
| |
| struct Hover { |
| /// The hover's content |
| MarkupContent contents; |
| |
| /// An optional range is a range inside a text document |
| /// that is used to visualize a hover, e.g. by changing the background color. |
| llvm::Optional<Range> range; |
| }; |
| llvm::json::Value toJSON(const Hover &H); |
| |
| /// Defines whether the insert text in a completion item should be interpreted |
| /// as plain text or a snippet. |
| enum class InsertTextFormat { |
| Missing = 0, |
| /// The primary text to be inserted is treated as a plain string. |
| PlainText = 1, |
| /// The primary text to be inserted is treated as a snippet. |
| /// |
| /// A snippet can define tab stops and placeholders with `$1`, `$2` |
| /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end |
| /// of the snippet. Placeholders with equal identifiers are linked, that is |
| /// typing in one will update others too. |
| /// |
| /// See also: |
| /// https://github.com/Microsoft/vscode/blob/main/src/vs/editor/contrib/snippet/snippet.md |
| Snippet = 2, |
| }; |
| |
| struct CompletionItem { |
| /// The label of this completion item. By default also the text that is |
| /// inserted when selecting this completion. |
| std::string label; |
| |
| /// The kind of this completion item. Based of the kind an icon is chosen by |
| /// the editor. |
| CompletionItemKind kind = CompletionItemKind::Missing; |
| |
| /// A human-readable string with additional information about this item, like |
| /// type or symbol information. |
| std::string detail; |
| |
| /// A human-readable string that represents a doc-comment. |
| llvm::Optional<MarkupContent> documentation; |
| |
| /// A string that should be used when comparing this item with other items. |
| /// When `falsy` the label is used. |
| std::string sortText; |
| |
| /// A string that should be used when filtering a set of completion items. |
| /// When `falsy` the label is used. |
| std::string filterText; |
| |
| /// A string that should be inserted to a document when selecting this |
| /// completion. When `falsy` the label is used. |
| std::string insertText; |
| |
| /// The format of the insert text. The format applies to both the `insertText` |
| /// property and the `newText` property of a provided `textEdit`. |
| InsertTextFormat insertTextFormat = InsertTextFormat::Missing; |
| |
| /// An edit which is applied to a document when selecting this completion. |
| /// When an edit is provided `insertText` is ignored. |
| /// |
| /// Note: The range of the edit must be a single line range and it must |
| /// contain the position at which completion has been requested. |
| llvm::Optional<TextEdit> textEdit; |
| |
| /// An optional array of additional text edits that are applied when selecting |
| /// this completion. Edits must not overlap with the main edit nor with |
| /// themselves. |
| std::vector<TextEdit> additionalTextEdits; |
| |
| /// Indicates if this item is deprecated. |
| bool deprecated = false; |
| |
| /// The score that clangd calculates to rank the returned completions. |
| /// This excludes the fuzzy-match between `filterText` and the partial word. |
| /// This can be used to re-rank results as the user types, using client-side |
| /// fuzzy-matching (that score should be multiplied with this one). |
| /// This is a clangd extension. |
| float score = 0.f; |
| |
| // TODO: Add custom commitCharacters for some of the completion items. For |
| // example, it makes sense to use () only for the functions. |
| // TODO(krasimir): The following optional fields defined by the language |
| // server protocol are unsupported: |
| // |
| // data?: any - A data entry field that is preserved on a completion item |
| // between a completion and a completion resolve request. |
| }; |
| llvm::json::Value toJSON(const CompletionItem &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &); |
| |
| bool operator<(const CompletionItem &, const CompletionItem &); |
| |
| /// Represents a collection of completion items to be presented in the editor. |
| struct CompletionList { |
| /// The list is not complete. Further typing should result in recomputing the |
| /// list. |
| bool isIncomplete = false; |
| |
| /// The completion items. |
| std::vector<CompletionItem> items; |
| }; |
| llvm::json::Value toJSON(const CompletionList &); |
| |
| /// A single parameter of a particular signature. |
| struct ParameterInformation { |
| |
| /// The label of this parameter. Ignored when labelOffsets is set. |
| std::string labelString; |
| |
| /// Inclusive start and exclusive end offsets withing the containing signature |
| /// label. |
| /// Offsets are computed by lspLength(), which counts UTF-16 code units by |
| /// default but that can be overriden, see its documentation for details. |
| llvm::Optional<std::pair<unsigned, unsigned>> labelOffsets; |
| |
| /// The documentation of this parameter. Optional. |
| std::string documentation; |
| }; |
| llvm::json::Value toJSON(const ParameterInformation &); |
| |
| /// Represents the signature of something callable. |
| struct SignatureInformation { |
| |
| /// The label of this signature. Mandatory. |
| std::string label; |
| |
| /// The documentation of this signature. Optional. |
| std::string documentation; |
| |
| /// The parameters of this signature. |
| std::vector<ParameterInformation> parameters; |
| }; |
| llvm::json::Value toJSON(const SignatureInformation &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, |
| const SignatureInformation &); |
| |
| /// Represents the signature of a callable. |
| struct SignatureHelp { |
| |
| /// The resulting signatures. |
| std::vector<SignatureInformation> signatures; |
| |
| /// The active signature. |
| int activeSignature = 0; |
| |
| /// The active parameter of the active signature. |
| int activeParameter = 0; |
| |
| /// Position of the start of the argument list, including opening paren. e.g. |
| /// foo("first arg", "second arg", |
| /// ^-argListStart ^-cursor |
| /// This is a clangd-specific extension, it is only available via C++ API and |
| /// not currently serialized for the LSP. |
| Position argListStart; |
| }; |
| llvm::json::Value toJSON(const SignatureHelp &); |
| |
| struct RenameParams { |
| /// The document that was opened. |
| TextDocumentIdentifier textDocument; |
| |
| /// The position at which this request was sent. |
| Position position; |
| |
| /// The new name of the symbol. |
| std::string newName; |
| }; |
| bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path); |
| |
| enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 }; |
| |
| /// A document highlight is a range inside a text document which deserves |
| /// special attention. Usually a document highlight is visualized by changing |
| /// the background color of its range. |
| |
| struct DocumentHighlight { |
| /// The range this highlight applies to. |
| Range range; |
| |
| /// The highlight kind, default is DocumentHighlightKind.Text. |
| DocumentHighlightKind kind = DocumentHighlightKind::Text; |
| |
| friend bool operator<(const DocumentHighlight &LHS, |
| const DocumentHighlight &RHS) { |
| int LHSKind = static_cast<int>(LHS.kind); |
| int RHSKind = static_cast<int>(RHS.kind); |
| return std::tie(LHS.range, LHSKind) < std::tie(RHS.range, RHSKind); |
| } |
| |
| friend bool operator==(const DocumentHighlight &LHS, |
| const DocumentHighlight &RHS) { |
| return LHS.kind == RHS.kind && LHS.range == RHS.range; |
| } |
| }; |
| llvm::json::Value toJSON(const DocumentHighlight &DH); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &); |
| |
| enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 }; |
| bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out, |
| llvm::json::Path); |
| |
| /// The type hierarchy params is an extension of the |
| /// `TextDocumentPositionsParams` with optional properties which can be used to |
| /// eagerly resolve the item when requesting from the server. |
| struct TypeHierarchyParams : public TextDocumentPositionParams { |
| /// The hierarchy levels to resolve. `0` indicates no level. |
| int resolve = 0; |
| |
| /// The direction of the hierarchy levels to resolve. |
| TypeHierarchyDirection direction = TypeHierarchyDirection::Parents; |
| }; |
| bool fromJSON(const llvm::json::Value &, TypeHierarchyParams &, |
| llvm::json::Path); |
| |
| struct TypeHierarchyItem { |
| /// The human readable name of the hierarchy item. |
| std::string name; |
| |
| /// Optional detail for the hierarchy item. It can be, for instance, the |
| /// signature of a function or method. |
| llvm::Optional<std::string> detail; |
| |
| /// The kind of the hierarchy item. For instance, class or interface. |
| SymbolKind kind; |
| |
| /// `true` if the hierarchy item is deprecated. Otherwise, `false`. |
| bool deprecated = false; |
| |
| /// The URI of the text document where this type hierarchy item belongs to. |
| URIForFile uri; |
| |
| /// The range enclosing this type hierarchy item not including |
| /// leading/trailing whitespace but everything else like comments. This |
| /// information is typically used to determine if the client's cursor is |
| /// inside the type hierarch item to reveal in the symbol in the UI. |
| Range range; |
| |
| /// The range that should be selected and revealed when this type hierarchy |
| /// item is being picked, e.g. the name of a function. Must be contained by |
| /// the `range`. |
| Range selectionRange; |
| |
| /// If this type hierarchy item is resolved, it contains the direct parents. |
| /// Could be empty if the item does not have direct parents. If not defined, |
| /// the parents have not been resolved yet. |
| llvm::Optional<std::vector<TypeHierarchyItem>> parents; |
| |
| /// If this type hierarchy item is resolved, it contains the direct children |
| /// of the current item. Could be empty if the item does not have any |
| /// descendants. If not defined, the children have not been resolved. |
| llvm::Optional<std::vector<TypeHierarchyItem>> children; |
| |
| /// An optional 'data' field, which can be used to identify a type hierarchy |
| /// item in a resolve request. |
| llvm::Optional<std::string> data; |
| }; |
| llvm::json::Value toJSON(const TypeHierarchyItem &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &); |
| bool fromJSON(const llvm::json::Value &, TypeHierarchyItem &, llvm::json::Path); |
| |
| /// Parameters for the `typeHierarchy/resolve` request. |
| struct ResolveTypeHierarchyItemParams { |
| /// The item to resolve. |
| TypeHierarchyItem item; |
| |
| /// The hierarchy levels to resolve. `0` indicates no level. |
| int resolve; |
| |
| /// The direction of the hierarchy levels to resolve. |
| TypeHierarchyDirection direction; |
| }; |
| bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &, |
| llvm::json::Path); |
| |
| enum class SymbolTag { Deprecated = 1 }; |
| llvm::json::Value toJSON(SymbolTag); |
| |
| /// The parameter of a `textDocument/prepareCallHierarchy` request. |
| struct CallHierarchyPrepareParams : public TextDocumentPositionParams {}; |
| |
| /// Represents programming constructs like functions or constructors |
| /// in the context of call hierarchy. |
| struct CallHierarchyItem { |
| /// The name of this item. |
| std::string name; |
| |
| /// The kind of this item. |
| SymbolKind kind; |
| |
| /// Tags for this item. |
| std::vector<SymbolTag> tags; |
| |
| /// More detaill for this item, e.g. the signature of a function. |
| std::string detail; |
| |
| /// The resource identifier of this item. |
| URIForFile uri; |
| |
| /// The range enclosing this symbol not including leading / trailing |
| /// whitespace but everything else, e.g. comments and code. |
| Range range; |
| |
| /// The range that should be selected and revealed when this symbol |
| /// is being picked, e.g. the name of a function. |
| /// Must be contained by `Rng`. |
| Range selectionRange; |
| |
| /// An optional 'data' field, which can be used to identify a call |
| /// hierarchy item in an incomingCalls or outgoingCalls request. |
| std::string data; |
| }; |
| llvm::json::Value toJSON(const CallHierarchyItem &); |
| bool fromJSON(const llvm::json::Value &, CallHierarchyItem &, llvm::json::Path); |
| |
| /// The parameter of a `callHierarchy/incomingCalls` request. |
| struct CallHierarchyIncomingCallsParams { |
| CallHierarchyItem item; |
| }; |
| bool fromJSON(const llvm::json::Value &, CallHierarchyIncomingCallsParams &, |
| llvm::json::Path); |
| |
| /// Represents an incoming call, e.g. a caller of a method or constructor. |
| struct CallHierarchyIncomingCall { |
| /// The item that makes the call. |
| CallHierarchyItem from; |
| |
| /// The range at which the calls appear. |
| /// This is relative to the caller denoted by `From`. |
| std::vector<Range> fromRanges; |
| }; |
| llvm::json::Value toJSON(const CallHierarchyIncomingCall &); |
| |
| /// The parameter of a `callHierarchy/outgoingCalls` request. |
| struct CallHierarchyOutgoingCallsParams { |
| CallHierarchyItem item; |
| }; |
| bool fromJSON(const llvm::json::Value &, CallHierarchyOutgoingCallsParams &, |
| llvm::json::Path); |
| |
| /// Represents an outgoing call, e.g. calling a getter from a method or |
| /// a method from a constructor etc. |
| struct CallHierarchyOutgoingCall { |
| /// The item that is called. |
| CallHierarchyItem to; |
| |
| /// The range at which this item is called. |
| /// This is the range relative to the caller, and not `To`. |
| std::vector<Range> fromRanges; |
| }; |
| llvm::json::Value toJSON(const CallHierarchyOutgoingCall &); |
| |
| /// The parameter of a `textDocument/inlayHints` request. |
| struct InlayHintsParams { |
| /// The text document for which inlay hints are requested. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, InlayHintsParams &, llvm::json::Path); |
| |
| /// A set of predefined hint kinds. |
| enum class InlayHintKind { |
| /// The hint corresponds to parameter information. |
| /// An example of a parameter hint is a hint in this position: |
| /// func(^arg); |
| /// which shows the name of the corresponding parameter. |
| ParameterHint, |
| |
| /// The hint corresponds to information about a deduced type. |
| /// An example of a type hint is a hint in this position: |
| /// auto var ^ = expr; |
| /// which shows the deduced type of the variable. |
| TypeHint, |
| |
| /// Other ideas for hints that are not currently implemented: |
| /// |
| /// * Chaining hints, showing the types of intermediate expressions |
| /// in a chain of function calls. |
| /// * Hints indicating implicit conversions or implicit constructor calls. |
| }; |
| llvm::json::Value toJSON(InlayHintKind); |
| |
| /// An annotation to be displayed inline next to a range of source code. |
| struct InlayHint { |
| /// The range of source code to which the hint applies. |
| /// We provide the entire range, rather than just the endpoint |
| /// relevant to `position` (e.g. the start of the range for |
| /// InlayHintPosition::Before), to give clients the flexibility |
| /// to make choices like only displaying the hint while the cursor |
| /// is over the range, rather than displaying it all the time. |
| Range range; |
| |
| /// The type of hint. |
| InlayHintKind kind; |
| |
| /// The label that is displayed in the editor. |
| std::string label; |
| }; |
| llvm::json::Value toJSON(const InlayHint &); |
| bool operator==(const InlayHint &, const InlayHint &); |
| bool operator<(const InlayHint &, const InlayHint &); |
| |
| struct ReferenceContext { |
| /// Include the declaration of the current symbol. |
| bool includeDeclaration = false; |
| }; |
| |
| struct ReferenceParams : public TextDocumentPositionParams { |
| ReferenceContext context; |
| }; |
| bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path); |
| |
| /// Clangd extension: indicates the current state of the file in clangd, |
| /// sent from server via the `textDocument/clangd.fileStatus` notification. |
| struct FileStatus { |
| /// The text document's URI. |
| URIForFile uri; |
| /// The human-readable string presents the current state of the file, can be |
| /// shown in the UI (e.g. status bar). |
| std::string state; |
| // FIXME: add detail messages. |
| }; |
| llvm::json::Value toJSON(const FileStatus &); |
| |
| /// Specifies a single semantic token in the document. |
| /// This struct is not part of LSP, which just encodes lists of tokens as |
| /// arrays of numbers directly. |
| struct SemanticToken { |
| /// token line number, relative to the previous token |
| unsigned deltaLine = 0; |
| /// token start character, relative to the previous token |
| /// (relative to 0 or the previous token's start if they are on the same line) |
| unsigned deltaStart = 0; |
| /// the length of the token. A token cannot be multiline |
| unsigned length = 0; |
| /// will be looked up in `SemanticTokensLegend.tokenTypes` |
| unsigned tokenType = 0; |
| /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` |
| unsigned tokenModifiers = 0; |
| }; |
| bool operator==(const SemanticToken &, const SemanticToken &); |
| |
| /// A versioned set of tokens. |
| struct SemanticTokens { |
| // An optional result id. If provided and clients support delta updating |
| // the client will include the result id in the next semantic token request. |
| // A server can then instead of computing all semantic tokens again simply |
| // send a delta. |
| std::string resultId; |
| |
| /// The actual tokens. |
| std::vector<SemanticToken> tokens; // encoded as a flat integer array. |
| }; |
| llvm::json::Value toJSON(const SemanticTokens &); |
| |
| /// Body of textDocument/semanticTokens/full request. |
| struct SemanticTokensParams { |
| /// The text document. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, SemanticTokensParams &, |
| llvm::json::Path); |
| |
| /// Body of textDocument/semanticTokens/full/delta request. |
| /// Requests the changes in semantic tokens since a previous response. |
| struct SemanticTokensDeltaParams { |
| /// The text document. |
| TextDocumentIdentifier textDocument; |
| /// The previous result id. |
| std::string previousResultId; |
| }; |
| bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R, |
| llvm::json::Path); |
| |
| /// Describes a a replacement of a contiguous range of semanticTokens. |
| struct SemanticTokensEdit { |
| // LSP specifies `start` and `deleteCount` which are relative to the array |
| // encoding of the previous tokens. |
| // We use token counts instead, and translate when serializing this struct. |
| unsigned startToken = 0; |
| unsigned deleteTokens = 0; |
| std::vector<SemanticToken> tokens; // encoded as a flat integer array |
| }; |
| llvm::json::Value toJSON(const SemanticTokensEdit &); |
| |
| /// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of |
| /// textDocument/semanticTokens/full/delta. |
| struct SemanticTokensOrDelta { |
| std::string resultId; |
| /// Set if we computed edits relative to a previous set of tokens. |
| llvm::Optional<std::vector<SemanticTokensEdit>> edits; |
| /// Set if we computed a fresh set of tokens. |
| llvm::Optional<std::vector<SemanticToken>> tokens; // encoded as integer array |
| }; |
| llvm::json::Value toJSON(const SemanticTokensOrDelta &); |
| |
| struct SelectionRangeParams { |
| /// The text document. |
| TextDocumentIdentifier textDocument; |
| |
| /// The positions inside the text document. |
| std::vector<Position> positions; |
| }; |
| bool fromJSON(const llvm::json::Value &, SelectionRangeParams &, |
| llvm::json::Path); |
| |
| struct SelectionRange { |
| /** |
| * The range of this selection range. |
| */ |
| Range range; |
| /** |
| * The parent selection range containing this range. Therefore `parent.range` |
| * must contain `this.range`. |
| */ |
| std::unique_ptr<SelectionRange> parent; |
| }; |
| llvm::json::Value toJSON(const SelectionRange &); |
| |
| /// Parameters for the document link request. |
| struct DocumentLinkParams { |
| /// The document to provide document links for. |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, DocumentLinkParams &, |
| llvm::json::Path); |
| |
| /// A range in a text document that links to an internal or external resource, |
| /// like another text document or a web site. |
| struct DocumentLink { |
| /// The range this link applies to. |
| Range range; |
| |
| /// The uri this link points to. If missing a resolve request is sent later. |
| URIForFile target; |
| |
| // TODO(forster): The following optional fields defined by the language |
| // server protocol are unsupported: |
| // |
| // data?: any - A data entry field that is preserved on a document link |
| // between a DocumentLinkRequest and a |
| // DocumentLinkResolveRequest. |
| |
| friend bool operator==(const DocumentLink &LHS, const DocumentLink &RHS) { |
| return LHS.range == RHS.range && LHS.target == RHS.target; |
| } |
| |
| friend bool operator!=(const DocumentLink &LHS, const DocumentLink &RHS) { |
| return !(LHS == RHS); |
| } |
| }; |
| llvm::json::Value toJSON(const DocumentLink &DocumentLink); |
| |
| // FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support |
| // per-line-folding editors. |
| struct FoldingRangeParams { |
| TextDocumentIdentifier textDocument; |
| }; |
| bool fromJSON(const llvm::json::Value &, FoldingRangeParams &, |
| llvm::json::Path); |
| |
| /// Stores information about a region of code that can be folded. |
| struct FoldingRange { |
| unsigned startLine = 0; |
| unsigned startCharacter; |
| unsigned endLine = 0; |
| unsigned endCharacter; |
| llvm::Optional<std::string> kind; |
| }; |
| llvm::json::Value toJSON(const FoldingRange &Range); |
| |
| /// Keys starting with an underscore(_) represent leaves, e.g. _total or _self |
| /// for memory usage of whole subtree or only that specific node in bytes. All |
| /// other keys represents children. An example: |
| /// { |
| /// "_self": 0, |
| /// "_total": 8, |
| /// "child1": { |
| /// "_self": 4, |
| /// "_total": 4, |
| /// } |
| /// "child2": { |
| /// "_self": 2, |
| /// "_total": 4, |
| /// "child_deep": { |
| /// "_self": 2, |
| /// "_total": 2, |
| /// } |
| /// } |
| /// } |
| llvm::json::Value toJSON(const MemoryTree &MT); |
| |
| /// Payload for textDocument/ast request. |
| /// This request is a clangd extension. |
| struct ASTParams { |
| /// The text document. |
| TextDocumentIdentifier textDocument; |
| |
| /// The position of the node to be dumped. |
| /// The highest-level node that entirely contains the range will be returned. |
| /// If no range is given, the root translation unit node will be returned. |
| llvm::Optional<Range> range; |
| }; |
| bool fromJSON(const llvm::json::Value &, ASTParams &, llvm::json::Path); |
| |
| /// Simplified description of a clang AST node. |
| /// This is clangd's internal representation of C++ code. |
| struct ASTNode { |
| /// The general kind of node, such as "expression" |
| /// Corresponds to the base AST node type such as Expr. |
| std::string role; |
| /// The specific kind of node this is, such as "BinaryOperator". |
| /// This is usually a concrete node class (with Expr etc suffix dropped). |
| /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind). |
| std::string kind; |
| /// Brief additional information, such as "||" for the particular operator. |
| /// The information included depends on the node kind, and may be empty. |
| std::string detail; |
| /// A one-line dump of detailed information about the node. |
| /// This includes role/kind/description information, but is rather cryptic. |
| /// It is similar to the output from `clang -Xclang -ast-dump`. |
| /// May be empty for certain types of nodes. |
| std::string arcana; |
| /// The range of the original source file covered by this node. |
| /// May be missing for implicit nodes, or those created by macro expansion. |
| llvm::Optional<Range> range; |
| /// Nodes nested within this one, such as the operands of a BinaryOperator. |
| std::vector<ASTNode> children; |
| }; |
| llvm::json::Value toJSON(const ASTNode &); |
| llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &); |
| |
| } // namespace clangd |
| } // namespace clang |
| |
| namespace llvm { |
| template <> struct format_provider<clang::clangd::Position> { |
| static void format(const clang::clangd::Position &Pos, raw_ostream &OS, |
| StringRef Style) { |
| assert(Style.empty() && "style modifiers for this type are not supported"); |
| OS << Pos; |
| } |
| }; |
| } // namespace llvm |
| |
| // NOLINTEND(readability-identifier-naming) |
| |
| #endif |