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