15 #include "llvm/ADT/ScopeExit.h" 16 #include "llvm/Support/Errc.h" 17 #include "llvm/Support/FormatVariadic.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/ScopedPrinter.h" 24 class IgnoreCompletionError :
public llvm::ErrorInfo<CancelledError> {
26 void log(llvm::raw_ostream &OS)
const override {
27 OS <<
"ignored auto-triggered completion, preceding char did not match";
29 std::error_code convertToErrorCode()
const override {
30 return std::make_error_code(std::errc::operation_canceled);
34 void adjustSymbolKinds(llvm::MutableArrayRef<DocumentSymbol> Syms,
36 for (
auto &S : Syms) {
38 adjustSymbolKinds(S.children, Kinds);
72 log(
"<-- {0}", Method);
76 elog(
"Notification {0} before initialization", Method);
77 else if (Method ==
"$/cancelRequest")
78 onCancel(std::move(Params));
79 else if (
auto Handler = Notifications.lookup(Method))
80 Handler(std::move(Params));
82 log(
"unhandled notification {0}", Method);
87 llvm::json::Value ID)
override {
89 WithContext WithCancel(cancelableRequestContext(ID));
92 ReplyOnce Reply(ID, Method, &Server, Tracer.
Args);
93 log(
"<-- {0}({1})", Method, ID);
94 if (!Server.Server && Method !=
"initialize") {
95 elog(
"Call {0} before initialization.", Method);
96 Reply(llvm::make_error<LSPError>(
"server not initialized",
98 }
else if (
auto Handler = Calls.lookup(Method))
99 Handler(std::move(Params), std::move(Reply));
101 Reply(llvm::make_error<LSPError>(
"method not found",
107 llvm::Expected<llvm::json::Value>
Result)
override {
110 log(
"<-- reply({0})", ID);
117 template <
typename Param,
typename Result>
120 Calls[
Method] = [
Method, Handler,
this](llvm::json::Value RawParams,
124 (Server.*Handler)(P, std::move(Reply));
126 elog(
"Failed to decode {0} request.", Method);
127 Reply(llvm::make_error<LSPError>(
"failed to decode request",
134 template <
typename Param>
138 this](llvm::json::Value RawParams) {
141 elog(
"Failed to decode {0} request.", Method);
146 (Server.*Handler)(P);
157 std::atomic<bool> Replied = {
false};
158 std::chrono::steady_clock::time_point Start;
159 llvm::json::Value ID;
162 llvm::json::Object *TraceArgs;
165 ReplyOnce(
const llvm::json::Value &ID, llvm::StringRef Method,
167 : Start(std::chrono::steady_clock::now()), ID(ID),
Method(Method),
168 Server(Server), TraceArgs(TraceArgs) {
171 ReplyOnce(ReplyOnce &&Other)
172 : Replied(Other.Replied.load()), Start(Other.Start),
173 ID(std::move(Other.ID)),
Method(std::move(Other.Method)),
174 Server(Other.Server), TraceArgs(Other.TraceArgs) {
175 Other.Server =
nullptr;
177 ReplyOnce &operator=(ReplyOnce &&) =
delete;
178 ReplyOnce(
const ReplyOnce &) =
delete;
179 ReplyOnce &operator=(
const ReplyOnce &) =
delete;
182 if (Server && !Replied) {
183 elog(
"No reply to message {0}({1})", Method, ID);
184 assert(
false &&
"must reply to all calls!");
185 (*this)(llvm::make_error<LSPError>(
"server failed to reply",
190 void operator()(llvm::Expected<llvm::json::Value> Reply) {
191 assert(Server &&
"moved-from!");
192 if (Replied.exchange(
true)) {
193 elog(
"Replied twice to message {0}({1})", Method, ID);
194 assert(
false &&
"must reply to each call only once!");
197 auto Duration = std::chrono::steady_clock::now() - Start;
199 log(
"--> reply:{0}({1}) {2:ms}", Method, ID, Duration);
201 (*TraceArgs)[
"Reply"] = *Reply;
202 std::lock_guard<std::mutex> Lock(Server->TranspWriter);
203 Server->Transp.
reply(std::move(ID), std::move(Reply));
205 llvm::Error Err = Reply.takeError();
206 log(
"--> reply:{0}({1}) {2:ms}, error: {3}", Method, ID, Duration, Err);
208 (*TraceArgs)[
"Error"] = llvm::to_string(Err);
209 std::lock_guard<std::mutex> Lock(Server->TranspWriter);
210 Server->Transp.
reply(std::move(ID), std::move(Err));
215 llvm::StringMap<std::function<void(llvm::json::Value)>> Notifications;
216 llvm::StringMap<std::function<void(llvm::json::Value, ReplyOnce)>> Calls;
221 mutable std::mutex RequestCancelersMutex;
222 llvm::StringMap<std::pair<
Canceler,
unsigned>> RequestCancelers;
223 unsigned NextRequestCookie = 0;
224 void onCancel(
const llvm::json::Value &Params) {
225 const llvm::json::Value *ID =
nullptr;
226 if (
auto *O = Params.getAsObject())
229 elog(
"Bad cancellation request: {0}", Params);
232 auto StrID = llvm::to_string(*ID);
233 std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
234 auto It = RequestCancelers.find(StrID);
235 if (It != RequestCancelers.end())
242 Context cancelableRequestContext(
const llvm::json::Value &ID) {
244 auto StrID = llvm::to_string(ID);
245 auto Cookie = NextRequestCookie++;
247 std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
248 RequestCancelers[StrID] = {std::move(Task.second), Cookie};
253 return Task.first.derive(llvm::make_scope_exit([
this, StrID, Cookie] {
254 std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
255 auto It = RequestCancelers.find(StrID);
256 if (It != RequestCancelers.end() && It->second.second == Cookie)
257 RequestCancelers.erase(It);
265 void ClangdLSPServer::call(llvm::StringRef Method, llvm::json::Value Params) {
266 auto ID = NextCallID++;
267 log(
"--> {0}({1})", Method, ID);
269 std::lock_guard<std::mutex> Lock(TranspWriter);
270 Transp.call(Method, std::move(Params), ID);
273 void ClangdLSPServer::notify(llvm::StringRef Method, llvm::json::Value Params) {
274 log(
"--> {0}", Method);
275 std::lock_guard<std::mutex> Lock(TranspWriter);
276 Transp.notify(Method, std::move(Params));
282 ClangdServerOpts.WorkspaceRoot = Params.
rootUri->file();
284 ClangdServerOpts.WorkspaceRoot = *Params.
rootPath;
286 return Reply(llvm::make_error<LSPError>(
"server already initialized",
291 BaseCDB = llvm::make_unique<DirectoryBasedGlobalCompilationDatabase>(
294 ClangdServerOpts.ResourceDir);
295 Server.emplace(*CDB, FSProvider, static_cast<DiagnosticsConsumer &>(*
this),
307 SupportsHierarchicalDocumentSymbol =
310 Reply(llvm::json::Object{
314 {
"documentFormattingProvider",
true},
315 {
"documentRangeFormattingProvider",
true},
316 {
"documentOnTypeFormattingProvider",
318 {
"firstTriggerCharacter",
"}"},
319 {
"moreTriggerCharacter", {}},
321 {
"codeActionProvider",
true},
322 {
"completionProvider",
324 {
"resolveProvider",
false},
327 {
"triggerCharacters", {
".",
">",
":"}},
329 {
"signatureHelpProvider",
331 {
"triggerCharacters", {
"(",
","}},
333 {
"definitionProvider",
true},
334 {
"documentHighlightProvider",
true},
335 {
"hoverProvider",
true},
336 {
"renameProvider",
true},
337 {
"documentSymbolProvider",
true},
338 {
"workspaceSymbolProvider",
true},
339 {
"referencesProvider",
true},
340 {
"executeCommandProvider",
350 ShutdownRequestReceived =
true;
356 void ClangdLSPServer::onSync(
const NoParams &Params,
358 if (Server->blockUntilIdleForTest(60))
361 Reply(llvm::createStringError(llvm::inconvertibleErrorCode(),
362 "Not idle after a minute"));
365 void ClangdLSPServer::onDocumentDidOpen(
371 DraftMgr.addDraft(File, Contents);
375 void ClangdLSPServer::onDocumentDidChange(
383 llvm::Expected<std::string>
Contents =
389 DraftMgr.removeDraft(File);
390 Server->removeDocument(File);
391 elog(
"Failed to update {0}: {1}", File, Contents.takeError());
395 Server->addDocument(File, *Contents, WantDiags);
399 Server->onFileEvent(Params);
406 Edit.
edit = std::move(WE);
409 call(
"workspace/applyEdit", Edit);
422 Reply(
"Fix applied.");
428 Reply(llvm::make_error<LSPError>(
429 llvm::formatv(
"Unsupported command \"{0}\".", Params.
command).str(),
434 void ClangdLSPServer::onWorkspaceSymbol(
436 Callback<std::vector<SymbolInformation>> Reply) {
437 Server->workspaceSymbols(
438 Params.
query, CCOpts.Limit,
440 [
this](decltype(Reply) Reply,
441 llvm::Expected<std::vector<SymbolInformation>> Items) {
443 return Reply(Items.takeError());
444 for (
auto &Sym : *Items)
447 Reply(std::move(*Items));
452 void ClangdLSPServer::onRename(
const RenameParams &Params,
455 llvm::Optional<std::string> Code = DraftMgr.getDraft(File);
457 return Reply(llvm::make_error<LSPError>(
463 [File, Code, Params](
464 decltype(Reply) Reply,
465 llvm::Expected<std::vector<tooling::Replacement>> Replacements) {
467 return Reply(Replacements.takeError());
471 std::vector<TextEdit> Edits;
472 for (
const auto &R : *Replacements)
481 void ClangdLSPServer::onDocumentDidClose(
484 DraftMgr.removeDraft(File);
485 Server->removeDocument(File);
488 void ClangdLSPServer::onDocumentOnTypeFormatting(
490 Callback<std::vector<TextEdit>> Reply) {
492 auto Code = DraftMgr.getDraft(
File);
494 return Reply(llvm::make_error<LSPError>(
495 "onDocumentOnTypeFormatting called for non-added file",
498 auto ReplacementsOrError = Server->formatOnType(*Code,
File, Params.
position);
499 if (ReplacementsOrError)
502 Reply(ReplacementsOrError.takeError());
505 void ClangdLSPServer::onDocumentRangeFormatting(
507 Callback<std::vector<TextEdit>> Reply) {
509 auto Code = DraftMgr.getDraft(
File);
511 return Reply(llvm::make_error<LSPError>(
512 "onDocumentRangeFormatting called for non-added file",
515 auto ReplacementsOrError = Server->formatRange(*Code,
File, Params.
range);
516 if (ReplacementsOrError)
519 Reply(ReplacementsOrError.takeError());
522 void ClangdLSPServer::onDocumentFormatting(
524 Callback<std::vector<TextEdit>> Reply) {
526 auto Code = DraftMgr.getDraft(
File);
528 return Reply(llvm::make_error<LSPError>(
529 "onDocumentFormatting called for non-added file",
532 auto ReplacementsOrError = Server->formatFile(*Code,
File);
533 if (ReplacementsOrError)
536 Reply(ReplacementsOrError.takeError());
541 static std::vector<SymbolInformation>
545 std::vector<SymbolInformation>
Results;
546 std::function<void(const DocumentSymbol &, llvm::StringRef)> Process =
547 [&](
const DocumentSymbol &S, llvm::Optional<llvm::StringRef> ParentName) {
555 Results.push_back(std::move(SI));
556 std::string FullName =
557 !ParentName ? S.
name : (ParentName->str() +
"::" + S.
name);
559 Process(C, FullName);
561 for (
auto &S : Symbols)
569 Server->documentSymbols(
572 [
this, FileURI](decltype(Reply) Reply,
573 llvm::Expected<std::vector<DocumentSymbol>> Items) {
575 return Reply(Items.takeError());
576 adjustSymbolKinds(*Items, SupportedSymbolKinds);
577 if (SupportsHierarchicalDocumentSymbol)
578 return Reply(std::move(*Items));
591 }
else if (Action.
edit) {
592 Cmd.command = Command::CLANGD_APPLY_FIX_COMMAND;
593 Cmd.workspaceEdit = *Action.
edit;
597 Cmd.title = Action.
title;
599 Cmd.title =
"Apply fix: " + Cmd.title;
607 return Reply(llvm::make_error<LSPError>(
610 std::vector<CodeAction> Actions;
614 Actions.back().diagnostics = {D};
618 if (SupportsCodeAction)
619 Reply(llvm::json::Array(Actions));
622 for (
const auto &
Action : Actions)
624 Commands.push_back(std::move(*
Command));
625 Reply(llvm::json::Array(Commands));
631 if (!shouldRunCompletion(Params))
632 return Reply(llvm::make_error<IgnoreCompletionError>());
635 [
this](decltype(Reply) Reply,
636 llvm::Expected<CodeCompleteResult> List) {
638 return Reply(List.takeError());
641 for (
const auto &R : List->Completions) {
644 C.
kind, SupportedCompletionItemKinds);
645 LSPList.
items.push_back(std::move(C));
647 return Reply(std::move(LSPList));
659 Callback<std::vector<Location>> Reply) {
666 llvm::Optional<Path>
Result = Server->switchSourceHeader(Params.
uri.
file());
670 void ClangdLSPServer::onDocumentHighlight(
672 Callback<std::vector<DocumentHighlight>> Reply) {
678 Callback<llvm::Optional<Hover>> Reply) {
683 void ClangdLSPServer::applyConfiguration(
686 bool ShouldReparseOpenFiles =
false;
691 auto Old = CDB->getCompileCommand(File);
693 tooling::CompileCommand(std::move(
Entry.second.workingDirectory), File,
694 std::move(
Entry.second.compilationCommand),
697 CDB->setCompileCommand(File, std::move(New));
698 ShouldReparseOpenFiles =
true;
701 if (ShouldReparseOpenFiles)
702 reparseOpenedFiles();
706 void ClangdLSPServer::onChangeConfiguration(
708 applyConfiguration(Params.
settings);
712 Callback<std::vector<Location>> Reply) {
714 CCOpts.Limit, std::move(Reply));
718 Callback<std::vector<SymbolDetails>> Reply) {
728 : Transp(Transp), MsgHandler(new
MessageHandler(*this)), CCOpts(CCOpts),
729 SupportedSymbolKinds(defaultSymbolKinds()),
730 SupportedCompletionItemKinds(defaultCompletionItemKinds()),
731 UseDirBasedCDB(UseDirBasedCDB),
732 CompileCommandsDir(std::move(CompileCommandsDir)),
733 ClangdServerOpts(Opts) {
735 MsgHandler->bind(
"initialize", &ClangdLSPServer::onInitialize);
736 MsgHandler->bind(
"shutdown", &ClangdLSPServer::onShutdown);
737 MsgHandler->bind(
"sync", &ClangdLSPServer::onSync);
738 MsgHandler->bind(
"textDocument/rangeFormatting", &ClangdLSPServer::onDocumentRangeFormatting);
739 MsgHandler->bind(
"textDocument/onTypeFormatting", &ClangdLSPServer::onDocumentOnTypeFormatting);
740 MsgHandler->bind(
"textDocument/formatting", &ClangdLSPServer::onDocumentFormatting);
741 MsgHandler->bind(
"textDocument/codeAction", &ClangdLSPServer::onCodeAction);
742 MsgHandler->bind(
"textDocument/completion", &ClangdLSPServer::onCompletion);
743 MsgHandler->bind(
"textDocument/signatureHelp", &ClangdLSPServer::onSignatureHelp);
744 MsgHandler->bind(
"textDocument/definition", &ClangdLSPServer::onGoToDefinition);
745 MsgHandler->bind(
"textDocument/references", &ClangdLSPServer::onReference);
746 MsgHandler->bind(
"textDocument/switchSourceHeader", &ClangdLSPServer::onSwitchSourceHeader);
747 MsgHandler->bind(
"textDocument/rename", &ClangdLSPServer::onRename);
748 MsgHandler->bind(
"textDocument/hover", &ClangdLSPServer::onHover);
749 MsgHandler->bind(
"textDocument/documentSymbol", &ClangdLSPServer::onDocumentSymbol);
750 MsgHandler->bind(
"workspace/executeCommand", &ClangdLSPServer::onCommand);
751 MsgHandler->bind(
"textDocument/documentHighlight", &ClangdLSPServer::onDocumentHighlight);
752 MsgHandler->bind(
"workspace/symbol", &ClangdLSPServer::onWorkspaceSymbol);
753 MsgHandler->bind(
"textDocument/didOpen", &ClangdLSPServer::onDocumentDidOpen);
754 MsgHandler->bind(
"textDocument/didClose", &ClangdLSPServer::onDocumentDidClose);
755 MsgHandler->bind(
"textDocument/didChange", &ClangdLSPServer::onDocumentDidChange);
756 MsgHandler->bind(
"workspace/didChangeWatchedFiles", &ClangdLSPServer::onFileEvent);
757 MsgHandler->bind(
"workspace/didChangeConfiguration", &ClangdLSPServer::onChangeConfiguration);
758 MsgHandler->bind(
"textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
766 bool CleanExit =
true;
767 if (
auto Err = Transp.
loop(*MsgHandler)) {
768 elog(
"Transport error: {0}", std::move(Err));
774 return CleanExit && ShutdownRequestReceived;
777 std::vector<Fix> ClangdLSPServer::getFixes(llvm::StringRef
File,
779 std::lock_guard<std::mutex> Lock(FixItsMutex);
780 auto DiagToFixItsIter = FixItsMap.find(File);
781 if (DiagToFixItsIter == FixItsMap.end())
784 const auto &DiagToFixItsMap = DiagToFixItsIter->second;
785 auto FixItsIter = DiagToFixItsMap.find(D);
786 if (FixItsIter == DiagToFixItsMap.end())
789 return FixItsIter->second;
792 bool ClangdLSPServer::shouldRunCompletion(
796 (Trigger !=
">" && Trigger !=
":"))
812 vlog(
"could not convert position '{0}' to offset for file '{1}'",
820 return (*Code)[*Offset - 2] ==
'-';
822 return (*Code)[*Offset - 2] ==
':';
823 assert(
false &&
"unhandled trigger character");
827 void ClangdLSPServer::onDiagnosticsReady(
PathRef File,
828 std::vector<Diag> Diagnostics) {
830 std::vector<Diagnostic> LSPDiagnostics;
831 DiagnosticToReplacementMap LocalFixIts;
832 for (
auto &
Diag : Diagnostics) {
835 auto &FixItsForDiagnostic = LocalFixIts[Diag];
836 llvm::copy(Fixes, std::back_inserter(FixItsForDiagnostic));
837 LSPDiagnostics.push_back(std::move(Diag));
844 std::lock_guard<std::mutex> Lock(FixItsMutex);
845 FixItsMap[
File] = LocalFixIts;
849 notify(
"textDocument/publishDiagnostics",
852 {
"diagnostics", std::move(LSPDiagnostics)},
856 void ClangdLSPServer::onFileUpdated(
PathRef File,
const TUStatus &Status) {
857 if (!SupportFileStatus)
866 notify(
"textDocument/clangd.fileStatus", Status.
render(File));
869 void ClangdLSPServer::reparseOpenedFiles() {
871 Server->addDocument(FilePath, *DraftMgr.
getDraft(FilePath),
const tooling::CompileCommand & Command
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.
ConfigurationSettings settings
static std::vector< SymbolInformation > flattenSymbolHierarchy(llvm::ArrayRef< DocumentSymbol > Symbols, const URIForFile &FileURI)
The functions constructs a flattened view of the DocumentSymbol hierarchy.
Represents a collection of completion items to be presented in the editor.
Diagnostics must be generated for this snapshot.
llvm::Optional< bool > wantDiagnostics
Forces diagnostics to be generated, or to not be generated, for this version of the file...
std::function< void()> Canceler
A canceller requests cancellation of a task, when called.
FileStatus render(PathRef File) const
Serialize this to an LSP file status item.
CodeActionContext context
Context carrying additional information.
bool onReply(llvm::json::Value ID, llvm::Expected< llvm::json::Value > Result) override
static const llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND
CompletionItemKind kind
The kind of this completion item.
bool CompletionSnippets
Client supports snippets as insert text.
std::vector< CompletionItem > items
The completion items.
void bind(const char *Method, void(ClangdLSPServer::*Handler)(const Param &))
CodeAction toCodeAction(const Fix &F, const URIForFile &File)
Convert from Fix to LSP CodeAction.
Documents are synced by sending the full content on open.
llvm::Optional< std::map< std::string, std::vector< TextEdit > > > changes
Holds changes to existing resources.
static cl::list< std::string > Commands("c", cl::desc("Specify command to run"), cl::value_desc("command"), cl::cat(ClangQueryCategory))
llvm::Optional< std::string > kind
The kind of the code action.
std::string title
A short, human-readable, title for this code action.
TextDocumentIdentifier textDocument
The document that was closed.
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
A code action represents a change that can be performed in code, e.g.
URIForFile uri
The text document's URI.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
llvm::Optional< WorkspaceEdit > edit
The workspace edit this code action performs.
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
std::vector< CodeCompletionResult > Results
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
constexpr auto SymbolKindMin
llvm::Optional< std::string > compilationDatabasePath
constexpr auto CompletionItemKindMin
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Documents should not be synced at all.
bool isIncomplete
The list is not complete.
Range range
The range enclosing this symbol not including leading/trailing whitespace but everything else like co...
void vlog(const char *Fmt, Ts &&... Vals)
void elog(const char *Fmt, Ts &&... Vals)
Represents programming constructs like variables, classes, interfaces etc.
bool onCall(llvm::StringRef Method, llvm::json::Value Params, llvm::json::Value ID) override
ConfigurationSettings ConfigSettings
A top-level diagnostic that may have Notes and Fixes.
URIForFile uri
The text document's URI.
static URI createFile(llvm::StringRef AbsolutePath)
This creates a file:// URI for AbsolutePath. The path must be absolute.
TextDocumentIdentifier textDocument
The document that was opened.
void toLSPDiags(const Diag &D, const URIForFile &File, const ClangdDiagnosticOptions &Opts, llvm::function_ref< void(clangd::Diagnostic, llvm::ArrayRef< Fix >)> OutFn)
Conversion to LSP diagnostics.
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.
InitializationOptions initializationOptions
User-provided initialization options.
TextDocumentIdentifier textDocument
MessageHandler(ClangdLSPServer &Server)
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
ForwardBinder< Func, Args... > Bind(Func F, Args &&... As)
Creates an object that stores a callable (F) and first arguments to the callable (As) and allows to c...
TextDocumentIdentifier textDocument
The document in which the command was invoked.
ClangdLSPServer(Transport &Transp, const clangd::CodeCompleteOptions &CCOpts, llvm::Optional< Path > CompileCommandsDir, bool UseDirBasedCDB, const ClangdServer::Options &Opts)
If CompileCommandsDir has a value, compile_commands.json will be loaded only from CompileCommandsDir...
llvm::unique_function< void()> Action
std::vector< std::string > fallbackFlags
void log(const char *Fmt, Ts &&... Vals)
std::string Path
A typedef to represent a file path.
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::vector< DocumentSymbol > children
Children of this symbol, e.g. properties of a class.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
bool FileStatus
Clients supports show file status for textDocument/clangd.fileStatus.
std::string name
The name of this symbol.
std::pair< Context, Canceler > cancelableTask()
Defines a new task whose cancellation may be requested.
static llvm::Optional< Command > asCommand(const CodeAction &Action)
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
Completion was triggered by a trigger character specified by the triggerCharacters properties of the ...
bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override
llvm::Optional< CompletionItemKindBitset > CompletionItemKinds
The supported set of CompletionItemKinds for textDocument/completion.
llvm::Optional< std::string > rootPath
The rootPath of the workspace.
virtual llvm::Error loop(MessageHandler &)=0
bool CodeActionStructure
Client supports CodeAction return value for textDocument/codeAction.
WithContext replaces Context::current() with a provided scope.
bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request)
void bind(const char *Method, void(ClangdLSPServer::*Handler)(const Param &, Callback< Result >))
std::vector< TextDocumentContentChangeEvent > contentChanges
The actual content changes.
CompletionContext context
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 triggerCharacter
The trigger character (a single character) that has trigger code complete.
TextDocumentIdentifier textDocument
The text document.
TextEdit replacementToEdit(llvm::StringRef Code, const tooling::Replacement &R)
virtual void reply(llvm::json::Value ID, llvm::Expected< llvm::json::Value > Result)=0
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.
llvm::Optional< Command > command
A command this code action executes.
std::vector< TextEdit > replacementsToEdits(llvm::StringRef Code, const tooling::Replacements &Repls)
The parameters of a Workspace Symbol Request.
std::string text
The content of the opened text document.
Position position
The position at which this request was sent.
URIForFile uri
The text document's URI.
std::vector< Path > getActiveFiles() const
llvm::Optional< WorkspaceEdit > workspaceEdit
This class exposes ClangdServer's capabilities via Language Server Protocol.
llvm::json::Object *const Args
Mutable metadata, if this span is interested.
static llvm::cl::opt< Path > CompileCommandsDir("compile-commands-dir", llvm::cl::desc("Specify a path to look for compile_commands.json. If path " "is invalid, clangd will look in the current directory and " "parent paths of each source file."))
Records an event whose duration is the lifetime of the Span object.
std::string toString() const
Returns a string URI with all components percent-encoded.
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Diagnostics must not be generated for this snapshot.
llvm::Optional< std::string > getDraft(PathRef File) const
bool HierarchicalDocumentSymbol
Client supports hierarchical document symbols.
llvm::StringRef file() const
Retrieves absolute path to the file.