18 #include "clang/Basic/LLVM.h" 19 #include "llvm/ADT/Hashing.h" 20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/Support/Format.h" 22 #include "llvm/Support/FormatVariadic.h" 23 #include "llvm/Support/JSON.h" 24 #include "llvm/Support/Path.h" 25 #include "llvm/Support/raw_ostream.h" 33 llvm::StringRef TUPath) {
34 assert(llvm::sys::path::is_absolute(AbsPath) &&
"the path is relative");
37 elog(
"URIForFile: failed to resolve path {0} with TU path {1}: " 38 "{2}.\nUsing unresolved path.",
39 AbsPath, TUPath, Resolved.takeError());
46 llvm::StringRef HintPath) {
49 return Resolved.takeError();
54 if (
auto S = E.getAsString()) {
57 elog(
"Failed to parse URI {0}: {1}", *S, Parsed.takeError());
60 if (Parsed->scheme() !=
"file" && Parsed->scheme() !=
"test") {
61 elog(
"Clangd only supports 'file' URI scheme for workspace files: {0}",
68 elog(
"{0}", U.takeError());
84 return llvm::json::Object{{
"uri", R.
uri}};
88 llvm::json::ObjectMapper O(Params);
89 return O && O.map(
"uri", R.
uri);
93 llvm::json::ObjectMapper O(Params);
94 return O && O.map(
"line", R.
line) && O.map(
"character", R.
character);
98 return llvm::json::Object{
109 llvm::json::ObjectMapper O(Params);
110 return O && O.map(
"start", R.
start) && O.map(
"end", R.
end);
114 return llvm::json::Object{
121 return OS << R.
start <<
'-' << R.
end;
125 return llvm::json::Object{
132 return OS << L.
range <<
'@' << L.
uri;
136 llvm::json::ObjectMapper O(Params);
137 return O && O.map(
"uri", R.
uri) && O.map(
"languageId", R.
languageId) &&
138 O.map(
"version", R.
version) && O.map(
"text", R.
text);
142 llvm::json::ObjectMapper O(Params);
143 return O && O.map(
"range", R.
range) && O.map(
"newText", R.
newText);
147 return llvm::json::Object{
154 OS << TE.
range <<
" => \"";
155 llvm::printEscapedString(TE.
newText, OS);
160 if (
auto S = E.getAsString()) {
164 }
else if (*S ==
"messages") {
167 }
else if (*S ==
"verbose") {
176 if (
auto T = E.getAsInteger()) {
187 if (
auto *A = E.getAsArray()) {
188 for (
size_t I = 0; I < A->size(); ++I) {
191 Out.set(
size_t(KindOut));
200 auto KindVal =
static_cast<size_t>(
Kind);
201 if (KindVal >=
SymbolKindMin && KindVal <= SupportedSymbolKinds.size() &&
202 SupportedSymbolKinds[KindVal])
217 const llvm::json::Object *O = Params.getAsObject();
220 if (
auto *TextDocument = O->getObject(
"textDocument")) {
221 if (
auto *Diagnostics = TextDocument->getObject(
"publishDiagnostics")) {
222 if (
auto CategorySupport = Diagnostics->getBoolean(
"categorySupport"))
224 if (
auto CodeActions = Diagnostics->getBoolean(
"codeActionsInline"))
227 if (
auto *Completion = TextDocument->getObject(
"completion")) {
228 if (
auto *Item = Completion->getObject(
"completionItem")) {
229 if (
auto SnippetSupport = Item->getBoolean(
"snippetSupport"))
232 if (
auto *ItemKind = Completion->getObject(
"completionItemKind")) {
233 if (
auto *ValueSet = ItemKind->get(
"valueSet")) {
240 if (
auto *
CodeAction = TextDocument->getObject(
"codeAction")) {
241 if (
CodeAction->getObject(
"codeActionLiteralSupport"))
244 if (
auto *
DocumentSymbol = TextDocument->getObject(
"documentSymbol")) {
245 if (
auto HierarchicalSupport =
250 if (
auto *Workspace = O->getObject(
"workspace")) {
251 if (
auto *
Symbol = Workspace->getObject(
"symbol")) {
253 if (
auto *ValueSet =
SymbolKind->get(
"valueSet")) {
265 llvm::json::ObjectMapper O(Params);
274 O.map(
"trace", R.
trace);
280 llvm::json::ObjectMapper O(Params);
285 llvm::json::ObjectMapper O(Params);
290 llvm::json::ObjectMapper O(Params);
297 if (
auto T = E.getAsInteger()) {
308 llvm::json::ObjectMapper O(Params);
309 return O && O.map(
"uri", R.
uri) && O.map(
"type", R.
type);
313 llvm::json::ObjectMapper O(Params);
314 return O && O.map(
"changes", R.
changes);
319 llvm::json::ObjectMapper O(Params);
320 return O && O.map(
"range", R.
range) && O.map(
"rangeLength", R.
rangeLength) &&
321 O.map(
"text", R.
text);
325 llvm::json::ObjectMapper O(Params);
326 return O && O.map(
"tabSize", R.
tabSize) &&
331 return llvm::json::Object{
339 llvm::json::ObjectMapper O(Params);
346 llvm::json::ObjectMapper O(Params);
348 O.map(
"position", R.
position) && O.map(
"ch", R.
ch) &&
353 llvm::json::ObjectMapper O(Params);
359 llvm::json::ObjectMapper O(Params);
364 llvm::json::Object
Diag{
373 return std::move(
Diag);
377 llvm::json::ObjectMapper O(Params);
378 if (!O || !O.map(
"range", R.
range) || !O.map(
"message", R.
message))
386 llvm::json::ObjectMapper O(Params);
391 OS << D.
range <<
" [";
413 llvm::json::ObjectMapper O(Params);
419 llvm::json::ObjectMapper O(Params);
420 return O && O.map(
"changes", R.
changes);
426 llvm::json::ObjectMapper O(Params);
427 if (!O || !O.map(
"command", R.
command))
430 auto Args = Params.getAsObject()->getArray(
"arguments");
431 if (R.
command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND) {
432 return Args && Args->size() == 1 &&
439 return llvm::json::Object{
441 {
"kind",
static_cast<int>(P.
kind)},
459 llvm::json::Object result{{
"name", llvm::json::Value(
nullptr)},
460 {
"containerName", llvm::json::Value(
nullptr)},
461 {
"usr", llvm::json::Value(
nullptr)},
462 {
"id", llvm::json::Value(
nullptr)}};
465 result[
"name"] = P.
name;
471 result[
"usr"] = P.
USR;
474 result[
"id"] = P.
ID.getValue().str();
477 return llvm::json::Value(std::move(result));
483 llvm::StringRef ContNameRef;
484 if (!ContNameRef.endswith(
"::")) {
493 llvm::json::ObjectMapper O(Params);
494 return O && O.map(
"query", R.
query);
498 auto Cmd = llvm::json::Object{{
"title", C.title}, {
"command", C.command}};
500 Cmd[
"arguments"] = {*C.workspaceEdit};
501 return std::move(Cmd);
525 {
"kind",
static_cast<int>(S.
kind)},
534 Result[
"deprecated"] =
true;
536 return llvm::json::Value(std::move(
Result));
541 return llvm::json::Object{};
542 llvm::json::Object FileChanges;
543 for (
auto &Change : *WE.
changes)
544 FileChanges[Change.first] = llvm::json::Array(Change.second);
545 return llvm::json::Object{{
"changes", std::move(FileChanges)}};
549 return llvm::json::Object{{
"edit", Params.
edit}};
553 llvm::json::ObjectMapper O(Params);
559 llvm::json::ObjectMapper O(Params);
564 if (!O.map(
"triggerKind", triggerKind))
568 if (
auto *TC = Params.getAsObject()->get(
"triggerCharacter"))
574 if (!
fromJSON(Params, static_cast<TextDocumentPositionParams &>(R)))
576 if (
auto *
Context = Params.getAsObject()->
get(
"context"))
588 llvm_unreachable(
"Invalid MarkupKind");
592 if (MC.
value.empty())
595 return llvm::json::Object{
604 if (H.
range.hasValue())
611 if (
auto T = E.getAsInteger()) {
624 auto KindVal =
static_cast<size_t>(
Kind);
626 KindVal <= supportedCompletionItemKinds.size() &&
627 supportedCompletionItemKinds[KindVal])
644 if (
auto *A = E.getAsArray()) {
645 for (
size_t I = 0; I < A->size(); ++I) {
648 Out.set(
size_t(KindOut));
656 assert(!CI.
label.empty() &&
"completion item label is required");
692 return llvm::json::Object{
694 {
"items", llvm::json::Array(L.
items)},
699 assert(!PI.
label.empty() &&
"parameter information label is required");
707 assert(!SI.
label.empty() &&
"signature information label is required");
708 llvm::json::Object
Result{
710 {
"parameters", llvm::json::Array(SI.
parameters)},
725 "Unexpected negative value for number of active signatures.");
727 "Unexpected negative value for active parameter index");
728 return llvm::json::Object{
731 {
"signatures", llvm::json::Array(SH.
signatures)},
736 llvm::json::ObjectMapper O(Params);
742 return llvm::json::Object{
744 {
"kind",
static_cast<int>(DH.
kind)},
749 return llvm::json::Object{
750 {
"uri", FStatus.
uri},
751 {
"state", FStatus.
state},
767 llvm::json::ObjectMapper O(Params);
768 return O && O.map(
"settings", CCP.
settings);
773 llvm::json::ObjectMapper O(Params);
779 llvm::json::ObjectMapper O(Params);
787 llvm::json::ObjectMapper O(Params);
std::string insertText
A string that should be inserted to a document when selecting this completion.
std::string USR
Unified Symbol Resolution identifier This is an opaque string uniquely identifying a symbol...
const tooling::CompileCommand & Command
URIForFile uri
The file's URI.
llvm::json::Value toJSON(const FuzzyFindRequest &Request)
llvm::Optional< TextEdit > textEdit
An edit which is applied to a document when selecting this completion.
Exact commands are not specified in the protocol so we define the ones supported by Clangd here...
llvm::Optional< SymbolKindBitset > WorkspaceSymbolKinds
The supported set of SymbolKinds for workspace/symbol.
llvm::Optional< URIForFile > rootUri
The rootUri of the workspace.
Position start
The range's start position.
friend bool operator==(const URIForFile &LHS, const URIForFile &RHS)
ConfigurationSettings settings
Represents a collection of completion items to be presented in the editor.
Range range
The range this highlight applies to.
llvm::Optional< bool > wantDiagnostics
Forces diagnostics to be generated, or to not be generated, for this version of the file...
std::vector< std::string > compilationCommand
Range range
The range for which the command was invoked.
CodeActionContext context
Context carrying additional information.
static const llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND
CompletionItemKind kind
The kind of this completion item.
Clangd extension: parameters configurable at initialize time.
bool CompletionSnippets
Client supports snippets as insert text.
std::vector< CompletionItem > items
The completion items.
llvm::Optional< std::vector< CodeAction > > codeActions
Clangd extension: code actions related to this diagnostic.
llvm::Optional< std::map< std::string, std::vector< TextEdit > > > changes
Holds changes to existing resources.
llvm::Optional< std::string > kind
The kind of the code action.
std::string title
A short, human-readable, title for this code action.
llvm::Optional< Range > range
An optional range is a range inside a text document that is used to visualize a hover, e.g.
TextDocumentIdentifier textDocument
The document that was closed.
static llvm::StringRef toTextKind(MarkupKind Kind)
std::string state
The human-readable string presents the current state of the file, can be shown in the UI (e...
A code action represents a change that can be performed in code, e.g.
URIForFile uri
The text document's URI.
std::string text
The new text of the range/document.
llvm::Optional< WorkspaceEdit > edit
The workspace edit this code action performs.
Range selectionRange
The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
constexpr auto SymbolKindMin
llvm::Optional< std::string > compilationDatabasePath
std::string sortText
A string that should be used when comparing this item with other items.
constexpr auto CompletionItemKindMin
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
bool isIncomplete
The list is not complete.
std::string documentation
A human-readable string that represents a doc-comment.
Range range
The range enclosing this symbol not including leading/trailing whitespace but everything else like co...
URIForFile uri
The text document's URI.
std::vector< TextEdit > additionalTextEdits
An optional array of additional text edits that are applied when selecting this completion.
void elog(const char *Fmt, Ts &&... Vals)
Represents programming constructs like variables, classes, interfaces etc.
llvm::Optional< int > processId
The process Id of the parent process that started the server.
CompletionItemKind
The kind of a completion entry.
ConfigurationSettings ConfigSettings
A top-level diagnostic that may have Notes and Fixes.
MarkupContent contents
The hover's content.
A document highlight is a range inside a text document which deserves special attention.
URIForFile uri
The text document's URI.
std::string detail
A human-readable string with additional information about this item, like type or symbol information...
const Type * get(const Key< Type > &Key) const
Get data stored for a typed Key.
llvm::Optional< SymbolID > ID
TextDocumentIdentifier textDocument
The document that was opened.
std::string newText
The string to be inserted.
bool DiagnosticCategory
Whether the client accepts diagnostics with category attached to it using the "category" extension...
std::string newName
The new name of the symbol.
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
std::string command
The command identifier, e.g. CLANGD_APPLY_FIX_COMMAND.
static llvm::Expected< URIForFile > fromURI(const URI &U, llvm::StringRef HintPath)
InitializationOptions initializationOptions
User-provided initialization options.
TextDocumentIdentifier textDocument
std::string filterText
A string that should be used when filtering a set of completion items.
TextDocumentIdentifier textDocument
The document in which the command was invoked.
Range range
The range of the text document to be manipulated.
static llvm::Expected< std::string > resolvePath(llvm::StringRef AbsPath, llvm::StringRef HintPath="")
Resolves AbsPath into a canonical path of its URI, by converting AbsPath to URI and resolving the URI...
bool deprecated
Indicates if this item is deprecated.
int activeSignature
The active signature.
std::vector< std::string > fallbackFlags
int activeParameter
The active parameter of the active signature.
llvm::Optional< Range > range
The range of the document that changed.
llvm::Optional< std::string > category
The diagnostic's category.
CompletionTriggerKind triggerKind
How the completion was triggered.
static URIForFile canonicalize(llvm::StringRef AbsPath, llvm::StringRef TUPath)
Canonicalizes AbsPath via URI.
Position position
The position inside the text document.
std::string containerName
std::vector< DocumentSymbol > children
Children of this symbol, e.g. properties of a class.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
std::vector< SignatureInformation > signatures
The resulting signatures.
llvm::Optional< int > rangeLength
The length of the range that got replaced.
bool FileStatus
Clients supports show file status for textDocument/clangd.fileStatus.
std::string name
The name of this symbol.
bool DiagnosticFixes
Whether the client accepts diagnostics with codeActions attached inline.
ClientCapabilities capabilities
The capabilities provided by the client (editor or tool)
TextDocumentItem textDocument
The document that was opened.
A context is an immutable container for per-request data that must be propagated through layers that ...
TextDocumentIdentifier textDocument
The document that did change.
std::map< std::string, ClangdCompileCommand > compilationDatabaseChanges
std::string detail
More detail for this symbol, e.g the signature of a function.
std::vector< FileEvent > changes
The actual file events.
llvm::Optional< CompletionItemKindBitset > CompletionItemKinds
The supported set of CompletionItemKinds for textDocument/completion.
std::string languageId
The text document's language identifier.
llvm::Optional< std::string > rootPath
The rootPath of the workspace.
bool CodeActionStructure
Client supports CodeAction return value for textDocument/codeAction.
bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request)
int line
Line position in a document (zero-based).
std::vector< TextDocumentContentChangeEvent > contentChanges
The actual content changes.
int character
Character offset on a line in a document (zero-based).
CompletionContext context
Represents the signature of a callable.
std::string query
A non-empty query string.
SymbolKind kind
The kind of this symbol.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::bitset< SymbolKindMax+1 > SymbolKindBitset
std::string message
The diagnostic's code.
std::string triggerCharacter
The trigger character (a single character) that has trigger code complete.
TextDocumentIdentifier textDocument
The text document.
std::string label
The label of this completion item.
DocumentHighlightKind kind
The highlight kind, default is DocumentHighlightKind.Text.
SymbolKind adjustKindToCapability(SymbolKind Kind, SymbolKindBitset &SupportedSymbolKinds)
static const llvm::StringLiteral QUICKFIX_KIND
A URI describes the location of a source file.
std::vector< Diagnostic > diagnostics
An array of diagnostics.
int severity
The diagnostic's severity.
bool deprecated
Indicates if this symbol is deprecated.
llvm::Optional< Command > command
A command this code action executes.
The parameters of a Workspace Symbol Request.
FileChangeType type
The change type.
std::string workingDirectory
std::string text
The content of the opened text document.
Clangd extension: indicates the current state of the file in clangd, sent from server via the textDoc...
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
llvm::Optional< std::vector< Diagnostic > > diagnostics
The diagnostics that this code action resolves.
Position position
The position at which this request was sent.
URIForFile uri
The text document's URI.
static llvm::Expected< URI > parse(llvm::StringRef Uri)
Parse a URI string "<scheme>:[//<authority>/]<path>".
Range range
The range at which the message applies.
friend bool operator<(const URIForFile &LHS, const URIForFile &RHS)
int version
The version number of this document (it will strictly increase after each.
Position end
The range's end position.
llvm::Optional< WorkspaceEdit > workspaceEdit
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
InsertTextFormat insertTextFormat
The format of the insert text.
Clangd extension that's used in the 'compilationDatabaseChanges' in workspace/didChangeConfiguration ...
Represents information about identifier.
llvm::Optional< TraceLevel > trace
The initial trace setting. If omitted trace is disabled ('off').
bool HierarchicalDocumentSymbol
Client supports hierarchical document symbols.