|  | //===--- ProtocolHandlers.cpp - LSP callbacks -----------------------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "ProtocolHandlers.h" | 
|  | #include "ClangdLSPServer.h" | 
|  | #include "ClangdServer.h" | 
|  | #include "DraftStore.h" | 
|  |  | 
|  | using namespace clang; | 
|  | using namespace clang::clangd; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Helper for attaching ProtocolCallbacks methods to a JSONRPCDispatcher. | 
|  | // Invoke like: Registerer("foo", &ProtocolCallbacks::onFoo) | 
|  | // onFoo should be: void onFoo(Ctx &C, FooParams &Params) | 
|  | // FooParams should have a static factory method: parse(yaml::MappingNode*). | 
|  | struct HandlerRegisterer { | 
|  | template <typename Param> | 
|  | void operator()(StringRef Method, | 
|  | void (ProtocolCallbacks::*Handler)(RequestContext, Param)) { | 
|  | // Capture pointers by value, as the lambda will outlive this object. | 
|  | auto *Out = this->Out; | 
|  | auto *Callbacks = this->Callbacks; | 
|  | Dispatcher.registerHandler( | 
|  | Method, [=](RequestContext C, llvm::yaml::MappingNode *RawParams) { | 
|  | if (auto P = std::decay<Param>::type::parse(RawParams, *Out)) { | 
|  | (Callbacks->*Handler)(std::move(C), *P); | 
|  | } else { | 
|  | Out->log("Failed to decode " + Method + " request.\n"); | 
|  | } | 
|  | }); | 
|  | } | 
|  |  | 
|  | JSONRPCDispatcher &Dispatcher; | 
|  | JSONOutput *Out; | 
|  | ProtocolCallbacks *Callbacks; | 
|  | }; | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | void clangd::registerCallbackHandlers(JSONRPCDispatcher &Dispatcher, | 
|  | JSONOutput &Out, | 
|  | ProtocolCallbacks &Callbacks) { | 
|  | HandlerRegisterer Register{Dispatcher, &Out, &Callbacks}; | 
|  |  | 
|  | Register("initialize", &ProtocolCallbacks::onInitialize); | 
|  | Register("shutdown", &ProtocolCallbacks::onShutdown); | 
|  | Register("textDocument/didOpen", &ProtocolCallbacks::onDocumentDidOpen); | 
|  | Register("textDocument/didClose", &ProtocolCallbacks::onDocumentDidClose); | 
|  | Register("textDocument/didChange", &ProtocolCallbacks::onDocumentDidChange); | 
|  | Register("textDocument/rangeFormatting", | 
|  | &ProtocolCallbacks::onDocumentRangeFormatting); | 
|  | Register("textDocument/onTypeFormatting", | 
|  | &ProtocolCallbacks::onDocumentOnTypeFormatting); | 
|  | Register("textDocument/formatting", &ProtocolCallbacks::onDocumentFormatting); | 
|  | Register("textDocument/codeAction", &ProtocolCallbacks::onCodeAction); | 
|  | Register("textDocument/completion", &ProtocolCallbacks::onCompletion); | 
|  | Register("textDocument/signatureHelp", &ProtocolCallbacks::onSignatureHelp); | 
|  | Register("textDocument/definition", &ProtocolCallbacks::onGoToDefinition); | 
|  | Register("textDocument/switchSourceHeader", | 
|  | &ProtocolCallbacks::onSwitchSourceHeader); | 
|  | Register("workspace/didChangeWatchedFiles", &ProtocolCallbacks::onFileEvent); | 
|  | } |