clang-tools 17.0.0git
ClangdLSPServer.h
Go to the documentation of this file.
1//===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
11
12#include "ClangdServer.h"
14#include "LSPBinder.h"
15#include "Protocol.h"
16#include "Transport.h"
17#include "support/Context.h"
18#include "support/MemoryTree.h"
19#include "support/Path.h"
20#include "support/Threading.h"
21#include "llvm/Support/JSON.h"
22#include <chrono>
23#include <cstddef>
24#include <cstdint>
25#include <memory>
26#include <optional>
27#include <vector>
28
29namespace clang {
30namespace clangd {
31
32/// This class exposes ClangdServer's capabilities via Language Server Protocol.
33///
34/// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to
35/// corresponding JSON-RPC methods ("initialize").
36/// The server also supports $/cancelRequest (MessageHandler provides this).
39public:
41 /// Supplies configuration (overrides ClangdServer::ContextProvider).
43 /// Look for compilation databases, rather than using compile commands
44 /// set via LSP (extensions) only.
45 bool UseDirBasedCDB = true;
46 /// The offset-encoding to use, or std::nullopt to negotiate it over LSP.
47 std::optional<OffsetEncoding> Encoding;
48 /// If set, periodically called to release memory.
49 /// Consider malloc_trim(3)
50 std::function<void()> MemoryCleanup = nullptr;
51
52 /// Per-feature options. Generally ClangdServer lets these vary
53 /// per-request, but LSP allows limited/no customizations.
57 /// Returns true if the tweak should be enabled.
58 std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
59 return !T.hidden(); // only enable non-hidden tweaks.
60 };
61
62 /// Limit the number of references returned (0 means no limit).
63 size_t ReferencesLimit = 0;
64 };
65
66 ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
67 const ClangdLSPServer::Options &Opts);
68 /// The destructor blocks on any outstanding background tasks.
70
71 /// Run LSP server loop, communicating with the Transport provided in the
72 /// constructor. This method must not be executed more than once.
73 ///
74 /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
75 bool run();
76
77 /// Profiles resource-usage.
78 void profile(MemoryTree &MT) const;
79
80private:
81 // Implement ClangdServer::Callbacks.
82 void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
83 std::vector<Diag> Diagnostics) override;
84 void onFileUpdated(PathRef File, const TUStatus &Status) override;
85 void onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) override;
86 void onSemanticsMaybeChanged(PathRef File) override;
87 void onInactiveRegionsReady(PathRef File,
88 std::vector<Range> InactiveRegions) override;
89
90 // LSP methods. Notifications have signature void(const Params&).
91 // Calls have signature void(const Params&, Callback<Response>).
92 void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
93 void onInitialized(const InitializedParams &);
94 void onShutdown(const NoParams &, Callback<std::nullptr_t>);
95 void onSync(const NoParams &, Callback<std::nullptr_t>);
96 void onDocumentDidOpen(const DidOpenTextDocumentParams &);
97 void onDocumentDidChange(const DidChangeTextDocumentParams &);
98 void onDocumentDidClose(const DidCloseTextDocumentParams &);
99 void onDocumentDidSave(const DidSaveTextDocumentParams &);
100 void onAST(const ASTParams &, Callback<std::optional<ASTNode>>);
101 void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
102 Callback<std::vector<TextEdit>>);
103 void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
104 Callback<std::vector<TextEdit>>);
105 void onDocumentFormatting(const DocumentFormattingParams &,
106 Callback<std::vector<TextEdit>>);
107 // The results are serialized 'vector<DocumentSymbol>' if
108 // SupportsHierarchicalDocumentSymbol is true and 'vector<SymbolInformation>'
109 // otherwise.
110 void onDocumentSymbol(const DocumentSymbolParams &,
112 void onFoldingRange(const FoldingRangeParams &,
113 Callback<std::vector<FoldingRange>>);
114 void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
115 void onCompletion(const CompletionParams &, Callback<CompletionList>);
116 void onSignatureHelp(const TextDocumentPositionParams &,
118 void onGoToDeclaration(const TextDocumentPositionParams &,
119 Callback<std::vector<Location>>);
120 void onGoToDefinition(const TextDocumentPositionParams &,
121 Callback<std::vector<Location>>);
122 void onGoToType(const TextDocumentPositionParams &,
123 Callback<std::vector<Location>>);
124 void onGoToImplementation(const TextDocumentPositionParams &,
125 Callback<std::vector<Location>>);
126 void onReference(const ReferenceParams &, Callback<std::vector<ReferenceLocation>>);
127 void onSwitchSourceHeader(const TextDocumentIdentifier &,
128 Callback<std::optional<URIForFile>>);
129 void onDocumentHighlight(const TextDocumentPositionParams &,
130 Callback<std::vector<DocumentHighlight>>);
131 void onFileEvent(const DidChangeWatchedFilesParams &);
132 void onWorkspaceSymbol(const WorkspaceSymbolParams &,
133 Callback<std::vector<SymbolInformation>>);
134 void onPrepareRename(const TextDocumentPositionParams &,
135 Callback<std::optional<Range>>);
136 void onRename(const RenameParams &, Callback<WorkspaceEdit>);
137 void onHover(const TextDocumentPositionParams &,
138 Callback<std::optional<Hover>>);
139 void onPrepareTypeHierarchy(const TypeHierarchyPrepareParams &,
140 Callback<std::vector<TypeHierarchyItem>>);
141 void onSuperTypes(const ResolveTypeHierarchyItemParams &,
142 Callback<std::optional<std::vector<TypeHierarchyItem>>>);
143 void onSubTypes(const ResolveTypeHierarchyItemParams &,
144 Callback<std::vector<TypeHierarchyItem>>);
145 void onTypeHierarchy(const TypeHierarchyPrepareParams &,
147 void onResolveTypeHierarchy(const ResolveTypeHierarchyItemParams &,
149 void onPrepareCallHierarchy(const CallHierarchyPrepareParams &,
150 Callback<std::vector<CallHierarchyItem>>);
151 void onCallHierarchyIncomingCalls(
153 Callback<std::vector<CallHierarchyIncomingCall>>);
154 void onClangdInlayHints(const InlayHintsParams &,
156 void onInlayHint(const InlayHintsParams &, Callback<std::vector<InlayHint>>);
157 void onChangeConfiguration(const DidChangeConfigurationParams &);
158 void onSymbolInfo(const TextDocumentPositionParams &,
159 Callback<std::vector<SymbolDetails>>);
160 void onSelectionRange(const SelectionRangeParams &,
161 Callback<std::vector<SelectionRange>>);
162 void onDocumentLink(const DocumentLinkParams &,
163 Callback<std::vector<DocumentLink>>);
164 void onSemanticTokens(const SemanticTokensParams &, Callback<SemanticTokens>);
165 void onSemanticTokensDelta(const SemanticTokensDeltaParams &,
167 /// This is a clangd extension. Provides a json tree representing memory usage
168 /// hierarchy.
169 void onMemoryUsage(const NoParams &, Callback<MemoryTree>);
170 void onCommand(const ExecuteCommandParams &, Callback<llvm::json::Value>);
171
172 /// Implement commands.
173 void onCommandApplyEdit(const WorkspaceEdit &, Callback<llvm::json::Value>);
174 void onCommandApplyTweak(const TweakArgs &, Callback<llvm::json::Value>);
175
176 /// Outgoing LSP calls.
179 ApplyWorkspaceEdit;
185 CreateWorkDoneProgress;
187 BeginWorkDoneProgress;
189 ReportWorkDoneProgress;
191 EndWorkDoneProgress;
193
194 void applyEdit(WorkspaceEdit WE, llvm::json::Value Success,
196
197 void bindMethods(LSPBinder &, const ClientCapabilities &Caps);
198 std::vector<CodeAction> getFixes(StringRef File, const clangd::Diagnostic &D);
199
200
201 /// Checks if completion request should be ignored. We need this due to the
202 /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
203 /// character" we specify, but for '>' and ':' we need to check they actually
204 /// produce '->' and '::', respectively.
205 bool shouldRunCompletion(const CompletionParams &Params) const;
206
207 void applyConfiguration(const ConfigurationSettings &Settings);
208
209 /// Runs profiling and exports memory usage metrics if tracing is enabled and
210 /// profiling hasn't happened recently.
211 void maybeExportMemoryProfile();
212 PeriodicThrottler ShouldProfile;
213
214 /// Run the MemoryCleanup callback if it's time.
215 /// This method is thread safe.
216 void maybeCleanupMemory();
217 PeriodicThrottler ShouldCleanupMemory;
218
219 /// Since initialization of CDBs and ClangdServer is done lazily, the
220 /// following context captures the one used while creating ClangdLSPServer and
221 /// passes it to above mentioned object instances to make sure they share the
222 /// same state.
223 Context BackgroundContext;
224
225 /// Used to indicate that the 'shutdown' request was received from the
226 /// Language Server client.
227 bool ShutdownRequestReceived = false;
228
229 /// Used to indicate the ClangdLSPServer is being destroyed.
230 std::atomic<bool> IsBeingDestroyed = {false};
231
232 std::mutex FixItsMutex;
233 typedef std::map<clangd::Diagnostic, std::vector<CodeAction>,
235 DiagnosticToReplacementMap;
236 /// Caches FixIts per file and diagnostics
237 llvm::StringMap<DiagnosticToReplacementMap>
238 FixItsMap;
239 // Last semantic-tokens response, for incremental requests.
240 std::mutex SemanticTokensMutex;
241 llvm::StringMap<SemanticTokens> LastSemanticTokens;
242
243 // Most code should not deal with Transport, callMethod, notify directly.
244 // Use LSPBinder to handle incoming and outgoing calls.
245 clangd::Transport &Transp;
246 class MessageHandler;
247 std::unique_ptr<MessageHandler> MsgHandler;
248 std::mutex TranspWriter;
249
250 void callMethod(StringRef Method, llvm::json::Value Params,
251 Callback<llvm::json::Value> CB) override;
252 void notify(StringRef Method, llvm::json::Value Params) override;
253
254 LSPBinder::RawHandlers Handlers;
255
256 const ThreadsafeFS &TFS;
257 /// Options used for diagnostics.
259 /// The supported kinds of the client.
260 SymbolKindBitset SupportedSymbolKinds;
261 /// The supported completion item kinds of the client.
262 CompletionItemKindBitset SupportedCompletionItemKinds;
263 /// Whether the client supports CodeAction response objects.
264 bool SupportsCodeAction = false;
265 /// From capabilities of textDocument/documentSymbol.
266 bool SupportsHierarchicalDocumentSymbol = false;
267 /// Whether the client supports showing file status.
268 bool SupportFileStatus = false;
269 /// Whether the client supports attaching a container string to references.
270 bool SupportsReferenceContainer = false;
271 /// Which kind of markup should we use in textDocument/hover responses.
272 MarkupKind HoverContentFormat = MarkupKind::PlainText;
273 /// Whether the client supports offsets for parameter info labels.
274 bool SupportsOffsetsInSignatureHelp = false;
275 /// Whether the client supports the versioned document changes.
276 bool SupportsDocumentChanges = false;
277 /// Whether the client supports change annotations on text edits.
278 bool SupportsChangeAnnotation = false;
279
280 std::mutex BackgroundIndexProgressMutex;
281 enum class BackgroundIndexProgress {
282 // Client doesn't support reporting progress. No transitions possible.
283 Unsupported,
284 // The queue is idle, and the client has no progress bar.
285 // Can transition to Creating when we have some activity.
286 Empty,
287 // We've requested the client to create a progress bar.
288 // Meanwhile, the state is buffered in PendingBackgroundIndexProgress.
289 Creating,
290 // The client has a progress bar, and we can send it updates immediately.
291 Live,
292 } BackgroundIndexProgressState = BackgroundIndexProgress::Unsupported;
293 // The progress to send when the progress bar is created.
294 // Only valid in state Creating.
295 BackgroundQueue::Stats PendingBackgroundIndexProgress;
296 /// LSP extension: skip WorkDoneProgressCreate, just send progress streams.
297 bool BackgroundIndexSkipCreate = false;
298
299 Options Opts;
300 // The CDB is created by the "initialize" LSP method.
301 std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
302 // CDB is BaseCDB plus any commands overridden via LSP extensions.
303 std::optional<OverlayCDB> CDB;
304 // The ClangdServer is created by the "initialize" LSP method.
305 std::optional<ClangdServer> Server;
306};
307} // namespace clangd
308} // namespace clang
309
310#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
WantDiagnostics Diagnostics
This class exposes ClangdServer's capabilities via Language Server Protocol.
~ClangdLSPServer()
The destructor blocks on any outstanding background tasks.
void profile(MemoryTree &MT) const
Profiles resource-usage.
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
Interface with hooks for users of ClangdServer to be notified of events.
Definition: ClangdServer.h:61
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
LSPBinder collects a table of functions that handle LSP calls.
Definition: LSPBinder.h:34
llvm::unique_function< void(const P &)> OutgoingNotification
Definition: LSPBinder.h:90
llvm::unique_function< void(const P &, Callback< R >)> OutgoingMethod
Definition: LSPBinder.h:81
Used to guard an operation that should run at most every N seconds.
Definition: Threading.h:186
Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
Definition: ThreadsafeFS.h:26
An interface base for small context-sensitive refactoring actions.
Definition: Tweak.h:46
A source of configuration fragments.
std::bitset< SymbolKindMax+1 > SymbolKindBitset
Definition: Protocol.h:411
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Definition: Protocol.h:372
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Payload for textDocument/ast request.
Definition: Protocol.h:1905
The parameter of a callHierarchy/incomingCalls request.
Definition: Protocol.h:1578
The parameter of a textDocument/prepareCallHierarchy request.
Definition: Protocol.h:1541
size_t ReferencesLimit
Limit the number of references returned (0 means no limit).
bool UseDirBasedCDB
Look for compilation databases, rather than using compile commands set via LSP (extensions) only.
std::function< void()> MemoryCleanup
If set, periodically called to release memory.
config::Provider * ConfigProvider
Supplies configuration (overrides ClangdServer::ContextProvider).
clangd::CodeCompleteOptions CodeComplete
Per-feature options.
std::function< bool(const Tweak &)> TweakFilter
Returns true if the tweak should be enabled.
std::optional< OffsetEncoding > Encoding
The offset-encoding to use, or std::nullopt to negotiate it over LSP.
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
Definition: Protocol.h:580
Parameters for the document link request.
Definition: Protocol.h:1827
A parameter literal used in inlay hint requests.
Definition: Protocol.h:1615
A LSP-specific comparator used to find diagnostic in a container like std:map.
Definition: Protocol.h:966
A tree that can be used to represent memory usage of nested components while preserving the hierarchy...
Definition: MemoryTree.h:30
Parameters for the typeHierarchy/resolve request.
Definition: Protocol.h:1524
Body of textDocument/semanticTokens/full/delta request.
Definition: Protocol.h:1762
Body of textDocument/semanticTokens/full request.
Definition: Protocol.h:1753
Arguments for the 'applyTweak' command.
Definition: Protocol.h:1037
The type hierarchy params is an extension of the TextDocumentPositionsParams with optional properties...
Definition: Protocol.h:1459
The edit should either provide changes or documentChanges.
Definition: Protocol.h:1016
The parameters of a Workspace Symbol Request.
Definition: Protocol.h:1183