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 
20 using namespace mlir;
21 using namespace mlir::lsp;
22 
23 using llvm::lsp::Callback;
24 using llvm::lsp::CompletionList;
25 using llvm::lsp::CompletionParams;
26 using llvm::lsp::DidChangeTextDocumentParams;
27 using llvm::lsp::DidCloseTextDocumentParams;
28 using llvm::lsp::DidOpenTextDocumentParams;
29 using llvm::lsp::DocumentLinkParams;
30 using llvm::lsp::DocumentSymbol;
31 using llvm::lsp::DocumentSymbolParams;
32 using llvm::lsp::Hover;
33 using llvm::lsp::InitializedParams;
34 using llvm::lsp::InitializeParams;
35 using llvm::lsp::InlayHintsParams;
36 using llvm::lsp::JSONTransport;
37 using llvm::lsp::Location;
38 using llvm::lsp::Logger;
39 using llvm::lsp::MessageHandler;
40 using llvm::lsp::NoParams;
41 using llvm::lsp::OutgoingNotification;
42 using llvm::lsp::PublishDiagnosticsParams;
43 using llvm::lsp::ReferenceParams;
44 using llvm::lsp::TextDocumentPositionParams;
45 using llvm::lsp::TextDocumentSyncKind;
46 
47 //===----------------------------------------------------------------------===//
48 // LSPServer
49 //===----------------------------------------------------------------------===//
50 
51 namespace {
52 struct 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 
142 void 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 }
183 void LSPServer::onInitialized(const InitializedParams &) {}
184 void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
185  shutdownRequestReceived = true;
186  reply(nullptr);
187 }
188 
189 //===----------------------------------------------------------------------===//
190 // Document Change
191 //===----------------------------------------------------------------------===//
192 
193 void 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 }
202 void 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 }
214 void 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 
228 void 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 
235 void 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 
246 void 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 
257 void 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 
266 void 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 
277 void 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 
286 void 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 
295 void 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 
306 void 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 
316 LogicalResult 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 }
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