MLIR  16.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 "../lsp-server-support/Logging.h"
12 #include "../lsp-server-support/Transport.h"
13 #include "PDLLServer.h"
14 #include "Protocol.h"
15 #include "llvm/ADT/FunctionExtras.h"
16 #include "llvm/ADT/StringMap.h"
17 
18 #define DEBUG_TYPE "pdll-lsp-server"
19 
20 using namespace mlir;
21 using namespace mlir::lsp;
22 
23 //===----------------------------------------------------------------------===//
24 // LSPServer
25 //===----------------------------------------------------------------------===//
26 
27 namespace {
28 struct LSPServer {
29  LSPServer(PDLLServer &server, JSONTransport &transport)
30  : server(server), transport(transport) {}
31 
32  //===--------------------------------------------------------------------===//
33  // Initialization
34 
35  void onInitialize(const InitializeParams &params,
37  void onInitialized(const InitializedParams &params);
38  void onShutdown(const NoParams &params, Callback<std::nullptr_t> reply);
39 
40  //===--------------------------------------------------------------------===//
41  // Document Change
42 
43  void onDocumentDidOpen(const DidOpenTextDocumentParams &params);
44  void onDocumentDidClose(const DidCloseTextDocumentParams &params);
45  void onDocumentDidChange(const DidChangeTextDocumentParams &params);
46 
47  //===--------------------------------------------------------------------===//
48  // Definitions and References
49 
50  void onGoToDefinition(const TextDocumentPositionParams &params,
51  Callback<std::vector<Location>> reply);
52  void onReference(const ReferenceParams &params,
53  Callback<std::vector<Location>> reply);
54 
55  //===----------------------------------------------------------------------===//
56  // DocumentLink
57 
58  void onDocumentLink(const DocumentLinkParams &params,
59  Callback<std::vector<DocumentLink>> reply);
60 
61  //===--------------------------------------------------------------------===//
62  // Hover
63 
64  void onHover(const TextDocumentPositionParams &params,
65  Callback<Optional<Hover>> reply);
66 
67  //===--------------------------------------------------------------------===//
68  // Document Symbols
69 
70  void onDocumentSymbol(const DocumentSymbolParams &params,
71  Callback<std::vector<DocumentSymbol>> reply);
72 
73  //===--------------------------------------------------------------------===//
74  // Code Completion
75 
76  void onCompletion(const CompletionParams &params,
78 
79  //===--------------------------------------------------------------------===//
80  // Signature Help
81 
82  void onSignatureHelp(const TextDocumentPositionParams &params,
84 
85  //===--------------------------------------------------------------------===//
86  // Inlay Hints
87 
88  void onInlayHint(const InlayHintsParams &params,
89  Callback<std::vector<InlayHint>> reply);
90 
91  //===--------------------------------------------------------------------===//
92  // PDLL View Output
93 
94  void onPDLLViewOutput(const PDLLViewOutputParams &params,
96 
97  //===--------------------------------------------------------------------===//
98  // Fields
99  //===--------------------------------------------------------------------===//
100 
101  PDLLServer &server;
102  JSONTransport &transport;
103 
104  /// An outgoing notification used to send diagnostics to the client when they
105  /// are ready to be processed.
107 
108  /// Used to indicate that the 'shutdown' request was received from the
109  /// Language Server client.
110  bool shutdownRequestReceived = false;
111 };
112 } // namespace
113 
114 //===----------------------------------------------------------------------===//
115 // Initialization
116 
117 void LSPServer::onInitialize(const InitializeParams &params,
119  // Send a response with the capabilities of this server.
120  llvm::json::Object serverCaps{
121  {"textDocumentSync",
122  llvm::json::Object{
123  {"openClose", true},
124  {"change", (int)TextDocumentSyncKind::Incremental},
125  {"save", true},
126  }},
127  {"completionProvider",
128  llvm::json::Object{
129  {"allCommitCharacters",
130  {"\t", "(", ")", "[", "]", "{", "}", "<", ">",
131  ":", ";", ",", "+", "-", "/", "*", "%", "^",
132  "&", "#", "?", ".", "=", "\"", "'", "|"}},
133  {"resolveProvider", false},
134  {"triggerCharacters",
135  {".", ">", "(", "{", ",", "<", ":", "[", " ", "\"", "/"}},
136  }},
137  {"signatureHelpProvider",
138  llvm::json::Object{
139  {"triggerCharacters", {"(", ","}},
140  }},
141  {"definitionProvider", true},
142  {"referencesProvider", true},
143  {"documentLinkProvider",
144  llvm::json::Object{
145  {"resolveProvider", false},
146  }},
147  {"hoverProvider", true},
148  {"documentSymbolProvider", true},
149  {"inlayHintProvider", true},
150  };
151 
152  llvm::json::Object result{
153  {{"serverInfo", llvm::json::Object{{"name", "mlir-pdll-lsp-server"},
154  {"version", "0.0.1"}}},
155  {"capabilities", std::move(serverCaps)}}};
156  reply(std::move(result));
157 }
158 void LSPServer::onInitialized(const InitializedParams &) {}
159 void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
160  shutdownRequestReceived = true;
161  reply(nullptr);
162 }
163 
164 //===----------------------------------------------------------------------===//
165 // Document Change
166 
167 void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams &params) {
168  PublishDiagnosticsParams diagParams(params.textDocument.uri,
169  params.textDocument.version);
170  server.addDocument(params.textDocument.uri, params.textDocument.text,
171  params.textDocument.version, diagParams.diagnostics);
172 
173  // Publish any recorded diagnostics.
174  publishDiagnostics(diagParams);
175 }
176 void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams &params) {
177  Optional<int64_t> version = server.removeDocument(params.textDocument.uri);
178  if (!version)
179  return;
180 
181  // Empty out the diagnostics shown for this document. This will clear out
182  // anything currently displayed by the client for this document (e.g. in the
183  // "Problems" pane of VSCode).
184  publishDiagnostics(
185  PublishDiagnosticsParams(params.textDocument.uri, *version));
186 }
187 void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams &params) {
188  PublishDiagnosticsParams diagParams(params.textDocument.uri,
189  params.textDocument.version);
190  server.updateDocument(params.textDocument.uri, params.contentChanges,
191  params.textDocument.version, diagParams.diagnostics);
192 
193  // Publish any recorded diagnostics.
194  publishDiagnostics(diagParams);
195 }
196 
197 //===----------------------------------------------------------------------===//
198 // Definitions and References
199 
200 void LSPServer::onGoToDefinition(const TextDocumentPositionParams &params,
201  Callback<std::vector<Location>> reply) {
202  std::vector<Location> locations;
203  server.getLocationsOf(params.textDocument.uri, params.position, locations);
204  reply(std::move(locations));
205 }
206 
207 void LSPServer::onReference(const ReferenceParams &params,
208  Callback<std::vector<Location>> reply) {
209  std::vector<Location> locations;
210  server.findReferencesOf(params.textDocument.uri, params.position, locations);
211  reply(std::move(locations));
212 }
213 
214 //===----------------------------------------------------------------------===//
215 // DocumentLink
216 
217 void LSPServer::onDocumentLink(const DocumentLinkParams &params,
218  Callback<std::vector<DocumentLink>> reply) {
219  std::vector<DocumentLink> links;
220  server.getDocumentLinks(params.textDocument.uri, links);
221  reply(std::move(links));
222 }
223 
224 //===----------------------------------------------------------------------===//
225 // Hover
226 
227 void LSPServer::onHover(const TextDocumentPositionParams &params,
228  Callback<Optional<Hover>> reply) {
229  reply(server.findHover(params.textDocument.uri, params.position));
230 }
231 
232 //===----------------------------------------------------------------------===//
233 // Document Symbols
234 
235 void LSPServer::onDocumentSymbol(const DocumentSymbolParams &params,
236  Callback<std::vector<DocumentSymbol>> reply) {
237  std::vector<DocumentSymbol> symbols;
238  server.findDocumentSymbols(params.textDocument.uri, symbols);
239  reply(std::move(symbols));
240 }
241 
242 //===----------------------------------------------------------------------===//
243 // Code Completion
244 
245 void LSPServer::onCompletion(const CompletionParams &params,
246  Callback<CompletionList> reply) {
247  reply(server.getCodeCompletion(params.textDocument.uri, params.position));
248 }
249 
250 //===----------------------------------------------------------------------===//
251 // Signature Help
252 
253 void LSPServer::onSignatureHelp(const TextDocumentPositionParams &params,
254  Callback<SignatureHelp> reply) {
255  reply(server.getSignatureHelp(params.textDocument.uri, params.position));
256 }
257 
258 //===----------------------------------------------------------------------===//
259 // Inlay Hints
260 
261 void LSPServer::onInlayHint(const InlayHintsParams &params,
262  Callback<std::vector<InlayHint>> reply) {
263  std::vector<InlayHint> hints;
264  server.getInlayHints(params.textDocument.uri, params.range, hints);
265  reply(std::move(hints));
266 }
267 
268 //===----------------------------------------------------------------------===//
269 // PDLL ViewOutput
270 
271 void LSPServer::onPDLLViewOutput(
272  const PDLLViewOutputParams &params,
274  reply(server.getPDLLViewOutput(params.uri, params.kind));
275 }
276 
277 //===----------------------------------------------------------------------===//
278 // Entry Point
279 //===----------------------------------------------------------------------===//
280 
282  JSONTransport &transport) {
283  LSPServer lspServer(server, transport);
284  MessageHandler messageHandler(transport);
285 
286  // Initialization
287  messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
288  messageHandler.notification("initialized", &lspServer,
289  &LSPServer::onInitialized);
290  messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
291 
292  // Document Changes
293  messageHandler.notification("textDocument/didOpen", &lspServer,
294  &LSPServer::onDocumentDidOpen);
295  messageHandler.notification("textDocument/didClose", &lspServer,
296  &LSPServer::onDocumentDidClose);
297  messageHandler.notification("textDocument/didChange", &lspServer,
298  &LSPServer::onDocumentDidChange);
299 
300  // Definitions and References
301  messageHandler.method("textDocument/definition", &lspServer,
302  &LSPServer::onGoToDefinition);
303  messageHandler.method("textDocument/references", &lspServer,
304  &LSPServer::onReference);
305 
306  // Document Link
307  messageHandler.method("textDocument/documentLink", &lspServer,
308  &LSPServer::onDocumentLink);
309 
310  // Hover
311  messageHandler.method("textDocument/hover", &lspServer, &LSPServer::onHover);
312 
313  // Document Symbols
314  messageHandler.method("textDocument/documentSymbol", &lspServer,
315  &LSPServer::onDocumentSymbol);
316 
317  // Code Completion
318  messageHandler.method("textDocument/completion", &lspServer,
319  &LSPServer::onCompletion);
320 
321  // Signature Help
322  messageHandler.method("textDocument/signatureHelp", &lspServer,
323  &LSPServer::onSignatureHelp);
324 
325  // Inlay Hints
326  messageHandler.method("textDocument/inlayHint", &lspServer,
327  &LSPServer::onInlayHint);
328 
329  // PDLL ViewOutput
330  messageHandler.method("pdll/viewOutput", &lspServer,
331  &LSPServer::onPDLLViewOutput);
332 
333  // Diagnostics
334  lspServer.publishDiagnostics =
336  "textDocument/publishDiagnostics");
337 
338  // Run the main loop of the transport.
339  if (llvm::Error error = transport.run(messageHandler)) {
340  Logger::error("Transport error: {0}", error);
341  llvm::consumeError(std::move(error));
342  return failure();
343  }
344  return success(lspServer.shutdownRequestReceived);
345 }
TextDocumentIdentifier textDocument
The document to provide document links for.
Definition: Protocol.h:977
Include the generated interface declarations.
std::vector< TextDocumentContentChangeEvent > contentChanges
The actual content changes.
Definition: Protocol.h:479
A handler used to process the incoming transport messages.
Definition: Transport.h:104
Parameters for the document link request.
Definition: Protocol.h:975
static void error(const char *fmt, Ts &&...vals)
Definition: Logging.h:42
URIForFile uri
The text document&#39;s URI.
Definition: Protocol.h:237
LogicalResult runPdllLSPServer(PDLLServer &server, JSONTransport &transport)
Run the main loop of the LSP server using the given PDLL server and transport.
Definition: LSPServer.cpp:281
Position position
The position inside the text document.
Definition: Protocol.h:395
VersionedTextDocumentIdentifier textDocument
The document that changed.
Definition: Protocol.h:476
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Transport.h:96
URIForFile uri
The text document&#39;s URI.
Definition: Protocol.h:223
Documents are synced by sending the full content on open.
URIForFile uri
The URI of the document to view the output of.
Definition: Protocol.h:41
int64_t version
The version number of this document.
Definition: Protocol.h:239
TextDocumentItem textDocument
The document that was opened.
Definition: Protocol.h:429
void notification(llvm::StringLiteral method, ThisT *thisPtr, void(ThisT::*handler)(const Param &))
Definition: Transport.h:146
int64_t version
The version number of this document.
Definition: Protocol.h:210
This class implements all of the PDLL related functionality necessary for a language server...
Definition: PDLLServer.h:38
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:392
Range range
The visible document range for which inlay hints should be computed.
Definition: Protocol.h:1030
A parameter literal used in inlay hint requests.
Definition: Protocol.h:1025
Represents the parameters used when viewing the output of a PDLL file.
Definition: Protocol.h:39
TextDocumentIdentifier textDocument
The document that was closed.
Definition: Protocol.h:442
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1027
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
std::string text
The content of the opened text document.
Definition: Protocol.h:207
URIForFile uri
The text document&#39;s URI.
Definition: Protocol.h:201
llvm::unique_function< void(const T &)> OutgoingNotification
An OutgoingNotification<T> is a function used for outgoing notifications send to the client...
Definition: Transport.h:101
void method(llvm::StringLiteral method, ThisT *thisPtr, void(ThisT::*handler)(const Param &, Callback< Result >))
Definition: Transport.h:133
std::vector< Diagnostic > diagnostics
The list of reported diagnostics.
Definition: Protocol.h:692
llvm::Error run(MessageHandler &handler)
Start executing the JSON-RPC transport.
Definition: Transport.cpp:196
TextDocumentIdentifier textDocument
Definition: Protocol.h:606
OutgoingNotification< T > outgoingNotification(llvm::StringLiteral method)
Create an OutgoingNotification object used for the given method.
Definition: Transport.h:159
PDLLViewOutputKind kind
The kind of output to generate.
Definition: Protocol.h:44
A transport class that performs the JSON-RPC communication with the LSP client.
Definition: Transport.h:48