MLIR  19.0.0git
LSPServer.cpp
Go to the documentation of this file.
1 //===- LSPServer.cpp - TableGen 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 "TableGenServer.h"
15 #include "llvm/ADT/FunctionExtras.h"
16 #include "llvm/ADT/StringMap.h"
17 #include <optional>
18 
19 using namespace mlir;
20 using namespace mlir::lsp;
21 
22 //===----------------------------------------------------------------------===//
23 // LSPServer
24 //===----------------------------------------------------------------------===//
25 
26 namespace {
27 struct LSPServer {
28  LSPServer(TableGenServer &server, JSONTransport &transport)
29  : server(server), transport(transport) {}
30 
31  //===--------------------------------------------------------------------===//
32  // Initialization
33 
34  void onInitialize(const InitializeParams &params,
36  void onInitialized(const InitializedParams &params);
37  void onShutdown(const NoParams &params, Callback<std::nullptr_t> reply);
38 
39  //===--------------------------------------------------------------------===//
40  // Document Change
41 
42  void onDocumentDidOpen(const DidOpenTextDocumentParams &params);
43  void onDocumentDidClose(const DidCloseTextDocumentParams &params);
44  void onDocumentDidChange(const DidChangeTextDocumentParams &params);
45 
46  //===--------------------------------------------------------------------===//
47  // Definitions and References
48 
49  void onGoToDefinition(const TextDocumentPositionParams &params,
50  Callback<std::vector<Location>> reply);
51  void onReference(const ReferenceParams &params,
52  Callback<std::vector<Location>> reply);
53 
54  //===----------------------------------------------------------------------===//
55  // DocumentLink
56 
57  void onDocumentLink(const DocumentLinkParams &params,
58  Callback<std::vector<DocumentLink>> reply);
59 
60  //===--------------------------------------------------------------------===//
61  // Hover
62 
63  void onHover(const TextDocumentPositionParams &params,
64  Callback<std::optional<Hover>> reply);
65 
66  //===--------------------------------------------------------------------===//
67  // Fields
68  //===--------------------------------------------------------------------===//
69 
70  TableGenServer &server;
71  JSONTransport &transport;
72 
73  /// An outgoing notification used to send diagnostics to the client when they
74  /// are ready to be processed.
76 
77  /// Used to indicate that the 'shutdown' request was received from the
78  /// Language Server client.
79  bool shutdownRequestReceived = false;
80 };
81 } // namespace
82 
83 //===----------------------------------------------------------------------===//
84 // Initialization
85 
86 void LSPServer::onInitialize(const InitializeParams &params,
88  // Send a response with the capabilities of this server.
89  llvm::json::Object serverCaps{
90  {"textDocumentSync",
91  llvm::json::Object{
92  {"openClose", true},
93  {"change", (int)TextDocumentSyncKind::Incremental},
94  {"save", true},
95  }},
96  {"definitionProvider", true},
97  {"referencesProvider", true},
98  {"documentLinkProvider",
99  llvm::json::Object{
100  {"resolveProvider", false},
101  }},
102  {"hoverProvider", true},
103  };
104 
105  llvm::json::Object result{
106  {{"serverInfo", llvm::json::Object{{"name", "tblgen-lsp-server"},
107  {"version", "0.0.1"}}},
108  {"capabilities", std::move(serverCaps)}}};
109  reply(std::move(result));
110 }
111 void LSPServer::onInitialized(const InitializedParams &) {}
112 void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
113  shutdownRequestReceived = true;
114  reply(nullptr);
115 }
116 
117 //===----------------------------------------------------------------------===//
118 // Document Change
119 
120 void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams &params) {
121  PublishDiagnosticsParams diagParams(params.textDocument.uri,
122  params.textDocument.version);
123  server.addDocument(params.textDocument.uri, params.textDocument.text,
124  params.textDocument.version, diagParams.diagnostics);
125 
126  // Publish any recorded diagnostics.
127  publishDiagnostics(diagParams);
128 }
129 void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams &params) {
130  std::optional<int64_t> version =
131  server.removeDocument(params.textDocument.uri);
132  if (!version)
133  return;
134 
135  // Empty out the diagnostics shown for this document. This will clear out
136  // anything currently displayed by the client for this document (e.g. in the
137  // "Problems" pane of VSCode).
138  publishDiagnostics(
139  PublishDiagnosticsParams(params.textDocument.uri, *version));
140 }
141 void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams &params) {
142  PublishDiagnosticsParams diagParams(params.textDocument.uri,
143  params.textDocument.version);
144  server.updateDocument(params.textDocument.uri, params.contentChanges,
145  params.textDocument.version, diagParams.diagnostics);
146 
147  // Publish any recorded diagnostics.
148  publishDiagnostics(diagParams);
149 }
150 
151 //===----------------------------------------------------------------------===//
152 // Definitions and References
153 
154 void LSPServer::onGoToDefinition(const TextDocumentPositionParams &params,
155  Callback<std::vector<Location>> reply) {
156  std::vector<Location> locations;
157  server.getLocationsOf(params.textDocument.uri, params.position, locations);
158  reply(std::move(locations));
159 }
160 
161 void LSPServer::onReference(const ReferenceParams &params,
162  Callback<std::vector<Location>> reply) {
163  std::vector<Location> locations;
164  server.findReferencesOf(params.textDocument.uri, params.position, locations);
165  reply(std::move(locations));
166 }
167 
168 //===----------------------------------------------------------------------===//
169 // DocumentLink
170 
171 void LSPServer::onDocumentLink(const DocumentLinkParams &params,
172  Callback<std::vector<DocumentLink>> reply) {
173  std::vector<DocumentLink> links;
174  server.getDocumentLinks(params.textDocument.uri, links);
175  reply(std::move(links));
176 }
177 
178 //===----------------------------------------------------------------------===//
179 // Hover
180 
181 void LSPServer::onHover(const TextDocumentPositionParams &params,
182  Callback<std::optional<Hover>> reply) {
183  reply(server.findHover(params.textDocument.uri, params.position));
184 }
185 
186 //===----------------------------------------------------------------------===//
187 // Entry Point
188 //===----------------------------------------------------------------------===//
189 
191  JSONTransport &transport) {
192  LSPServer lspServer(server, transport);
193  MessageHandler messageHandler(transport);
194 
195  // Initialization
196  messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
197  messageHandler.notification("initialized", &lspServer,
198  &LSPServer::onInitialized);
199  messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
200 
201  // Document Changes
202  messageHandler.notification("textDocument/didOpen", &lspServer,
203  &LSPServer::onDocumentDidOpen);
204  messageHandler.notification("textDocument/didClose", &lspServer,
205  &LSPServer::onDocumentDidClose);
206  messageHandler.notification("textDocument/didChange", &lspServer,
207  &LSPServer::onDocumentDidChange);
208 
209  // Definitions and References
210  messageHandler.method("textDocument/definition", &lspServer,
211  &LSPServer::onGoToDefinition);
212  messageHandler.method("textDocument/references", &lspServer,
213  &LSPServer::onReference);
214 
215  // Document Link
216  messageHandler.method("textDocument/documentLink", &lspServer,
217  &LSPServer::onDocumentLink);
218 
219  // Hover
220  messageHandler.method("textDocument/hover", &lspServer, &LSPServer::onHover);
221 
222  // Diagnostics
223  lspServer.publishDiagnostics =
225  "textDocument/publishDiagnostics");
226 
227  // Run the main loop of the transport.
228  if (llvm::Error error = transport.run(messageHandler)) {
229  Logger::error("Transport error: {0}", error);
230  llvm::consumeError(std::move(error));
231  return failure();
232  }
233  return success(lspServer.shutdownRequestReceived);
234 }
A transport class that performs the JSON-RPC communication with the LSP client.
Definition: Transport.h:48
llvm::Error run(MessageHandler &handler)
Start executing the JSON-RPC transport.
Definition: Transport.cpp:201
static void error(const char *fmt, Ts &&...vals)
Definition: Logging.h:42
A handler used to process the incoming transport messages.
Definition: Transport.h:104
void notification(llvm::StringLiteral method, ThisT *thisPtr, void(ThisT::*handler)(const Param &))
Definition: Transport.h:146
void method(llvm::StringLiteral method, ThisT *thisPtr, void(ThisT::*handler)(const Param &, Callback< Result >))
Definition: Transport.h:133
OutgoingNotification< T > outgoingNotification(llvm::StringLiteral method)
Create an OutgoingNotification object used for the given method.
Definition: Transport.h:159
This class implements all of the TableGen related functionality necessary for a language server.
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
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Transport.h:96
@ Incremental
Documents are synced by sending the full content on open.
LogicalResult runTableGenLSPServer(TableGenServer &server, JSONTransport &transport)
Run the main loop of the LSP server using the given TableGen server and transport.
Definition: LSPServer.cpp:190
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
VersionedTextDocumentIdentifier textDocument
The document that changed.
Definition: Protocol.h:506
std::vector< TextDocumentContentChangeEvent > contentChanges
The actual content changes.
Definition: Protocol.h:509
TextDocumentIdentifier textDocument
The document that was closed.
Definition: Protocol.h:472
TextDocumentItem textDocument
The document that was opened.
Definition: Protocol.h:459
Parameters for the document link request.
Definition: Protocol.h:1005
TextDocumentIdentifier textDocument
The document to provide document links for.
Definition: Protocol.h:1007
URIForFile uri
The text document's URI.
Definition: Protocol.h:253
int64_t version
The version number of this document.
Definition: Protocol.h:240
std::string text
The content of the opened text document.
Definition: Protocol.h:237
URIForFile uri
The text document's URI.
Definition: Protocol.h:231
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:422
Position position
The position inside the text document.
Definition: Protocol.h:425
int64_t version
The version number of this document.
Definition: Protocol.h:269
URIForFile uri
The text document's URI.
Definition: Protocol.h:267