blob: 936c673ebab3404c2549a62663587f657bb0d58a [file] [log] [blame]
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +00001//===--- ProtocolHandlers.cpp - LSP callbacks -----------------------------===//
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#include "ProtocolHandlers.h"
Ilya Biryukovafb55542017-05-16 14:40:30 +000011#include "ClangdLSPServer.h"
Ilya Biryukov38d79772017-05-16 09:38:59 +000012#include "ClangdServer.h"
13#include "DraftStore.h"
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000014using namespace clang;
15using namespace clangd;
16
Ilya Biryukovafb55542017-05-16 14:40:30 +000017namespace {
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000018
Ilya Biryukovafb55542017-05-16 14:40:30 +000019struct InitializeHandler : Handler {
20 InitializeHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
21 : Handler(Output), Callbacks(Callbacks) {}
22
23 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle37de9712017-09-27 15:31:17 +000024 auto IP = InitializeParams::parse(Params, Output);
25 if (!IP) {
26 Output.log("Failed to decode InitializeParams!\n");
27 IP = InitializeParams();
28 }
29
30 Callbacks.onInitialize(ID, *IP, Output);
Krasimir Georgiev561ba5e2017-04-10 13:31:39 +000031 }
32
Ilya Biryukovafb55542017-05-16 14:40:30 +000033private:
34 ProtocolCallbacks &Callbacks;
35};
Krasimir Georgiev561ba5e2017-04-10 13:31:39 +000036
Ilya Biryukovafb55542017-05-16 14:40:30 +000037struct ShutdownHandler : Handler {
38 ShutdownHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
39 : Handler(Output), Callbacks(Callbacks) {}
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000040
Ilya Biryukovafb55542017-05-16 14:40:30 +000041 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
42 Callbacks.onShutdown(Output);
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000043 }
44
Ilya Biryukovafb55542017-05-16 14:40:30 +000045private:
46 ProtocolCallbacks &Callbacks;
47};
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000048
Ilya Biryukovafb55542017-05-16 14:40:30 +000049struct TextDocumentDidOpenHandler : Handler {
50 TextDocumentDidOpenHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
51 : Handler(Output), Callbacks(Callbacks) {}
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000052
Ilya Biryukovafb55542017-05-16 14:40:30 +000053 void handleNotification(llvm::yaml::MappingNode *Params) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +000054 auto DOTDP = DidOpenTextDocumentParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +000055 if (!DOTDP) {
56 Output.log("Failed to decode DidOpenTextDocumentParams!\n");
57 return;
58 }
59 Callbacks.onDocumentDidOpen(*DOTDP, Output);
Krasimir Georgiev1b8bfd42017-02-16 10:49:46 +000060 }
61
Ilya Biryukovafb55542017-05-16 14:40:30 +000062private:
63 ProtocolCallbacks &Callbacks;
64};
Krasimir Georgiev1b8bfd42017-02-16 10:49:46 +000065
Ilya Biryukovafb55542017-05-16 14:40:30 +000066struct TextDocumentDidChangeHandler : Handler {
67 TextDocumentDidChangeHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
68 : Handler(Output), Callbacks(Callbacks) {}
Krasimir Georgiev1b8bfd42017-02-16 10:49:46 +000069
Ilya Biryukovafb55542017-05-16 14:40:30 +000070 void handleNotification(llvm::yaml::MappingNode *Params) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +000071 auto DCTDP = DidChangeTextDocumentParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +000072 if (!DCTDP || DCTDP->contentChanges.size() != 1) {
73 Output.log("Failed to decode DidChangeTextDocumentParams!\n");
74 return;
75 }
76
77 Callbacks.onDocumentDidChange(*DCTDP, Output);
Benjamin Kramerbb1cdb62017-02-07 10:28:20 +000078 }
79
Ilya Biryukovafb55542017-05-16 14:40:30 +000080private:
81 ProtocolCallbacks &Callbacks;
82};
Benjamin Kramerf0af3e62017-03-01 16:16:29 +000083
Ilya Biryukovafb55542017-05-16 14:40:30 +000084struct TextDocumentDidCloseHandler : Handler {
85 TextDocumentDidCloseHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
86 : Handler(Output), Callbacks(Callbacks) {}
87
88 void handleNotification(llvm::yaml::MappingNode *Params) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +000089 auto DCTDP = DidCloseTextDocumentParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +000090 if (!DCTDP) {
91 Output.log("Failed to decode DidCloseTextDocumentParams!\n");
92 return;
93 }
94
95 Callbacks.onDocumentDidClose(*DCTDP, Output);
Benjamin Kramerf0af3e62017-03-01 16:16:29 +000096 }
97
Ilya Biryukovafb55542017-05-16 14:40:30 +000098private:
99 ProtocolCallbacks &Callbacks;
100};
Benjamin Kramerf0af3e62017-03-01 16:16:29 +0000101
Ilya Biryukovafb55542017-05-16 14:40:30 +0000102struct TextDocumentOnTypeFormattingHandler : Handler {
103 TextDocumentOnTypeFormattingHandler(JSONOutput &Output,
104 ProtocolCallbacks &Callbacks)
105 : Handler(Output), Callbacks(Callbacks) {}
Benjamin Kramerf0af3e62017-03-01 16:16:29 +0000106
Ilya Biryukovafb55542017-05-16 14:40:30 +0000107 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000108 auto DOTFP = DocumentOnTypeFormattingParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +0000109 if (!DOTFP) {
110 Output.log("Failed to decode DocumentOnTypeFormattingParams!\n");
111 return;
112 }
Krasimir Georgiev6d2131a2017-04-04 09:46:39 +0000113
Ilya Biryukovafb55542017-05-16 14:40:30 +0000114 Callbacks.onDocumentOnTypeFormatting(*DOTFP, ID, Output);
Krasimir Georgiev6d2131a2017-04-04 09:46:39 +0000115 }
116
Ilya Biryukovafb55542017-05-16 14:40:30 +0000117private:
118 ProtocolCallbacks &Callbacks;
119};
120
121struct TextDocumentRangeFormattingHandler : Handler {
122 TextDocumentRangeFormattingHandler(JSONOutput &Output,
123 ProtocolCallbacks &Callbacks)
124 : Handler(Output), Callbacks(Callbacks) {}
125
126 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000127 auto DRFP = DocumentRangeFormattingParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +0000128 if (!DRFP) {
129 Output.log("Failed to decode DocumentRangeFormattingParams!\n");
130 return;
131 }
132
133 Callbacks.onDocumentRangeFormatting(*DRFP, ID, Output);
Krasimir Georgiev6d2131a2017-04-04 09:46:39 +0000134 }
Ilya Biryukovafb55542017-05-16 14:40:30 +0000135
136private:
137 ProtocolCallbacks &Callbacks;
138};
139
140struct TextDocumentFormattingHandler : Handler {
141 TextDocumentFormattingHandler(JSONOutput &Output,
142 ProtocolCallbacks &Callbacks)
143 : Handler(Output), Callbacks(Callbacks) {}
144
145 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000146 auto DFP = DocumentFormattingParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +0000147 if (!DFP) {
148 Output.log("Failed to decode DocumentFormattingParams!\n");
149 return;
150 }
151
152 Callbacks.onDocumentFormatting(*DFP, ID, Output);
153 }
154
155private:
156 ProtocolCallbacks &Callbacks;
157};
158
159struct CodeActionHandler : Handler {
160 CodeActionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
161 : Handler(Output), Callbacks(Callbacks) {}
162
163 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000164 auto CAP = CodeActionParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +0000165 if (!CAP) {
166 Output.log("Failed to decode CodeActionParams!\n");
167 return;
168 }
169
170 Callbacks.onCodeAction(*CAP, ID, Output);
171 }
172
173private:
174 ProtocolCallbacks &Callbacks;
175};
176
177struct CompletionHandler : Handler {
178 CompletionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
179 : Handler(Output), Callbacks(Callbacks) {}
180
181 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000182 auto TDPP = TextDocumentPositionParams::parse(Params, Output);
Ilya Biryukovafb55542017-05-16 14:40:30 +0000183 if (!TDPP) {
184 Output.log("Failed to decode TextDocumentPositionParams!\n");
185 return;
186 }
187
188 Callbacks.onCompletion(*TDPP, ID, Output);
189 }
190
191private:
192 ProtocolCallbacks &Callbacks;
193};
194
Marc-Andre Laperle2cbf0372017-06-28 16:12:10 +0000195struct GotoDefinitionHandler : Handler {
196 GotoDefinitionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
197 : Handler(Output), Callbacks(Callbacks) {}
198
199 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
Marc-Andre Laperle85dcce42017-09-18 15:02:59 +0000200 auto TDPP = TextDocumentPositionParams::parse(Params, Output);
Marc-Andre Laperle2cbf0372017-06-28 16:12:10 +0000201 if (!TDPP) {
202 Output.log("Failed to decode TextDocumentPositionParams!\n");
203 return;
204 }
205
206 Callbacks.onGoToDefinition(*TDPP, ID, Output);
207 }
208
209private:
210 ProtocolCallbacks &Callbacks;
211};
212
Marc-Andre Laperle6571b3e2017-09-28 03:14:40 +0000213struct SwitchSourceHeaderHandler : Handler {
214 SwitchSourceHeaderHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks)
215 : Handler(Output), Callbacks(Callbacks) {}
216
217 void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
218 auto TDPP = TextDocumentIdentifier::parse(Params, Output);
219 if (!TDPP)
220 return;
221
222 Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
223 }
224
225private:
226 ProtocolCallbacks &Callbacks;
227};
228
Marc-Andre Laperlebf114242017-10-02 18:00:37 +0000229struct WorkspaceDidChangeWatchedFilesHandler : Handler {
230 WorkspaceDidChangeWatchedFilesHandler(JSONOutput &Output,
231 ProtocolCallbacks &Callbacks)
232 : Handler(Output), Callbacks(Callbacks) {}
233
234 void handleNotification(llvm::yaml::MappingNode *Params) {
235 auto DCWFP = DidChangeWatchedFilesParams::parse(Params, Output);
236 if (!DCWFP) {
237 Output.log("Failed to decode DidChangeWatchedFilesParams.\n");
238 return;
239 }
240
241 Callbacks.onFileEvent(*DCWFP);
242 }
243
244private:
245 ProtocolCallbacks &Callbacks;
246};
247
Ilya Biryukovafb55542017-05-16 14:40:30 +0000248} // namespace
249
Sam McCallef41c342017-09-29 16:41:23 +0000250void clangd::registerCallbackHandlers(JSONRPCDispatcher &Dispatcher,
Ilya Biryukovafb55542017-05-16 14:40:30 +0000251 JSONOutput &Out,
252 ProtocolCallbacks &Callbacks) {
253 Dispatcher.registerHandler(
254 "initialize", llvm::make_unique<InitializeHandler>(Out, Callbacks));
255 Dispatcher.registerHandler(
256 "shutdown", llvm::make_unique<ShutdownHandler>(Out, Callbacks));
257 Dispatcher.registerHandler(
258 "textDocument/didOpen",
259 llvm::make_unique<TextDocumentDidOpenHandler>(Out, Callbacks));
260 Dispatcher.registerHandler(
261 "textDocument/didClose",
262 llvm::make_unique<TextDocumentDidCloseHandler>(Out, Callbacks));
263 Dispatcher.registerHandler(
264 "textDocument/didChange",
265 llvm::make_unique<TextDocumentDidChangeHandler>(Out, Callbacks));
266 Dispatcher.registerHandler(
267 "textDocument/rangeFormatting",
268 llvm::make_unique<TextDocumentRangeFormattingHandler>(Out, Callbacks));
269 Dispatcher.registerHandler(
270 "textDocument/onTypeFormatting",
271 llvm::make_unique<TextDocumentOnTypeFormattingHandler>(Out, Callbacks));
272 Dispatcher.registerHandler(
273 "textDocument/formatting",
274 llvm::make_unique<TextDocumentFormattingHandler>(Out, Callbacks));
275 Dispatcher.registerHandler(
276 "textDocument/codeAction",
277 llvm::make_unique<CodeActionHandler>(Out, Callbacks));
278 Dispatcher.registerHandler(
279 "textDocument/completion",
280 llvm::make_unique<CompletionHandler>(Out, Callbacks));
Ilya Biryukov574b7532017-08-02 09:08:39 +0000281 Dispatcher.registerHandler(
282 "textDocument/definition",
Marc-Andre Laperle2cbf0372017-06-28 16:12:10 +0000283 llvm::make_unique<GotoDefinitionHandler>(Out, Callbacks));
Marc-Andre Laperle6571b3e2017-09-28 03:14:40 +0000284 Dispatcher.registerHandler(
285 "textDocument/switchSourceHeader",
Marc-Andre Laperlebf114242017-10-02 18:00:37 +0000286 llvm::make_unique<SwitchSourceHeaderHandler>(Out, Callbacks));
287 Dispatcher.registerHandler(
288 "workspace/didChangeWatchedFiles",
289 llvm::make_unique<WorkspaceDidChangeWatchedFilesHandler>(Out, Callbacks));
Krasimir Georgiev6d2131a2017-04-04 09:46:39 +0000290}