clang-tools  16.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/ADT/Optional.h"
22 #include "llvm/Support/JSON.h"
23 #include <chrono>
24 #include <cstddef>
25 #include <memory>
26 #include <vector>
27 
28 namespace clang {
29 namespace clangd {
30 
31 /// This class exposes ClangdServer's capabilities via Language Server Protocol.
32 ///
33 /// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to
34 /// corresponding JSON-RPC methods ("initialize").
35 /// The server also supports $/cancelRequest (MessageHandler provides this).
37  private LSPBinder::RawOutgoing {
38 public:
40  /// Supplies configuration (overrides ClangdServer::ContextProvider).
42  /// Look for compilation databases, rather than using compile commands
43  /// set via LSP (extensions) only.
44  bool UseDirBasedCDB = true;
45  /// The offset-encoding to use, or None to negotiate it over LSP.
46  llvm::Optional<OffsetEncoding> Encoding;
47  /// If set, periodically called to release memory.
48  /// Consider malloc_trim(3)
49  std::function<void()> MemoryCleanup = nullptr;
50 
51  /// Per-feature options. Generally ClangdServer lets these vary
52  /// per-request, but LSP allows limited/no customizations.
56  /// Returns true if the tweak should be enabled.
57  std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
58  return !T.hidden(); // only enable non-hidden tweaks.
59  };
60 
61  /// Limit the number of references returned (0 means no limit).
62  size_t ReferencesLimit = 0;
63  };
64 
65  ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
66  const ClangdLSPServer::Options &Opts);
67  /// The destructor blocks on any outstanding background tasks.
69 
70  /// Run LSP server loop, communicating with the Transport provided in the
71  /// constructor. This method must not be executed more than once.
72  ///
73  /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
74  bool run();
75 
76  /// Profiles resource-usage.
77  void profile(MemoryTree &MT) const;
78 
79 private:
80  // Implement ClangdServer::Callbacks.
81  void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
82  std::vector<Diag> Diagnostics) override;
83  void onFileUpdated(PathRef File, const TUStatus &Status) override;
84  void onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) override;
85  void onSemanticsMaybeChanged(PathRef File) override;
86 
87  // LSP methods. Notifications have signature void(const Params&).
88  // Calls have signature void(const Params&, Callback<Response>).
89  void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
90  void onInitialized(const InitializedParams &);
91  void onShutdown(const NoParams &, Callback<std::nullptr_t>);
92  void onSync(const NoParams &, Callback<std::nullptr_t>);
93  void onDocumentDidOpen(const DidOpenTextDocumentParams &);
94  void onDocumentDidChange(const DidChangeTextDocumentParams &);
95  void onDocumentDidClose(const DidCloseTextDocumentParams &);
96  void onDocumentDidSave(const DidSaveTextDocumentParams &);
97  void onAST(const ASTParams &, Callback<llvm::Optional<ASTNode>>);
98  void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
99  Callback<std::vector<TextEdit>>);
100  void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
101  Callback<std::vector<TextEdit>>);
102  void onDocumentFormatting(const DocumentFormattingParams &,
103  Callback<std::vector<TextEdit>>);
104  // The results are serialized 'vector<DocumentSymbol>' if
105  // SupportsHierarchicalDocumentSymbol is true and 'vector<SymbolInformation>'
106  // otherwise.
107  void onDocumentSymbol(const DocumentSymbolParams &,
109  void onFoldingRange(const FoldingRangeParams &,
110  Callback<std::vector<FoldingRange>>);
111  void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
112  void onCompletion(const CompletionParams &, Callback<CompletionList>);
113  void onSignatureHelp(const TextDocumentPositionParams &,
115  void onGoToDeclaration(const TextDocumentPositionParams &,
116  Callback<std::vector<Location>>);
117  void onGoToDefinition(const TextDocumentPositionParams &,
118  Callback<std::vector<Location>>);
119  void onGoToType(const TextDocumentPositionParams &,
120  Callback<std::vector<Location>>);
121  void onGoToImplementation(const TextDocumentPositionParams &,
122  Callback<std::vector<Location>>);
123  void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
124  void onSwitchSourceHeader(const TextDocumentIdentifier &,
125  Callback<llvm::Optional<URIForFile>>);
126  void onDocumentHighlight(const TextDocumentPositionParams &,
127  Callback<std::vector<DocumentHighlight>>);
128  void onFileEvent(const DidChangeWatchedFilesParams &);
129  void onWorkspaceSymbol(const WorkspaceSymbolParams &,
130  Callback<std::vector<SymbolInformation>>);
131  void onPrepareRename(const TextDocumentPositionParams &,
132  Callback<llvm::Optional<Range>>);
133  void onRename(const RenameParams &, Callback<WorkspaceEdit>);
134  void onHover(const TextDocumentPositionParams &,
135  Callback<llvm::Optional<Hover>>);
136  void onPrepareTypeHierarchy(const TypeHierarchyPrepareParams &,
137  Callback<std::vector<TypeHierarchyItem>>);
138  void onSuperTypes(const ResolveTypeHierarchyItemParams &,
139  Callback<llvm::Optional<std::vector<TypeHierarchyItem>>>);
140  void onSubTypes(const ResolveTypeHierarchyItemParams &,
141  Callback<std::vector<TypeHierarchyItem>>);
142  void onTypeHierarchy(const TypeHierarchyPrepareParams &,
144  void onResolveTypeHierarchy(const ResolveTypeHierarchyItemParams &,
146  void onPrepareCallHierarchy(const CallHierarchyPrepareParams &,
147  Callback<std::vector<CallHierarchyItem>>);
148  void onCallHierarchyIncomingCalls(
150  Callback<std::vector<CallHierarchyIncomingCall>>);
151  void onCallHierarchyOutgoingCalls(
153  Callback<std::vector<CallHierarchyOutgoingCall>>);
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;
184  CreateWorkDoneProgress;
186  BeginWorkDoneProgress;
188  ReportWorkDoneProgress;
190  EndWorkDoneProgress;
192 
193  void applyEdit(WorkspaceEdit WE, llvm::json::Value Success,
195 
196  void bindMethods(LSPBinder &, const ClientCapabilities &Caps);
197  std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
198 
199  /// Checks if completion request should be ignored. We need this due to the
200  /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
201  /// character" we specify, but for '>' and ':' we need to check they actually
202  /// produce '->' and '::', respectively.
203  bool shouldRunCompletion(const CompletionParams &Params) const;
204 
205  void applyConfiguration(const ConfigurationSettings &Settings);
206 
207  /// Runs profiling and exports memory usage metrics if tracing is enabled and
208  /// profiling hasn't happened recently.
209  void maybeExportMemoryProfile();
210  PeriodicThrottler ShouldProfile;
211 
212  /// Run the MemoryCleanup callback if it's time.
213  /// This method is thread safe.
214  void maybeCleanupMemory();
215  PeriodicThrottler ShouldCleanupMemory;
216 
217  /// Since initialization of CDBs and ClangdServer is done lazily, the
218  /// following context captures the one used while creating ClangdLSPServer and
219  /// passes it to above mentioned object instances to make sure they share the
220  /// same state.
221  Context BackgroundContext;
222 
223  /// Used to indicate that the 'shutdown' request was received from the
224  /// Language Server client.
225  bool ShutdownRequestReceived = false;
226 
227  /// Used to indicate the ClangdLSPServer is being destroyed.
228  std::atomic<bool> IsBeingDestroyed = {false};
229 
230  std::mutex FixItsMutex;
231  typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
232  DiagnosticToReplacementMap;
233  /// Caches FixIts per file and diagnostics
234  llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;
235  // Last semantic-tokens response, for incremental requests.
236  std::mutex SemanticTokensMutex;
237  llvm::StringMap<SemanticTokens> LastSemanticTokens;
238 
239  // Most code should not deal with Transport, callMethod, notify directly.
240  // Use LSPBinder to handle incoming and outgoing calls.
241  clangd::Transport &Transp;
242  class MessageHandler;
243  std::unique_ptr<MessageHandler> MsgHandler;
244  std::mutex TranspWriter;
245 
246  void callMethod(StringRef Method, llvm::json::Value Params,
247  Callback<llvm::json::Value> CB) override;
248  void notify(StringRef Method, llvm::json::Value Params) override;
249 
250  LSPBinder::RawHandlers Handlers;
251 
252  const ThreadsafeFS &TFS;
253  /// Options used for diagnostics.
254  ClangdDiagnosticOptions DiagOpts;
255  /// The supported kinds of the client.
256  SymbolKindBitset SupportedSymbolKinds;
257  /// The supported completion item kinds of the client.
258  CompletionItemKindBitset SupportedCompletionItemKinds;
259  /// Whether the client supports CodeAction response objects.
260  bool SupportsCodeAction = false;
261  /// From capabilities of textDocument/documentSymbol.
262  bool SupportsHierarchicalDocumentSymbol = false;
263  /// Whether the client supports showing file status.
264  bool SupportFileStatus = false;
265  /// Which kind of markup should we use in textDocument/hover responses.
266  MarkupKind HoverContentFormat = MarkupKind::PlainText;
267  /// Whether the client supports offsets for parameter info labels.
268  bool SupportsOffsetsInSignatureHelp = false;
269  std::mutex BackgroundIndexProgressMutex;
270  enum class BackgroundIndexProgress {
271  // Client doesn't support reporting progress. No transitions possible.
272  Unsupported,
273  // The queue is idle, and the client has no progress bar.
274  // Can transition to Creating when we have some activity.
275  Empty,
276  // We've requested the client to create a progress bar.
277  // Meanwhile, the state is buffered in PendingBackgroundIndexProgress.
278  Creating,
279  // The client has a progress bar, and we can send it updates immediately.
280  Live,
281  } BackgroundIndexProgressState = BackgroundIndexProgress::Unsupported;
282  // The progress to send when the progress bar is created.
283  // Only valid in state Creating.
284  BackgroundQueue::Stats PendingBackgroundIndexProgress;
285  /// LSP extension: skip WorkDoneProgressCreate, just send progress streams.
286  bool BackgroundIndexSkipCreate = false;
287 
288  Options Opts;
289  // The CDB is created by the "initialize" LSP method.
290  std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
291  // CDB is BaseCDB plus any commands overridden via LSP extensions.
292  llvm::Optional<OverlayCDB> CDB;
293  // The ClangdServer is created by the "initialize" LSP method.
294  llvm::Optional<ClangdServer> Server;
295 };
296 } // namespace clangd
297 } // namespace clang
298 
299 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
clang::clangd::ClangdLSPServer::run
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
Definition: ClangdLSPServer.cpp:1644
clang::clangd::BackgroundQueue::Stats
Definition: Background.h:85
clang::clangd::WorkspaceEdit
Definition: Protocol.h:955
clang::clangd::MarkupKind::PlainText
@ PlainText
clang::clangd::SemanticTokensParams
Body of textDocument/semanticTokens/full request.
Definition: Protocol.h:1685
clang::clangd::ClangdLSPServer::Options::ReferencesLimit
size_t ReferencesLimit
Limit the number of references returned (0 means no limit).
Definition: ClangdLSPServer.h:62
clang::clangd::ClangdLSPServer::profile
void profile(MemoryTree &MT) const
Profiles resource-usage.
Definition: ClangdLSPServer.cpp:1655
clang::clangd::SemanticTokensDeltaParams
Body of textDocument/semanticTokens/full/delta request.
Definition: Protocol.h:1694
Path.h
Diagnostics
WantDiagnostics Diagnostics
Definition: TUScheduler.cpp:661
clang::clangd::ClientCapabilities
Definition: Protocol.h:405
clang::clangd::DidCloseTextDocumentParams
Definition: Protocol.h:695
clang::clangd::LSPBinder::OutgoingMethod
llvm::unique_function< void(const P &, Callback< R >)> OutgoingMethod
Definition: LSPBinder.h:81
clang::clangd::ClangdDiagnosticOptions
Definition: Diagnostics.h:36
clang::clangd::config::Provider
A source of configuration fragments.
Definition: ConfigProvider.h:62
clang::clangd::FoldingRangeParams
Definition: Protocol.h:1784
clang::clangd::InitializeParams
Definition: Protocol.h:549
clang::clangd::LSPBinder::RawOutgoing
Definition: LSPBinder.h:46
clang::clangd::ClangdLSPServer::Options::CodeComplete
clangd::CodeCompleteOptions CodeComplete
Per-feature options.
Definition: ClangdLSPServer.h:53
clang::clangd::PeriodicThrottler
Used to guard an operation that should run at most every N seconds.
Definition: Threading.h:185
clang::clangd::SymbolKindBitset
std::bitset< SymbolKindMax+1 > SymbolKindBitset
Definition: Protocol.h:367
clang::clangd::DocumentFormattingParams
Definition: Protocol.h:809
clang::clangd::CallHierarchyPrepareParams
The parameter of a textDocument/prepareCallHierarchy request.
Definition: Protocol.h:1473
LSPBinder.h
clang::clangd::DocumentSymbolParams
Definition: Protocol.h:816
clang::clangd::CompletionItemKindBitset
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Definition: Protocol.h:328
clang::clangd::SelectionRangeParams
Definition: Protocol.h:1725
clang::clangd::ClangdLSPServer::Options
Definition: ClangdLSPServer.h:39
Protocol.h
clang::clangd::ClangdLSPServer
This class exposes ClangdServer's capabilities via Language Server Protocol.
Definition: ClangdLSPServer.h:36
clang::clangd::Diagnostic
Definition: Protocol.h:855
clang::clangd::ClangdServer::Options
Definition: ClangdServer.h:95
clang::clangd::TUStatus
Definition: TUScheduler.h:141
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
clang::clangd::TweakArgs
Arguments for the 'applyTweak' command.
Definition: Protocol.h:969
clang::clangd::MemoryTree
A tree that can be used to represent memory usage of nested components while preserving the hierarchy...
Definition: MemoryTree.h:30
GlobalCompilationDatabase.h
clang::clangd::DidChangeWatchedFilesParams
Definition: Protocol.h:765
Threading.h
clang::clangd::LSPBinder::RawHandlers
Definition: LSPBinder.h:38
clang::clangd::TextDocumentIdentifier
Definition: Protocol.h:131
clang::clangd::DocumentRangeFormattingParams
Definition: Protocol.h:786
clang::clangd::ClangdLSPServer::Options::Rename
clangd::RenameOptions Rename
Definition: ClangdLSPServer.h:55
clang::clangd::RenameOptions
Definition: Rename.h:22
clang::clangd::NoParams
Definition: Protocol.h:272
clang::clangd::ClangdLSPServer::Options::UseDirBasedCDB
bool UseDirBasedCDB
Look for compilation databases, rather than using compile commands set via LSP (extensions) only.
Definition: ClangdLSPServer.h:44
clang::clangd::ClangdLSPServer::ClangdLSPServer
ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts)
Definition: ClangdLSPServer.cpp:1553
clang::clangd::DidChangeConfigurationParams
Definition: Protocol.h:772
clang::clangd::ClangdLSPServer::Options::ConfigProvider
config::Provider * ConfigProvider
Supplies configuration (overrides ClangdServer::ContextProvider).
Definition: ClangdLSPServer.h:41
clang::clangd::ConfigurationSettings
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
Definition: Protocol.h:522
clang::clangd::DocumentLinkParams
Parameters for the document link request.
Definition: Protocol.h:1749
clang::clangd::LSPBinder::OutgoingNotification
llvm::unique_function< void(const P &)> OutgoingNotification
Definition: LSPBinder.h:90
clang::clangd::CodeCompleteOptions
Definition: CodeComplete.h:42
clang::clangd::ExecuteCommandParams
Definition: Protocol.h:980
clang::clangd::ClangdLSPServer::Options::SignatureHelpDocumentationFormat
MarkupKind SignatureHelpDocumentationFormat
Definition: ClangdLSPServer.h:54
clang::clangd::Transport
Definition: Transport.h:35
clang::clangd::CallHierarchyIncomingCallsParams
The parameter of a callHierarchy/incomingCalls request.
Definition: Protocol.h:1510
Transport.h
clang::clangd::MarkupKind
MarkupKind
Definition: Protocol.h:395
clang::clangd::Empty
@ Empty
Definition: FuzzyMatch.h:42
clang::clangd::DidChangeTextDocumentParams
Definition: Protocol.h:722
clang::clangd::ASTParams
Payload for textDocument/ast request.
Definition: Protocol.h:1827
clang::clangd::ClangdServer::Callbacks
Interface with hooks for users of ClangdServer to be notified of events.
Definition: ClangdServer.h:61
clang::clangd::LSPBinder
LSPBinder collects a table of functions that handle LSP calls.
Definition: LSPBinder.h:34
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
clang::clangd::ThreadsafeFS
Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
Definition: ThreadsafeFS.h:27
clang::clangd::ClangdLSPServer::Options::MemoryCleanup
std::function< void()> MemoryCleanup
If set, periodically called to release memory.
Definition: ClangdLSPServer.h:49
clang::clangd::TypeHierarchyPrepareParams
The type hierarchy params is an extension of the TextDocumentPositionsParams with optional properties...
Definition: Protocol.h:1391
clang::clangd::WorkspaceSymbolParams
The parameters of a Workspace Symbol Request.
Definition: Protocol.h:1115
clang::clangd::CompletionParams
Definition: Protocol.h:1169
clang::clangd::ApplyWorkspaceEditResponse
Definition: Protocol.h:1132
MemoryTree.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
ClangdServer.h
clang::clangd::ClangdLSPServer::Options::TweakFilter
std::function< bool(const Tweak &)> TweakFilter
Returns true if the tweak should be enabled.
Definition: ClangdLSPServer.h:57
clang::clangd::DidSaveTextDocumentParams
Definition: Protocol.h:702
clang::clangd::ClangdLSPServer::Options::Encoding
llvm::Optional< OffsetEncoding > Encoding
The offset-encoding to use, or None to negotiate it over LSP.
Definition: ClangdLSPServer.h:46
clang::clangd::Tweak
An interface base for small context-sensitive refactoring actions.
Definition: Tweak.h:46
clang::clangd::CodeActionParams
Definition: Protocol.h:943
clang::clangd::TextDocumentPositionParams
Definition: Protocol.h:1139
clang::clangd::DocumentOnTypeFormattingParams
Definition: Protocol.h:796
clang::clangd::RenameParams
Definition: Protocol.h:1344
clang::clangd::ApplyWorkspaceEditParams
Definition: Protocol.h:1127
clang::clangd::DidOpenTextDocumentParams
Definition: Protocol.h:688
clang::clangd::Callback
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
clang::clangd::ReferenceParams
Definition: Protocol.h:1636
clang::clangd::LSPDiagnosticCompare
A LSP-specific comparator used to find diagnostic in a container like std:map.
Definition: Protocol.h:908
clang::clangd::ClangdLSPServer::~ClangdLSPServer
~ClangdLSPServer()
The destructor blocks on any outstanding background tasks.
Definition: ClangdLSPServer.cpp:1637
clang::clangd::CallHierarchyOutgoingCallsParams
The parameter of a callHierarchy/outgoingCalls request.
Definition: Protocol.h:1528
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
Value
static constexpr bool Value
Definition: SuspiciousCallArgumentCheck.cpp:72
Context.h
clang::clangd::InlayHintsParams
A parameter literal used in inlay hint requests.
Definition: Protocol.h:1547
clang::clangd::ResolveTypeHierarchyItemParams
Parameters for the typeHierarchy/resolve request.
Definition: Protocol.h:1456