blob: 5cfab902494487977fcf5dd1ce7c2daa2183418b [file] [log] [blame]
Ilya Biryukov38d79772017-05-16 09:38:59 +00001//===--- 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//
Kirill Bobyrev8e35f1e2018-08-14 16:03:32 +00008//===----------------------------------------------------------------------===//
Ilya Biryukov38d79772017-05-16 09:38:59 +00009
10#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
12
13#include "ClangdServer.h"
Simon Marchi9569fd52018-03-16 14:30:42 +000014#include "DraftStore.h"
Marc-Andre Laperleb387b6e2018-04-23 20:00:52 +000015#include "FindSymbols.h"
Ilya Biryukov103c9512017-06-13 15:59:43 +000016#include "GlobalCompilationDatabase.h"
Ilya Biryukov38d79772017-05-16 09:38:59 +000017#include "Path.h"
18#include "Protocol.h"
Sam McCall2c30fbc2018-10-18 12:32:04 +000019#include "Transport.h"
Ilya Biryukov38d79772017-05-16 09:38:59 +000020#include "clang/Tooling/Core/Replacement.h"
Krasimir Georgiev0dcb48e2017-07-19 15:43:35 +000021#include "llvm/ADT/Optional.h"
Ilya Biryukov652364b2018-09-26 05:48:29 +000022#include <memory>
Ilya Biryukov38d79772017-05-16 09:38:59 +000023
24namespace clang {
25namespace clangd {
26
Haojian Wuba28e9a2018-01-10 14:44:34 +000027class SymbolIndex;
Ilya Biryukov38d79772017-05-16 09:38:59 +000028
Sam McCall45be5cf2018-09-13 12:58:36 +000029/// This class exposes ClangdServer's capabilities via Language Server Protocol.
30///
Sam McCall2c30fbc2018-10-18 12:32:04 +000031/// 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).
34class ClangdLSPServer : private DiagnosticsConsumer {
Ilya Biryukov38d79772017-05-16 09:38:59 +000035public:
Ilya Biryukov0c1ca6b2017-10-02 15:13:20 +000036 /// 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.
Sam McCallc55d09a2018-11-02 13:09:36 +000039 /// If UseDirBasedCDB is false, compile commands are not read from disk.
40 // FIXME: Clean up signature around CDBs.
Sam McCalldc8f3cf2018-10-17 07:32:05 +000041 ClangdLSPServer(Transport &Transp, const clangd::CodeCompleteOptions &CCOpts,
Sam McCallc55d09a2018-11-02 13:09:36 +000042 llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
43 const ClangdServer::Options &Opts);
Sam McCall2c30fbc2018-10-18 12:32:04 +000044 ~ClangdLSPServer();
Ilya Biryukov38d79772017-05-16 09:38:59 +000045
Sam McCalldc8f3cf2018-10-17 07:32:05 +000046 /// Run LSP server loop, communicating with the Transport provided in the
47 /// constructor. This method must not be executed more than once.
Ilya Biryukov0d9b8a32017-10-25 08:45:41 +000048 ///
Sam McCalldc8f3cf2018-10-17 07:32:05 +000049 /// \return Whether we shut down cleanly with a 'shutdown' -> 'exit' sequence.
50 bool run();
Ilya Biryukov38d79772017-05-16 09:38:59 +000051
52private:
Sam McCall4db732a2017-09-30 10:08:52 +000053 // Implement DiagnosticsConsumer.
Sam McCalla7bb0cc2018-03-12 23:22:35 +000054 void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;
Ilya Biryukov103c9512017-06-13 15:59:43 +000055
Sam McCall2c30fbc2018-10-18 12:32:04 +000056 // LSP methods. Notifications have signature void(const Params&).
57 // Calls have signature void(const Params&, Callback<Response>).
58 void onInitialize(const InitializeParams &, Callback<llvm::json::Value>);
59 void onShutdown(const ShutdownParams &, Callback<std::nullptr_t>);
60 void onDocumentDidOpen(const DidOpenTextDocumentParams &);
61 void onDocumentDidChange(const DidChangeTextDocumentParams &);
62 void onDocumentDidClose(const DidCloseTextDocumentParams &);
63 void onDocumentOnTypeFormatting(const DocumentOnTypeFormattingParams &,
64 Callback<std::vector<TextEdit>>);
65 void onDocumentRangeFormatting(const DocumentRangeFormattingParams &,
66 Callback<std::vector<TextEdit>>);
67 void onDocumentFormatting(const DocumentFormattingParams &,
68 Callback<std::vector<TextEdit>>);
69 void onDocumentSymbol(const DocumentSymbolParams &,
70 Callback<std::vector<SymbolInformation>>);
71 void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
72 void onCompletion(const TextDocumentPositionParams &,
73 Callback<CompletionList>);
74 void onSignatureHelp(const TextDocumentPositionParams &,
75 Callback<SignatureHelp>);
76 void onGoToDefinition(const TextDocumentPositionParams &,
77 Callback<std::vector<Location>>);
78 void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
79 void onSwitchSourceHeader(const TextDocumentIdentifier &,
80 Callback<std::string>);
81 void onDocumentHighlight(const TextDocumentPositionParams &,
82 Callback<std::vector<DocumentHighlight>>);
83 void onFileEvent(const DidChangeWatchedFilesParams &);
84 void onCommand(const ExecuteCommandParams &, Callback<llvm::json::Value>);
85 void onWorkspaceSymbol(const WorkspaceSymbolParams &,
86 Callback<std::vector<SymbolInformation>>);
87 void onRename(const RenameParams &, Callback<WorkspaceEdit>);
88 void onHover(const TextDocumentPositionParams &,
89 Callback<llvm::Optional<Hover>>);
90 void onChangeConfiguration(const DidChangeConfigurationParams &);
Ilya Biryukov38d79772017-05-16 09:38:59 +000091
Ilya Biryukov71028b82018-03-12 15:28:22 +000092 std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
Ilya Biryukovafb55542017-05-16 14:40:30 +000093
Simon Marchi9569fd52018-03-16 14:30:42 +000094 /// Forces a reparse of all currently opened files. As a result, this method
95 /// may be very expensive. This method is normally called when the
96 /// compilation database is changed.
97 void reparseOpenedFiles();
Sam McCallbc904612018-10-25 04:22:52 +000098 void applyConfiguration(const ConfigurationSettings &Settings);
Simon Marchi9569fd52018-03-16 14:30:42 +000099
Ilya Biryukovafb55542017-05-16 14:40:30 +0000100 /// Used to indicate that the 'shutdown' request was received from the
101 /// Language Server client.
Ilya Biryukov0d9b8a32017-10-25 08:45:41 +0000102 bool ShutdownRequestReceived = false;
103
Ilya Biryukov38d79772017-05-16 09:38:59 +0000104 std::mutex FixItsMutex;
Ilya Biryukov71028b82018-03-12 15:28:22 +0000105 typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
Ilya Biryukov38d79772017-05-16 09:38:59 +0000106 DiagnosticToReplacementMap;
107 /// Caches FixIts per file and diagnostics
108 llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;
Ilya Biryukov103c9512017-06-13 15:59:43 +0000109
Sam McCall2c30fbc2018-10-18 12:32:04 +0000110 // Most code should not deal with Transport directly.
111 // MessageHandler deals with incoming messages, use call() etc for outgoing.
Sam McCalldc8f3cf2018-10-17 07:32:05 +0000112 clangd::Transport &Transp;
Sam McCall2c30fbc2018-10-18 12:32:04 +0000113 class MessageHandler;
114 std::unique_ptr<MessageHandler> MsgHandler;
115 std::atomic<int> NextCallID = {0};
116 std::mutex TranspWriter;
117 void call(StringRef Method, llvm::json::Value Params);
118 void notify(StringRef Method, llvm::json::Value Params);
Sam McCall2c30fbc2018-10-18 12:32:04 +0000119
Ilya Biryukov103c9512017-06-13 15:59:43 +0000120 RealFileSystemProvider FSProvider;
Ilya Biryukovd3b04e32017-12-05 10:42:57 +0000121 /// Options used for code completion
122 clangd::CodeCompleteOptions CCOpts;
Alex Lorenz8626d362018-08-10 17:25:07 +0000123 /// Options used for diagnostics.
124 ClangdDiagnosticOptions DiagOpts;
Marc-Andre Laperleb387b6e2018-04-23 20:00:52 +0000125 /// The supported kinds of the client.
126 SymbolKindBitset SupportedSymbolKinds;
Kadir Cetinkaya133d46f2018-09-27 17:13:07 +0000127 /// The supported completion item kinds of the client.
128 CompletionItemKindBitset SupportedCompletionItemKinds;
Sam McCall20841d42018-10-16 16:29:41 +0000129 // Whether the client supports CodeAction response objects.
130 bool SupportsCodeAction = false;
Simon Marchi9569fd52018-03-16 14:30:42 +0000131
132 // Store of the current versions of the open documents.
133 DraftStore DraftMgr;
134
Sam McCalld1c9d112018-10-23 14:19:54 +0000135 // The CDB is created by the "initialize" LSP method.
Sam McCallc55d09a2018-11-02 13:09:36 +0000136 bool UseDirBasedCDB; // FIXME: make this a capability.
Sam McCall4b86bb02018-10-25 02:22:53 +0000137 llvm::Optional<Path> CompileCommandsDir; // FIXME: merge with capability?
Sam McCallc55d09a2018-11-02 13:09:36 +0000138 std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
139 // CDB is BaseCDB plus any comands overridden via LSP extensions.
140 llvm::Optional<OverlayCDB> CDB;
Sam McCall3d0adbe2018-10-18 14:41:50 +0000141 // The ClangdServer is created by the "initialize" LSP method.
142 // It is destroyed before run() returns, to ensure worker threads exit.
143 ClangdServer::Options ClangdServerOpts;
144 llvm::Optional<ClangdServer> Server;
Kadir Cetinkaya689bf932018-08-24 13:09:41 +0000145};
Ilya Biryukov38d79772017-05-16 09:38:59 +0000146} // namespace clangd
147} // namespace clang
148
Kirill Bobyrev8e35f1e2018-08-14 16:03:32 +0000149#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H