nixd
Loading...
Searching...
No Matches
LSPBinder.h
Go to the documentation of this file.
1#pragma once
2
3#include "Function.h"
4#include "Logger.h"
5#include "Protocol.h"
6#include <llvm/ADT/FunctionExtras.h>
7#include <llvm/ADT/StringMap.h>
8#include <llvm/Support/JSON.h>
9
10namespace lspserver {
11
12template <typename T>
13llvm::Expected<T> parseParam(const llvm::json::Value &Raw,
14 llvm::StringRef PayloadName,
15 llvm::StringRef PayloadKind) {
16 T Result;
17 llvm::json::Path::Root Root;
18 if (!fromJSON(Raw, Result, Root)) {
19 elog("Failed to decode {0} {1}: {2}", PayloadName, PayloadKind,
20 Root.getError());
21 // Dump the relevant parts of the broken message.
22 std::string Context;
23 llvm::raw_string_ostream OS(Context);
24 Root.printErrorContext(Raw, OS);
25 vlog("{0}", OS.str());
26 // Report the error (e.g. to the client).
27 return llvm::make_error<LSPError>(
28 llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind,
29 fmt_consume(Root.getError())),
31 }
32 return std::move(Result);
33}
34
35template <>
36inline llvm::Expected<llvm::json::Value>
37parseParam(const llvm::json::Value &Raw, llvm::StringRef PayloadName,
38 llvm::StringRef PayloadKind) {
39 return Raw;
40}
41
43 using JSON = llvm::json::Value;
44 template <typename HandlerT>
45 using HandlerMap = llvm::StringMap<llvm::unique_function<HandlerT>>;
46
50
51public:
52 /// Bind a handler for an LSP method.
53 /// e.g. method("peek", this, &ThisModule::peek);
54 /// Handler should be e.g. void peek(const PeekParams&, Callback<PeekResult>);
55 /// PeekParams must be JSON-parseable and PeekResult must be serializable.
56 template <typename Param, typename Result, typename ThisT>
57 void addMethod(llvm::StringRef Method, ThisT *This,
58 void (ThisT::*Handler)(const Param &, Callback<Result>)) {
61 auto P = parseParam<Param>(RawParams, Method, "request");
62 if (!P)
63 return Reply(P.takeError());
64 (This->*Handler)(*P, std::move(Reply));
65 };
66 }
67
68 /// Bind a handler for an LSP notification.
69 /// e.g. notification("poke", this, &ThisModule::poke);
70 /// Handler should be e.g. void poke(const PokeParams&);
71 /// PokeParams must be JSON-parseable.
72 template <typename Param, typename ThisT>
73 void addNotification(llvm::StringLiteral Method, ThisT *This,
74 void (ThisT::*Handler)(const Param &)) {
76 llvm::Expected<Param> P = parseParam<Param>(RawParams, Method, "request");
77 if (!P)
78 return llvm::consumeError(P.takeError());
79 (This->*Handler)(*P);
80 };
81 }
82
83 /// Bind a handler for an LSP command.
84 /// e.g. command("load", this, &ThisModule::load);
85 /// Handler should be e.g. void load(const LoadParams&, Callback<LoadResult>);
86 /// LoadParams must be JSON-parseable and LoadResult must be serializable.
87 template <typename Param, typename Result, typename ThisT>
88 void addCommand(llvm::StringLiteral Command, ThisT *This,
89 void (ThisT::*Handler)(const Param &, Callback<Result>)) {
92 auto P = parseParam<Param>(RawParams, Command, "command");
93 if (!P)
94 return Reply(P.takeError());
95 (This->*Handler)(*P, std::move(Reply));
96 };
97 }
98};
99
100} // namespace lspserver
Whether current platform treats paths case insensitively.
Definition Connection.h:11
llvm::unique_function< void(llvm::Expected< T >)> Callback
Definition Function.h:14
llvm::Expected< T > parseParam(const llvm::json::Value &Raw, llvm::StringRef PayloadName, llvm::StringRef PayloadKind)
Definition LSPBinder.h:13
bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path)
void elog(const char *Fmt, Ts &&...Vals)
Definition Logger.h:52
void vlog(const char *Fmt, Ts &&...Vals)
Definition Logger.h:63
void addMethod(llvm::StringRef Method, ThisT *This, void(ThisT::*Handler)(const Param &, Callback< Result >))
Definition LSPBinder.h:57
llvm::StringMap< llvm::unique_function< HandlerT > > HandlerMap
Definition LSPBinder.h:45
void addNotification(llvm::StringLiteral Method, ThisT *This, void(ThisT::*Handler)(const Param &))
Definition LSPBinder.h:73
llvm::json::Value JSON
Definition LSPBinder.h:43
HandlerMap< void(JSON)> NotificationHandlers
Definition LSPBinder.h:47
HandlerMap< void(JSON, Callback< JSON >)> MethodHandlers
Definition LSPBinder.h:48
void addCommand(llvm::StringLiteral Command, ThisT *This, void(ThisT::*Handler)(const Param &, Callback< Result >))
Definition LSPBinder.h:88
HandlerMap< void(JSON, Callback< JSON >)> CommandHandlers
Definition LSPBinder.h:49