clang-tools  8.0.0
ClangdLSPServer.h
Go to the documentation of this file.
1 //===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
12 
13 #include "ClangdServer.h"
14 #include "DraftStore.h"
15 #include "FindSymbols.h"
17 #include "Path.h"
18 #include "Protocol.h"
19 #include "Transport.h"
20 #include "clang/Tooling/Core/Replacement.h"
21 #include "llvm/ADT/Optional.h"
22 #include <memory>
23 
24 namespace clang {
25 namespace clangd {
26 
27 class SymbolIndex;
28 
29 /// This class exposes ClangdServer's capabilities via Language Server Protocol.
30 ///
31 /// MessageHandler binds the implemented LSP methods (e.g. onInitialize) to
32 /// corresponding JSON-RPC methods ("initialize").
33 /// The server also supports $/cancelRequest (MessageHandler provides this).
35 public:
36  /// If \p CompileCommandsDir has a value, compile_commands.json will be
37  /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look
38  /// for compile_commands.json in all parent directories of each file.
39  /// If UseDirBasedCDB is false, compile commands are not read from disk.
40  // FIXME: Clean up signature around CDBs.
42  llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
43  const ClangdServer::Options &Opts);
45 
46  /// Run LSP server loop, communicating with the Transport provided in the
47  /// constructor. This method must not be executed more than once.
48  ///
49  /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
50  bool run();
51 
52 private:
53  // Implement DiagnosticsConsumer.
54  void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;
55  void onFileUpdated(PathRef File, const TUStatus &Status) override;
56 
57  // LSP methods. Notifications have signature void(const Params&).
58  // Calls have signature void(const Params&, Callback<Response>).
59  void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
60  void onShutdown(const ShutdownParams &, Callback<std::nullptr_t>);
61  void onSync(const NoParams &, Callback<std::nullptr_t>);
62  void onDocumentDidOpen(const DidOpenTextDocumentParams &);
63  void onDocumentDidChange(const DidChangeTextDocumentParams &);
64  void onDocumentDidClose(const DidCloseTextDocumentParams &);
65  void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
66  Callback<std::vector<TextEdit>>);
67  void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
68  Callback<std::vector<TextEdit>>);
69  void onDocumentFormatting(const DocumentFormattingParams &,
70  Callback<std::vector<TextEdit>>);
71  // The results are serialized 'vector<DocumentSymbol>' if
72  // SupportsHierarchicalDocumentSymbol is true and 'vector<SymbolInformation>'
73  // otherwise.
74  void onDocumentSymbol(const DocumentSymbolParams &,
76  void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
77  void onCompletion(const CompletionParams &, Callback<CompletionList>);
78  void onSignatureHelp(const TextDocumentPositionParams &,
80  void onGoToDefinition(const TextDocumentPositionParams &,
81  Callback<std::vector<Location>>);
82  void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
83  void onSwitchSourceHeader(const TextDocumentIdentifier &,
85  void onDocumentHighlight(const TextDocumentPositionParams &,
86  Callback<std::vector<DocumentHighlight>>);
87  void onFileEvent(const DidChangeWatchedFilesParams &);
88  void onCommand(const ExecuteCommandParams &, Callback<llvm::json::Value>);
89  void onWorkspaceSymbol(const WorkspaceSymbolParams &,
90  Callback<std::vector<SymbolInformation>>);
91  void onRename(const RenameParams &, Callback<WorkspaceEdit>);
92  void onHover(const TextDocumentPositionParams &,
93  Callback<llvm::Optional<Hover>>);
94  void onChangeConfiguration(const DidChangeConfigurationParams &);
95  void onSymbolInfo(const TextDocumentPositionParams &,
96  Callback<std::vector<SymbolDetails>>);
97 
98  std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
99 
100  /// Checks if completion request should be ignored. We need this due to the
101  /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
102  /// character" we specify, but for '>' and ':' we need to check they actually
103  /// produce '->' and '::', respectively.
104  bool shouldRunCompletion(const CompletionParams &Params) const;
105 
106  /// Forces a reparse of all currently opened files. As a result, this method
107  /// may be very expensive. This method is normally called when the
108  /// compilation database is changed.
109  void reparseOpenedFiles();
110  void applyConfiguration(const ConfigurationSettings &Settings);
111 
112  /// Used to indicate that the 'shutdown' request was received from the
113  /// Language Server client.
114  bool ShutdownRequestReceived = false;
115 
116  std::mutex FixItsMutex;
117  typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
118  DiagnosticToReplacementMap;
119  /// Caches FixIts per file and diagnostics
120  llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;
121 
122  // Most code should not deal with Transport directly.
123  // MessageHandler deals with incoming messages, use call() etc for outgoing.
124  clangd::Transport &Transp;
125  class MessageHandler;
126  std::unique_ptr<MessageHandler> MsgHandler;
127  std::atomic<int> NextCallID = {0};
128  std::mutex TranspWriter;
129  void call(StringRef Method, llvm::json::Value Params);
130  void notify(StringRef Method, llvm::json::Value Params);
131 
132  RealFileSystemProvider FSProvider;
133  /// Options used for code completion
135  /// Options used for diagnostics.
136  ClangdDiagnosticOptions DiagOpts;
137  /// The supported kinds of the client.
138  SymbolKindBitset SupportedSymbolKinds;
139  /// The supported completion item kinds of the client.
140  CompletionItemKindBitset SupportedCompletionItemKinds;
141  /// Whether the client supports CodeAction response objects.
142  bool SupportsCodeAction = false;
143  /// From capabilities of textDocument/documentSymbol.
144  bool SupportsHierarchicalDocumentSymbol = false;
145  /// Whether the client supports showing file status.
146  bool SupportFileStatus = false;
147  // Store of the current versions of the open documents.
148  DraftStore DraftMgr;
149 
150  // The CDB is created by the "initialize" LSP method.
151  bool UseDirBasedCDB; // FIXME: make this a capability.
152  llvm::Optional<Path> CompileCommandsDir; // FIXME: merge with capability?
153  std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
154  // CDB is BaseCDB plus any comands overridden via LSP extensions.
155  llvm::Optional<OverlayCDB> CDB;
156  // The ClangdServer is created by the "initialize" LSP method.
157  // It is destroyed before run() returns, to ensure worker threads exit.
158  ClangdServer::Options ClangdServerOpts;
159  llvm::Optional<ClangdServer> Server;
160 };
161 } // namespace clangd
162 } // namespace clang
163 
164 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
Exact commands are not specified in the protocol so we define the ones supported by Clangd here...
Definition: Protocol.h:643
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:24
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:29
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Definition: Protocol.h:292
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
Definition: Protocol.h:381
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...
const Decl * D
Definition: XRefs.cpp:79
A LSP-specific comparator used to find diagnostic in a container like std:map.
Definition: Protocol.h:599
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::bitset< SymbolKindMax+1 > SymbolKindBitset
Definition: Protocol.h:330
A thread-safe container for files opened in a workspace, addressed by filenames.
Definition: DraftStore.h:27
The parameters of a Workspace Symbol Request.
Definition: Protocol.h:758
This class exposes ClangdServer&#39;s capabilities via Language Server Protocol.
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."))