MLIR 22.0.0git
LSPServer.cpp
Go to the documentation of this file.
1//===- LSPServer.cpp - PDLL Language Server -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "LSPServer.h"
10
11#include "PDLLServer.h"
12#include "Protocol.h"
13#include "llvm/Support/LSP/Logging.h"
14#include "llvm/Support/LSP/Protocol.h"
15#include "llvm/Support/LSP/Transport.h"
16#include <optional>
17
18#define DEBUG_TYPE "pdll-lsp-server"
19
20using namespace mlir;
21using namespace mlir::lsp;
22
23using llvm::lsp::Callback;
24using llvm::lsp::CompletionList;
25using llvm::lsp::CompletionParams;
26using llvm::lsp::DidChangeTextDocumentParams;
27using llvm::lsp::DidCloseTextDocumentParams;
28using llvm::lsp::DidOpenTextDocumentParams;
29using llvm::lsp::DocumentLinkParams;
30using llvm::lsp::DocumentSymbol;
31using llvm::lsp::DocumentSymbolParams;
32using llvm::lsp::Hover;
33using llvm::lsp::InitializedParams;
34using llvm::lsp::InitializeParams;
35using llvm::lsp::InlayHintsParams;
36using llvm::lsp::JSONTransport;
37using llvm::lsp::Location;
38using llvm::lsp::Logger;
39using llvm::lsp::MessageHandler;
40using llvm::lsp::NoParams;
41using llvm::lsp::OutgoingNotification;
42using llvm::lsp::PublishDiagnosticsParams;
43using llvm::lsp::ReferenceParams;
44using llvm::lsp::TextDocumentPositionParams;
45using llvm::lsp::TextDocumentSyncKind;
46
47//===----------------------------------------------------------------------===//
48// LSPServer
49//===----------------------------------------------------------------------===//
50
51namespace {
52struct LSPServer {
53 LSPServer(PDLLServer &server, JSONTransport &transport)
54 : server(server), transport(transport) {}
55
56 //===--------------------------------------------------------------------===//
57 // Initialization
58
59 void onInitialize(const InitializeParams &params,
60 Callback<llvm::json::Value> reply);
61 void onInitialized(const InitializedParams &params);
62 void onShutdown(const NoParams &params, Callback<std::nullptr_t> reply);
63
64 //===--------------------------------------------------------------------===//
65 // Document Change
66
67 void onDocumentDidOpen(const DidOpenTextDocumentParams &params);
68 void onDocumentDidClose(const DidCloseTextDocumentParams &params);
69 void onDocumentDidChange(const DidChangeTextDocumentParams &params);
70
71 //===--------------------------------------------------------------------===//
72 // Definitions and References
73
74 void onGoToDefinition(const TextDocumentPositionParams &params,
75 Callback<std::vector<Location>> reply);
76 void onReference(const ReferenceParams &params,
77 Callback<std::vector<Location>> reply);
78
79 //===----------------------------------------------------------------------===//
80 // DocumentLink
81
82 void onDocumentLink(const DocumentLinkParams &params,
83 Callback<std::vector<DocumentLink>> reply);
84
85 //===--------------------------------------------------------------------===//
86 // Hover
87
88 void onHover(const TextDocumentPositionParams &params,
89 Callback<std::optional<Hover>> reply);
90
91 //===--------------------------------------------------------------------===//
92 // Document Symbols
93
94 void onDocumentSymbol(const DocumentSymbolParams &params,
95 Callback<std::vector<DocumentSymbol>> reply);
96
97 //===--------------------------------------------------------------------===//
98 // Code Completion
99
100 void onCompletion(const CompletionParams &params,
101 Callback<CompletionList> reply);
102
103 //===--------------------------------------------------------------------===//
104 // Signature Help
105
106 void onSignatureHelp(const TextDocumentPositionParams &params,
107 Callback<SignatureHelp> reply);
108
109 //===--------------------------------------------------------------------===//
110 // Inlay Hints
111
112 void onInlayHint(const InlayHintsParams &params,
113 Callback<std::vector<InlayHint>> reply);
114
115 //===--------------------------------------------------------------------===//
116 // PDLL View Output
117
118 void onPDLLViewOutput(const PDLLViewOutputParams &params,
119 Callback<std::optional<PDLLViewOutputResult>> reply);
120
121 //===--------------------------------------------------------------------===//
122 // Fields
123 //===--------------------------------------------------------------------===//
124
125 PDLLServer &server;
126 JSONTransport &transport;
127
128 /// An outgoing notification used to send diagnostics to the client when they
129 /// are ready to be processed.
130 OutgoingNotification<PublishDiagnosticsParams> publishDiagnostics;
131
132 /// Used to indicate that the 'shutdown' request was received from the
133 /// Language Server client.
134 bool shutdownRequestReceived = false;
135};
136} // namespace
137
138//===----------------------------------------------------------------------===//
139// Initialization
140//===----------------------------------------------------------------------===//
141
142void LSPServer::onInitialize(const InitializeParams &params,
143 Callback<llvm::json::Value> reply) {
144 // Send a response with the capabilities of this server.
145 llvm::json::Object serverCaps{
146 {"textDocumentSync",
147 llvm::json::Object{
148 {"openClose", true},
149 {"change", (int)TextDocumentSyncKind::Incremental},
150 {"save", true},
151 }},
152 {"completionProvider",
153 llvm::json::Object{
154 {"allCommitCharacters",
155 {"\t", "(", ")", "[", "]", "{", "}", "<", ">",
156 ":", ";", ",", "+", "-", "/", "*", "%", "^",
157 "&", "#", "?", ".", "=", "\"", "'", "|"}},
158 {"resolveProvider", false},
159 {"triggerCharacters",
160 {".", ">", "(", "{", ",", "<", ":", "[", " ", "\"", "/"}},
161 }},
162 {"signatureHelpProvider",
163 llvm::json::Object{
164 {"triggerCharacters", {"(", ","}},
165 }},
166 {"definitionProvider", true},
167 {"referencesProvider", true},
168 {"documentLinkProvider",
169 llvm::json::Object{
170 {"resolveProvider", false},
171 }},
172 {"hoverProvider", true},
173 {"documentSymbolProvider", true},
174 {"inlayHintProvider", true},
175 };
176
177 llvm::json::Object result{
178 {{"serverInfo", llvm::json::Object{{"name", "mlir-pdll-lsp-server"},
179 {"version", "0.0.1"}}},
180 {"capabilities", std::move(serverCaps)}}};
181 reply(std::move(result));
182}
183void LSPServer::onInitialized(const InitializedParams &) {}
184void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
185 shutdownRequestReceived = true;
186 reply(nullptr);
187}
188
189//===----------------------------------------------------------------------===//
190// Document Change
191//===----------------------------------------------------------------------===//
192
193void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams &params) {
194 PublishDiagnosticsParams diagParams(params.textDocument.uri,
195 params.textDocument.version);
196 server.addDocument(params.textDocument.uri, params.textDocument.text,
197 params.textDocument.version, diagParams.diagnostics);
198
199 // Publish any recorded diagnostics.
200 publishDiagnostics(diagParams);
201}
202void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams &params) {
203 std::optional<int64_t> version =
204 server.removeDocument(params.textDocument.uri);
205 if (!version)
206 return;
207
208 // Empty out the diagnostics shown for this document. This will clear out
209 // anything currently displayed by the client for this document (e.g. in the
210 // "Problems" pane of VSCode).
211 publishDiagnostics(
212 PublishDiagnosticsParams(params.textDocument.uri, *version));
213}
214void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams &params) {
215 PublishDiagnosticsParams diagParams(params.textDocument.uri,
216 params.textDocument.version);
217 server.updateDocument(params.textDocument.uri, params.contentChanges,
218 params.textDocument.version, diagParams.diagnostics);
219
220 // Publish any recorded diagnostics.
221 publishDiagnostics(diagParams);
222}
223
224//===----------------------------------------------------------------------===//
225// Definitions and References
226//===----------------------------------------------------------------------===//
227
228void LSPServer::onGoToDefinition(const TextDocumentPositionParams &params,
229 Callback<std::vector<Location>> reply) {
230 std::vector<Location> locations;
231 server.getLocationsOf(params.textDocument.uri, params.position, locations);
232 reply(std::move(locations));
233}
234
235void LSPServer::onReference(const ReferenceParams &params,
236 Callback<std::vector<Location>> reply) {
237 std::vector<Location> locations;
238 server.findReferencesOf(params.textDocument.uri, params.position, locations);
239 reply(std::move(locations));
240}
241
242//===----------------------------------------------------------------------===//
243// DocumentLink
244//===----------------------------------------------------------------------===//
245
246void LSPServer::onDocumentLink(const DocumentLinkParams &params,
247 Callback<std::vector<DocumentLink>> reply) {
248 std::vector<DocumentLink> links;
249 server.getDocumentLinks(params.textDocument.uri, links);
250 reply(std::move(links));
251}
252
253//===----------------------------------------------------------------------===//
254// Hover
255//===----------------------------------------------------------------------===//
256
257void LSPServer::onHover(const TextDocumentPositionParams &params,
258 Callback<std::optional<Hover>> reply) {
259 reply(server.findHover(params.textDocument.uri, params.position));
260}
261
262//===----------------------------------------------------------------------===//
263// Document Symbols
264//===----------------------------------------------------------------------===//
265
266void LSPServer::onDocumentSymbol(const DocumentSymbolParams &params,
267 Callback<std::vector<DocumentSymbol>> reply) {
268 std::vector<DocumentSymbol> symbols;
269 server.findDocumentSymbols(params.textDocument.uri, symbols);
270 reply(std::move(symbols));
271}
272
273//===----------------------------------------------------------------------===//
274// Code Completion
275//===----------------------------------------------------------------------===//
276
277void LSPServer::onCompletion(const CompletionParams &params,
278 Callback<CompletionList> reply) {
279 reply(server.getCodeCompletion(params.textDocument.uri, params.position));
280}
281
282//===----------------------------------------------------------------------===//
283// Signature Help
284//===----------------------------------------------------------------------===//
285
286void LSPServer::onSignatureHelp(const TextDocumentPositionParams &params,
287 Callback<SignatureHelp> reply) {
288 reply(server.getSignatureHelp(params.textDocument.uri, params.position));
289}
290
291//===----------------------------------------------------------------------===//
292// Inlay Hints
293//===----------------------------------------------------------------------===//
294
295void LSPServer::onInlayHint(const InlayHintsParams &params,
296 Callback<std::vector<InlayHint>> reply) {
297 std::vector<InlayHint> hints;
298 server.getInlayHints(params.textDocument.uri, params.range, hints);
299 reply(std::move(hints));
300}
301
302//===----------------------------------------------------------------------===//
303// PDLL ViewOutput
304//===----------------------------------------------------------------------===//
305
306void LSPServer::onPDLLViewOutput(
307 const PDLLViewOutputParams &params,
308 Callback<std::optional<PDLLViewOutputResult>> reply) {
309 reply(server.getPDLLViewOutput(params.uri, params.kind));
310}
311
312//===----------------------------------------------------------------------===//
313// Entry Point
314//===----------------------------------------------------------------------===//
315
316LogicalResult mlir::lsp::runPdllLSPServer(PDLLServer &server,
317 JSONTransport &transport) {
318 LSPServer lspServer(server, transport);
319 MessageHandler messageHandler(transport);
320
321 // Initialization
322 messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
323 messageHandler.notification("initialized", &lspServer,
324 &LSPServer::onInitialized);
325 messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
326
327 // Document Changes
328 messageHandler.notification("textDocument/didOpen", &lspServer,
329 &LSPServer::onDocumentDidOpen);
330 messageHandler.notification("textDocument/didClose", &lspServer,
331 &LSPServer::onDocumentDidClose);
332 messageHandler.notification("textDocument/didChange", &lspServer,
333 &LSPServer::onDocumentDidChange);
334
335 // Definitions and References
336 messageHandler.method("textDocument/definition", &lspServer,
337 &LSPServer::onGoToDefinition);
338 messageHandler.method("textDocument/references", &lspServer,
339 &LSPServer::onReference);
340
341 // Document Link
342 messageHandler.method("textDocument/documentLink", &lspServer,
343 &LSPServer::onDocumentLink);
344
345 // Hover
346 messageHandler.method("textDocument/hover", &lspServer, &LSPServer::onHover);
347
348 // Document Symbols
349 messageHandler.method("textDocument/documentSymbol", &lspServer,
350 &LSPServer::onDocumentSymbol);
351
352 // Code Completion
353 messageHandler.method("textDocument/completion", &lspServer,
354 &LSPServer::onCompletion);
355
356 // Signature Help
357 messageHandler.method("textDocument/signatureHelp", &lspServer,
358 &LSPServer::onSignatureHelp);
359
360 // Inlay Hints
361 messageHandler.method("textDocument/inlayHint", &lspServer,
362 &LSPServer::onInlayHint);
363
364 // PDLL ViewOutput
365 messageHandler.method("pdll/viewOutput", &lspServer,
366 &LSPServer::onPDLLViewOutput);
367
368 // Diagnostics
369 lspServer.publishDiagnostics =
370 messageHandler.outgoingNotification<PublishDiagnosticsParams>(
371 "textDocument/publishDiagnostics");
372
373 // Run the main loop of the transport.
374 if (llvm::Error error = transport.run(messageHandler)) {
375 Logger::error("Transport error: {0}", error);
376 llvm::consumeError(std::move(error));
377 return failure();
378 }
379 return success(lspServer.shutdownRequestReceived);
380}
return success()
std::optional< int64_t > removeDocument(const URIForFile &uri)
Remove the document with the given uri.
void findReferencesOf(const URIForFile &uri, const Position &pos, std::vector< Location > &references)
Find all references of the object pointed at by the given position.
void getLocationsOf(const URIForFile &uri, const Position &defPos, std::vector< Location > &locations)
Return the locations of the object pointed at by the given position.
std::optional< Hover > findHover(const URIForFile &uri, const Position &hoverPos)
Find a hover description for the given hover position, or std::nullopt if one couldn't be found.
CompletionList getCodeCompletion(const URIForFile &uri, const Position &completePos)
Get the code completion list for the position within the given file.
void findDocumentSymbols(const URIForFile &uri, std::vector< DocumentSymbol > &symbols)
Find all of the document symbols within the given file.
This class implements all of the PDLL related functionality necessary for a language server.
Definition PDLLServer.h:42
llvm::LogicalResult runPdllLSPServer(PDLLServer &server, llvm::lsp::JSONTransport &transport)
Run the main loop of the LSP server using the given PDLL server and transport.
Include the generated interface declarations.
Represents the parameters used when viewing the output of a PDLL file.
Definition Protocol.h:41
URIForFile uri
The URI of the document to view the output of.
Definition Protocol.h:43
PDLLViewOutputKind kind
The kind of output to generate.
Definition Protocol.h:46