clang-tools  15.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 
27 namespace clang {
28 namespace clangd {
29 
30 /// This class exposes ClangdServer's capabilities via Language Server Protocol.
31 ///
32 /// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to
33 /// corresponding JSON-RPC methods ("initialize").
34 /// The server also supports $/cancelRequest (MessageHandler provides this).
36  private LSPBinder::RawOutgoing {
37 public:
39  /// Supplies configuration (overrides ClangdServer::ContextProvider).
41  /// Look for compilation databases, rather than using compile commands
42  /// set via LSP (extensions) only.
43  bool UseDirBasedCDB = true;
44  /// The offset-encoding to use, or None to negotiate it over LSP.
45  llvm::Optional<OffsetEncoding> Encoding;
46  /// If set, periodically called to release memory.
47  /// Consider malloc_trim(3)
48  std::function<void()> MemoryCleanup = nullptr;
49 
50  /// Per-feature options. Generally ClangdServer lets these vary
51  /// per-request, but LSP allows limited/no customizations.
55  /// Returns true if the tweak should be enabled.
56  std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
57  return !T.hidden(); // only enable non-hidden tweaks.
58  };
59 
60  /// Limit the number of references returned (0 means no limit).
61  size_t ReferencesLimit = 0;
62  };
63 
64  ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
65  const ClangdLSPServer::Options &Opts);
66  /// The destructor blocks on any outstanding background tasks.
68 
69  /// Run LSP server loop, communicating with the Transport provided in the
70  /// constructor. This method must not be executed more than once.
71  ///
72  /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
73  bool run();
74 
75  /// Profiles resource-usage.
76  void profile(MemoryTree &MT) const;
77 
78 private:
79  // Implement ClangdServer::Callbacks.
80  void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
81  std::vector<Diag> Diagnostics) override;
82  void onFileUpdated(PathRef File, const TUStatus &Status) override;
83  void onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) override;
84  void onSemanticsMaybeChanged(PathRef File) override;
85 
86  // LSP methods. Notifications have signature void(const Params&).
87  // Calls have signature void(const Params&, Callback<Response>).
88  void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
89  void onInitialized(const InitializedParams &);
90  void onShutdown(const NoParams &, Callback<std::nullptr_t>);
91  void onSync(const NoParams &, Callback<std::nullptr_t>);
92  void onDocumentDidOpen(const DidOpenTextDocumentParams &);
93  void onDocumentDidChange(const DidChangeTextDocumentParams &);
94  void onDocumentDidClose(const DidCloseTextDocumentParams &);
95  void onDocumentDidSave(const DidSaveTextDocumentParams &);
96  void onAST(const ASTParams &, Callback<llvm::Optional<ASTNode>>);
97  void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
98  Callback<std::vector<TextEdit>>);
99  void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
100  Callback<std::vector<TextEdit>>);
101  void onDocumentFormatting(const DocumentFormattingParams &,
102  Callback<std::vector<TextEdit>>);
103  // The results are serialized 'vector<DocumentSymbol>' if
104  // SupportsHierarchicalDocumentSymbol is true and 'vector<SymbolInformation>'
105  // otherwise.
106  void onDocumentSymbol(const DocumentSymbolParams &,
108  void onFoldingRange(const FoldingRangeParams &,
109  Callback<std::vector<FoldingRange>>);
110  void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
111  void onCompletion(const CompletionParams &, Callback<CompletionList>);
112  void onSignatureHelp(const TextDocumentPositionParams &,
114  void onGoToDeclaration(const TextDocumentPositionParams &,
115  Callback<std::vector<Location>>);
116  void onGoToDefinition(const TextDocumentPositionParams &,
117  Callback<std::vector<Location>>);
118  void onGoToType(const TextDocumentPositionParams &,
119  Callback<std::vector<Location>>);
120  void onGoToImplementation(const TextDocumentPositionParams &,
121  Callback<std::vector<Location>>);
122  void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
123  void onSwitchSourceHeader(const TextDocumentIdentifier &,
124  Callback<llvm::Optional<URIForFile>>);
125  void onDocumentHighlight(const TextDocumentPositionParams &,
126  Callback<std::vector<DocumentHighlight>>);
127  void onFileEvent(const DidChangeWatchedFilesParams &);
128  void onWorkspaceSymbol(const WorkspaceSymbolParams &,
129  Callback<std::vector<SymbolInformation>>);
130  void onPrepareRename(const TextDocumentPositionParams &,
131  Callback<llvm::Optional<Range>>);
132  void onRename(const RenameParams &, Callback<WorkspaceEdit>);
133  void onHover(const TextDocumentPositionParams &,
134  Callback<llvm::Optional<Hover>>);
135  void onTypeHierarchy(const TypeHierarchyParams &,
136  Callback<llvm::Optional<TypeHierarchyItem>>);
137  void onResolveTypeHierarchy(const ResolveTypeHierarchyItemParams &,
138  Callback<llvm::Optional<TypeHierarchyItem>>);
139  void onPrepareCallHierarchy(const CallHierarchyPrepareParams &,
140  Callback<std::vector<CallHierarchyItem>>);
141  void onCallHierarchyIncomingCalls(
143  Callback<std::vector<CallHierarchyIncomingCall>>);
144  void onCallHierarchyOutgoingCalls(
146  Callback<std::vector<CallHierarchyOutgoingCall>>);
147  void onClangdInlayHints(const InlayHintsParams &,
149  void onInlayHint(const InlayHintsParams &, Callback<std::vector<InlayHint>>);
150  void onChangeConfiguration(const DidChangeConfigurationParams &);
151  void onSymbolInfo(const TextDocumentPositionParams &,
152  Callback<std::vector<SymbolDetails>>);
153  void onSelectionRange(const SelectionRangeParams &,
154  Callback<std::vector<SelectionRange>>);
155  void onDocumentLink(const DocumentLinkParams &,
156  Callback<std::vector<DocumentLink>>);
157  void onSemanticTokens(const SemanticTokensParams &, Callback<SemanticTokens>);
158  void onSemanticTokensDelta(const SemanticTokensDeltaParams &,
160  /// This is a clangd extension. Provides a json tree representing memory usage
161  /// hierarchy.
162  void onMemoryUsage(const NoParams &, Callback<MemoryTree>);
163  void onCommand(const ExecuteCommandParams &, Callback<llvm::json::Value>);
164 
165  /// Implement commands.
166  void onCommandApplyEdit(const WorkspaceEdit &, Callback<llvm::json::Value>);
167  void onCommandApplyTweak(const TweakArgs &, Callback<llvm::json::Value>);
168 
169  /// Outgoing LSP calls.
172  ApplyWorkspaceEdit;
177  CreateWorkDoneProgress;
179  BeginWorkDoneProgress;
181  ReportWorkDoneProgress;
183  EndWorkDoneProgress;
185 
186  void applyEdit(WorkspaceEdit WE, llvm::json::Value Success,
188 
189  void bindMethods(LSPBinder &, const ClientCapabilities &Caps);
190  std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
191 
192  /// Checks if completion request should be ignored. We need this due to the
193  /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
194  /// character" we specify, but for '>' and ':' we need to check they actually
195  /// produce '->' and '::', respectively.
196  bool shouldRunCompletion(const CompletionParams &Params) const;
197 
198  void applyConfiguration(const ConfigurationSettings &Settings);
199 
200  /// Runs profiling and exports memory usage metrics if tracing is enabled and
201  /// profiling hasn't happened recently.
202  void maybeExportMemoryProfile();
203  PeriodicThrottler ShouldProfile;
204 
205  /// Run the MemoryCleanup callback if it's time.
206  /// This method is thread safe.
207  void maybeCleanupMemory();
208  PeriodicThrottler ShouldCleanupMemory;
209 
210  /// Since initialization of CDBs and ClangdServer is done lazily, the
211  /// following context captures the one used while creating ClangdLSPServer and
212  /// passes it to above mentioned object instances to make sure they share the
213  /// same state.
214  Context BackgroundContext;
215 
216  /// Used to indicate that the 'shutdown' request was received from the
217  /// Language Server client.
218  bool ShutdownRequestReceived = false;
219 
220  /// Used to indicate the ClangdLSPServer is being destroyed.
221  std::atomic<bool> IsBeingDestroyed = {false};
222 
223  std::mutex FixItsMutex;
224  typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
225  DiagnosticToReplacementMap;
226  /// Caches FixIts per file and diagnostics
227  llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;
228  // Last semantic-tokens response, for incremental requests.
229  std::mutex SemanticTokensMutex;
230  llvm::StringMap<SemanticTokens> LastSemanticTokens;
231 
232  // Most code should not deal with Transport, callMethod, notify directly.
233  // Use LSPBinder to handle incoming and outgoing calls.
234  clangd::Transport &Transp;
235  class MessageHandler;
236  std::unique_ptr<MessageHandler> MsgHandler;
237  std::mutex TranspWriter;
238 
239  void callMethod(StringRef Method, llvm::json::Value Params,
240  Callback<llvm::json::Value> CB) override;
241  void notify(StringRef Method, llvm::json::Value Params) override;
242 
243  LSPBinder::RawHandlers Handlers;
244 
245  const ThreadsafeFS &TFS;
246  /// Options used for diagnostics.
247  ClangdDiagnosticOptions DiagOpts;
248  /// The supported kinds of the client.
249  SymbolKindBitset SupportedSymbolKinds;
250  /// The supported completion item kinds of the client.
251  CompletionItemKindBitset SupportedCompletionItemKinds;
252  /// Whether the client supports CodeAction response objects.
253  bool SupportsCodeAction = false;
254  /// From capabilities of textDocument/documentSymbol.
255  bool SupportsHierarchicalDocumentSymbol = false;
256  /// Whether the client supports showing file status.
257  bool SupportFileStatus = false;
258  /// Which kind of markup should we use in textDocument/hover responses.
259  MarkupKind HoverContentFormat = MarkupKind::PlainText;
260  /// Whether the client supports offsets for parameter info labels.
261  bool SupportsOffsetsInSignatureHelp = false;
262  std::mutex BackgroundIndexProgressMutex;
263  enum class BackgroundIndexProgress {
264  // Client doesn't support reporting progress. No transitions possible.
265  Unsupported,
266  // The queue is idle, and the client has no progress bar.
267  // Can transition to Creating when we have some activity.
268  Empty,
269  // We've requested the client to create a progress bar.
270  // Meanwhile, the state is buffered in PendingBackgroundIndexProgress.
271  Creating,
272  // The client has a progress bar, and we can send it updates immediately.
273  Live,
274  } BackgroundIndexProgressState = BackgroundIndexProgress::Unsupported;
275  // The progress to send when the progress bar is created.
276  // Only valid in state Creating.
277  BackgroundQueue::Stats PendingBackgroundIndexProgress;
278  /// LSP extension: skip WorkDoneProgressCreate, just send progress streams.
279  bool BackgroundIndexSkipCreate = false;
280 
281  Options Opts;
282  // The CDB is created by the "initialize" LSP method.
283  std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
284  // CDB is BaseCDB plus any commands overridden via LSP extensions.
285  llvm::Optional<OverlayCDB> CDB;
286  // The ClangdServer is created by the "initialize" LSP method.
287  llvm::Optional<ClangdServer> Server;
288 };
289 } // namespace clangd
290 } // namespace clang
291 
292 #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:1557
clang::clangd::BackgroundQueue::Stats
Definition: Background.h:85
clang::clangd::WorkspaceEdit
Definition: Protocol.h:946
clang::clangd::MarkupKind::PlainText
@ PlainText
clang::clangd::SemanticTokensParams
Body of textDocument/semanticTokens/full request.
Definition: Protocol.h:1664
clang::clangd::ClangdLSPServer::Options::ReferencesLimit
size_t ReferencesLimit
Limit the number of references returned (0 means no limit).
Definition: ClangdLSPServer.h:61
clang::clangd::ClangdLSPServer::profile
void profile(MemoryTree &MT) const
Profiles resource-usage.
Definition: ClangdLSPServer.cpp:1568
clang::clangd::SemanticTokensDeltaParams
Body of textDocument/semanticTokens/full/delta request.
Definition: Protocol.h:1673
Path.h
Diagnostics
WantDiagnostics Diagnostics
Definition: TUScheduler.cpp:602
clang::clangd::ClientCapabilities
Definition: Protocol.h:402
clang::clangd::DidCloseTextDocumentParams
Definition: Protocol.h:686
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:1763
clang::clangd::InitializeParams
Definition: Protocol.h:540
clang::clangd::LSPBinder::RawOutgoing
Definition: LSPBinder.h:46
clang::clangd::ClangdLSPServer::Options::CodeComplete
clangd::CodeCompleteOptions CodeComplete
Per-feature options.
Definition: ClangdLSPServer.h:52
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:364
clang::clangd::DocumentFormattingParams
Definition: Protocol.h:800
clang::clangd::CallHierarchyPrepareParams
The parameter of a textDocument/prepareCallHierarchy request.
Definition: Protocol.h:1452
LSPBinder.h
clang::clangd::DocumentSymbolParams
Definition: Protocol.h:807
clang::clangd::CompletionItemKindBitset
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Definition: Protocol.h:325
clang::clangd::SelectionRangeParams
Definition: Protocol.h:1704
clang::clangd::ClangdLSPServer::Options
Definition: ClangdLSPServer.h:38
Protocol.h
clang::clangd::ClangdLSPServer
This class exposes ClangdServer's capabilities via Language Server Protocol.
Definition: ClangdLSPServer.h:35
clang::clangd::Diagnostic
Definition: Protocol.h:846
clang::clangd::ClangdServer::Options
Definition: ClangdServer.h:95
clang::clangd::TUStatus
Definition: TUScheduler.h:112
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
clang::clangd::TweakArgs
Arguments for the 'applyTweak' command.
Definition: Protocol.h:960
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:756
Threading.h
clang::clangd::LSPBinder::RawHandlers
Definition: LSPBinder.h:38
clang::clangd::TextDocumentIdentifier
Definition: Protocol.h:128
clang::clangd::DocumentRangeFormattingParams
Definition: Protocol.h:777
clang::clangd::ClangdLSPServer::Options::Rename
clangd::RenameOptions Rename
Definition: ClangdLSPServer.h:54
clang::clangd::RenameOptions
Definition: Rename.h:22
clang::clangd::NoParams
Definition: Protocol.h:269
clang::clangd::ClangdLSPServer::Options::UseDirBasedCDB
bool UseDirBasedCDB
Look for compilation databases, rather than using compile commands set via LSP (extensions) only.
Definition: ClangdLSPServer.h:43
clang::clangd::ClangdLSPServer::ClangdLSPServer
ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts)
Definition: ClangdLSPServer.cpp:1468
clang::clangd::DidChangeConfigurationParams
Definition: Protocol.h:763
clang::clangd::ClangdLSPServer::Options::ConfigProvider
config::Provider * ConfigProvider
Supplies configuration (overrides ClangdServer::ContextProvider).
Definition: ClangdLSPServer.h:40
clang::clangd::ConfigurationSettings
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
Definition: Protocol.h:513
clang::clangd::DocumentLinkParams
Parameters for the document link request.
Definition: Protocol.h:1728
clang::clangd::LSPBinder::OutgoingNotification
llvm::unique_function< void(const P &)> OutgoingNotification
Definition: LSPBinder.h:90
clang::clangd::CodeCompleteOptions
Definition: CodeComplete.h:41
clang::clangd::ExecuteCommandParams
Definition: Protocol.h:971
clang::clangd::ClangdLSPServer::Options::SignatureHelpDocumentationFormat
MarkupKind SignatureHelpDocumentationFormat
Definition: ClangdLSPServer.h:53
clang::clangd::Transport
Definition: Transport.h:35
clang::clangd::CallHierarchyIncomingCallsParams
The parameter of a callHierarchy/incomingCalls request.
Definition: Protocol.h:1489
Transport.h
clang::clangd::MarkupKind
MarkupKind
Definition: Protocol.h:392
clang::clangd::TypeHierarchyParams
The type hierarchy params is an extension of the TextDocumentPositionsParams with optional properties...
Definition: Protocol.h:1378
clang::clangd::Empty
@ Empty
Definition: FuzzyMatch.h:42
clang::clangd::DidChangeTextDocumentParams
Definition: Protocol.h:713
clang::clangd::ASTParams
Payload for textDocument/ast request.
Definition: Protocol.h:1802
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:48
clang::clangd::WorkspaceSymbolParams
The parameters of a Workspace Symbol Request.
Definition: Protocol.h:1102
clang::clangd::CompletionParams
Definition: Protocol.h:1156
clang::clangd::ApplyWorkspaceEditResponse
Definition: Protocol.h:1119
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:56
clang::clangd::DidSaveTextDocumentParams
Definition: Protocol.h:693
clang::clangd::ClangdLSPServer::Options::Encoding
llvm::Optional< OffsetEncoding > Encoding
The offset-encoding to use, or None to negotiate it over LSP.
Definition: ClangdLSPServer.h:45
clang::clangd::Tweak
An interface base for small context-sensitive refactoring actions.
Definition: Tweak.h:46
clang::clangd::CodeActionParams
Definition: Protocol.h:934
clang::clangd::TextDocumentPositionParams
Definition: Protocol.h:1126
clang::clangd::DocumentOnTypeFormattingParams
Definition: Protocol.h:787
clang::clangd::RenameParams
Definition: Protocol.h:1331
clang::clangd::ApplyWorkspaceEditParams
Definition: Protocol.h:1114
clang::clangd::DidOpenTextDocumentParams
Definition: Protocol.h:679
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:1615
clang::clangd::LSPDiagnosticCompare
A LSP-specific comparator used to find diagnostic in a container like std:map.
Definition: Protocol.h:899
clang::clangd::ClangdLSPServer::~ClangdLSPServer
~ClangdLSPServer()
The destructor blocks on any outstanding background tasks.
Definition: ClangdLSPServer.cpp:1550
clang::clangd::CallHierarchyOutgoingCallsParams
The parameter of a callHierarchy/outgoingCalls request.
Definition: Protocol.h:1507
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:1526
clang::clangd::ResolveTypeHierarchyItemParams
Parameters for the typeHierarchy/resolve request.
Definition: Protocol.h:1435