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