15de12bb7SRiver Riddle //===- LSPServer.cpp - TableGen Language Server ---------------------------===//
25de12bb7SRiver Riddle //
35de12bb7SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45de12bb7SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
55de12bb7SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65de12bb7SRiver Riddle //
75de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
85de12bb7SRiver Riddle
95de12bb7SRiver Riddle #include "LSPServer.h"
105de12bb7SRiver Riddle
115de12bb7SRiver Riddle #include "TableGenServer.h"
12305d7185SRiver Riddle #include "mlir/Tools/lsp-server-support/Logging.h"
13305d7185SRiver Riddle #include "mlir/Tools/lsp-server-support/Protocol.h"
14305d7185SRiver Riddle #include "mlir/Tools/lsp-server-support/Transport.h"
155de12bb7SRiver Riddle #include "llvm/ADT/FunctionExtras.h"
165de12bb7SRiver Riddle #include "llvm/ADT/StringMap.h"
17a1fe1f5fSKazu Hirata #include <optional>
185de12bb7SRiver Riddle
195de12bb7SRiver Riddle using namespace mlir;
205de12bb7SRiver Riddle using namespace mlir::lsp;
215de12bb7SRiver Riddle
225de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
235de12bb7SRiver Riddle // LSPServer
245de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
255de12bb7SRiver Riddle
265de12bb7SRiver Riddle namespace {
275de12bb7SRiver Riddle struct LSPServer {
LSPServer__anonbf2586cd0111::LSPServer285de12bb7SRiver Riddle LSPServer(TableGenServer &server, JSONTransport &transport)
295de12bb7SRiver Riddle : server(server), transport(transport) {}
305de12bb7SRiver Riddle
315de12bb7SRiver Riddle //===--------------------------------------------------------------------===//
325de12bb7SRiver Riddle // Initialization
335de12bb7SRiver Riddle
345de12bb7SRiver Riddle void onInitialize(const InitializeParams ¶ms,
355de12bb7SRiver Riddle Callback<llvm::json::Value> reply);
365de12bb7SRiver Riddle void onInitialized(const InitializedParams ¶ms);
375de12bb7SRiver Riddle void onShutdown(const NoParams ¶ms, Callback<std::nullptr_t> reply);
385de12bb7SRiver Riddle
395de12bb7SRiver Riddle //===--------------------------------------------------------------------===//
405de12bb7SRiver Riddle // Document Change
415de12bb7SRiver Riddle
425de12bb7SRiver Riddle void onDocumentDidOpen(const DidOpenTextDocumentParams ¶ms);
435de12bb7SRiver Riddle void onDocumentDidClose(const DidCloseTextDocumentParams ¶ms);
445de12bb7SRiver Riddle void onDocumentDidChange(const DidChangeTextDocumentParams ¶ms);
455de12bb7SRiver Riddle
468d021670SRiver Riddle //===--------------------------------------------------------------------===//
478d021670SRiver Riddle // Definitions and References
488d021670SRiver Riddle
498d021670SRiver Riddle void onGoToDefinition(const TextDocumentPositionParams ¶ms,
508d021670SRiver Riddle Callback<std::vector<Location>> reply);
518d021670SRiver Riddle void onReference(const ReferenceParams ¶ms,
528d021670SRiver Riddle Callback<std::vector<Location>> reply);
538d021670SRiver Riddle
54682ca00eSRiver Riddle //===----------------------------------------------------------------------===//
55682ca00eSRiver Riddle // DocumentLink
56682ca00eSRiver Riddle
57682ca00eSRiver Riddle void onDocumentLink(const DocumentLinkParams ¶ms,
58682ca00eSRiver Riddle Callback<std::vector<DocumentLink>> reply);
59682ca00eSRiver Riddle
60682ca00eSRiver Riddle //===--------------------------------------------------------------------===//
61682ca00eSRiver Riddle // Hover
62682ca00eSRiver Riddle
63682ca00eSRiver Riddle void onHover(const TextDocumentPositionParams ¶ms,
641da3a795SFangrui Song Callback<std::optional<Hover>> reply);
65682ca00eSRiver Riddle
665de12bb7SRiver Riddle //===--------------------------------------------------------------------===//
675de12bb7SRiver Riddle // Fields
685de12bb7SRiver Riddle //===--------------------------------------------------------------------===//
695de12bb7SRiver Riddle
705de12bb7SRiver Riddle TableGenServer &server;
715de12bb7SRiver Riddle JSONTransport &transport;
725de12bb7SRiver Riddle
735de12bb7SRiver Riddle /// An outgoing notification used to send diagnostics to the client when they
745de12bb7SRiver Riddle /// are ready to be processed.
75*a8c88de0SBrian Gesiak OutgoingNotification<PublishDiagnosticsParams> publishDiagnostics;
765de12bb7SRiver Riddle
775de12bb7SRiver Riddle /// Used to indicate that the 'shutdown' request was received from the
785de12bb7SRiver Riddle /// Language Server client.
795de12bb7SRiver Riddle bool shutdownRequestReceived = false;
805de12bb7SRiver Riddle };
815de12bb7SRiver Riddle } // namespace
825de12bb7SRiver Riddle
835de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
845de12bb7SRiver Riddle // Initialization
855de12bb7SRiver Riddle
onInitialize(const InitializeParams & params,Callback<llvm::json::Value> reply)865de12bb7SRiver Riddle void LSPServer::onInitialize(const InitializeParams ¶ms,
875de12bb7SRiver Riddle Callback<llvm::json::Value> reply) {
885de12bb7SRiver Riddle // Send a response with the capabilities of this server.
895de12bb7SRiver Riddle llvm::json::Object serverCaps{
905de12bb7SRiver Riddle {"textDocumentSync",
915de12bb7SRiver Riddle llvm::json::Object{
925de12bb7SRiver Riddle {"openClose", true},
936187178eSRiver Riddle {"change", (int)TextDocumentSyncKind::Incremental},
945de12bb7SRiver Riddle {"save", true},
955de12bb7SRiver Riddle }},
968d021670SRiver Riddle {"definitionProvider", true},
978d021670SRiver Riddle {"referencesProvider", true},
98682ca00eSRiver Riddle {"documentLinkProvider",
99682ca00eSRiver Riddle llvm::json::Object{
100682ca00eSRiver Riddle {"resolveProvider", false},
101682ca00eSRiver Riddle }},
102682ca00eSRiver Riddle {"hoverProvider", true},
1035de12bb7SRiver Riddle };
1045de12bb7SRiver Riddle
1055de12bb7SRiver Riddle llvm::json::Object result{
1065de12bb7SRiver Riddle {{"serverInfo", llvm::json::Object{{"name", "tblgen-lsp-server"},
1075de12bb7SRiver Riddle {"version", "0.0.1"}}},
1085de12bb7SRiver Riddle {"capabilities", std::move(serverCaps)}}};
1095de12bb7SRiver Riddle reply(std::move(result));
1105de12bb7SRiver Riddle }
onInitialized(const InitializedParams &)1115de12bb7SRiver Riddle void LSPServer::onInitialized(const InitializedParams &) {}
onShutdown(const NoParams &,Callback<std::nullptr_t> reply)1125de12bb7SRiver Riddle void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
1135de12bb7SRiver Riddle shutdownRequestReceived = true;
1145de12bb7SRiver Riddle reply(nullptr);
1155de12bb7SRiver Riddle }
1165de12bb7SRiver Riddle
1175de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
1185de12bb7SRiver Riddle // Document Change
1195de12bb7SRiver Riddle
onDocumentDidOpen(const DidOpenTextDocumentParams & params)1205de12bb7SRiver Riddle void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams ¶ms) {
1215de12bb7SRiver Riddle PublishDiagnosticsParams diagParams(params.textDocument.uri,
1225de12bb7SRiver Riddle params.textDocument.version);
1236187178eSRiver Riddle server.addDocument(params.textDocument.uri, params.textDocument.text,
1246187178eSRiver Riddle params.textDocument.version, diagParams.diagnostics);
1255de12bb7SRiver Riddle
1265de12bb7SRiver Riddle // Publish any recorded diagnostics.
1275de12bb7SRiver Riddle publishDiagnostics(diagParams);
1285de12bb7SRiver Riddle }
onDocumentDidClose(const DidCloseTextDocumentParams & params)1295de12bb7SRiver Riddle void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams ¶ms) {
1300a81ace0SKazu Hirata std::optional<int64_t> version =
1310a81ace0SKazu Hirata server.removeDocument(params.textDocument.uri);
1325de12bb7SRiver Riddle if (!version)
1335de12bb7SRiver Riddle return;
1345de12bb7SRiver Riddle
1355de12bb7SRiver Riddle // Empty out the diagnostics shown for this document. This will clear out
1365de12bb7SRiver Riddle // anything currently displayed by the client for this document (e.g. in the
1375de12bb7SRiver Riddle // "Problems" pane of VSCode).
1385de12bb7SRiver Riddle publishDiagnostics(
1395de12bb7SRiver Riddle PublishDiagnosticsParams(params.textDocument.uri, *version));
1405de12bb7SRiver Riddle }
onDocumentDidChange(const DidChangeTextDocumentParams & params)1415de12bb7SRiver Riddle void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams ¶ms) {
1425de12bb7SRiver Riddle PublishDiagnosticsParams diagParams(params.textDocument.uri,
1435de12bb7SRiver Riddle params.textDocument.version);
1446187178eSRiver Riddle server.updateDocument(params.textDocument.uri, params.contentChanges,
1455de12bb7SRiver Riddle params.textDocument.version, diagParams.diagnostics);
1465de12bb7SRiver Riddle
1475de12bb7SRiver Riddle // Publish any recorded diagnostics.
1485de12bb7SRiver Riddle publishDiagnostics(diagParams);
1495de12bb7SRiver Riddle }
1505de12bb7SRiver Riddle
1515de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
1528d021670SRiver Riddle // Definitions and References
1538d021670SRiver Riddle
onGoToDefinition(const TextDocumentPositionParams & params,Callback<std::vector<Location>> reply)1548d021670SRiver Riddle void LSPServer::onGoToDefinition(const TextDocumentPositionParams ¶ms,
1558d021670SRiver Riddle Callback<std::vector<Location>> reply) {
1568d021670SRiver Riddle std::vector<Location> locations;
1578d021670SRiver Riddle server.getLocationsOf(params.textDocument.uri, params.position, locations);
1588d021670SRiver Riddle reply(std::move(locations));
1598d021670SRiver Riddle }
1608d021670SRiver Riddle
onReference(const ReferenceParams & params,Callback<std::vector<Location>> reply)1618d021670SRiver Riddle void LSPServer::onReference(const ReferenceParams ¶ms,
1628d021670SRiver Riddle Callback<std::vector<Location>> reply) {
1638d021670SRiver Riddle std::vector<Location> locations;
1648d021670SRiver Riddle server.findReferencesOf(params.textDocument.uri, params.position, locations);
1658d021670SRiver Riddle reply(std::move(locations));
1668d021670SRiver Riddle }
1678d021670SRiver Riddle
1688d021670SRiver Riddle //===----------------------------------------------------------------------===//
169682ca00eSRiver Riddle // DocumentLink
170682ca00eSRiver Riddle
onDocumentLink(const DocumentLinkParams & params,Callback<std::vector<DocumentLink>> reply)171682ca00eSRiver Riddle void LSPServer::onDocumentLink(const DocumentLinkParams ¶ms,
172682ca00eSRiver Riddle Callback<std::vector<DocumentLink>> reply) {
173682ca00eSRiver Riddle std::vector<DocumentLink> links;
174682ca00eSRiver Riddle server.getDocumentLinks(params.textDocument.uri, links);
175682ca00eSRiver Riddle reply(std::move(links));
176682ca00eSRiver Riddle }
177682ca00eSRiver Riddle
178682ca00eSRiver Riddle //===----------------------------------------------------------------------===//
179682ca00eSRiver Riddle // Hover
180682ca00eSRiver Riddle
onHover(const TextDocumentPositionParams & params,Callback<std::optional<Hover>> reply)181682ca00eSRiver Riddle void LSPServer::onHover(const TextDocumentPositionParams ¶ms,
1821da3a795SFangrui Song Callback<std::optional<Hover>> reply) {
183682ca00eSRiver Riddle reply(server.findHover(params.textDocument.uri, params.position));
184682ca00eSRiver Riddle }
185682ca00eSRiver Riddle
186682ca00eSRiver Riddle //===----------------------------------------------------------------------===//
1875de12bb7SRiver Riddle // Entry Point
1885de12bb7SRiver Riddle //===----------------------------------------------------------------------===//
1895de12bb7SRiver Riddle
runTableGenLSPServer(TableGenServer & server,JSONTransport & transport)1905de12bb7SRiver Riddle LogicalResult mlir::lsp::runTableGenLSPServer(TableGenServer &server,
1915de12bb7SRiver Riddle JSONTransport &transport) {
1925de12bb7SRiver Riddle LSPServer lspServer(server, transport);
1935de12bb7SRiver Riddle MessageHandler messageHandler(transport);
1945de12bb7SRiver Riddle
1955de12bb7SRiver Riddle // Initialization
1965de12bb7SRiver Riddle messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
1975de12bb7SRiver Riddle messageHandler.notification("initialized", &lspServer,
1985de12bb7SRiver Riddle &LSPServer::onInitialized);
1995de12bb7SRiver Riddle messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
2005de12bb7SRiver Riddle
2015de12bb7SRiver Riddle // Document Changes
2025de12bb7SRiver Riddle messageHandler.notification("textDocument/didOpen", &lspServer,
2035de12bb7SRiver Riddle &LSPServer::onDocumentDidOpen);
2045de12bb7SRiver Riddle messageHandler.notification("textDocument/didClose", &lspServer,
2055de12bb7SRiver Riddle &LSPServer::onDocumentDidClose);
2065de12bb7SRiver Riddle messageHandler.notification("textDocument/didChange", &lspServer,
2075de12bb7SRiver Riddle &LSPServer::onDocumentDidChange);
2085de12bb7SRiver Riddle
2098d021670SRiver Riddle // Definitions and References
2108d021670SRiver Riddle messageHandler.method("textDocument/definition", &lspServer,
2118d021670SRiver Riddle &LSPServer::onGoToDefinition);
2128d021670SRiver Riddle messageHandler.method("textDocument/references", &lspServer,
2138d021670SRiver Riddle &LSPServer::onReference);
2148d021670SRiver Riddle
215682ca00eSRiver Riddle // Document Link
216682ca00eSRiver Riddle messageHandler.method("textDocument/documentLink", &lspServer,
217682ca00eSRiver Riddle &LSPServer::onDocumentLink);
218682ca00eSRiver Riddle
219682ca00eSRiver Riddle // Hover
220682ca00eSRiver Riddle messageHandler.method("textDocument/hover", &lspServer, &LSPServer::onHover);
221682ca00eSRiver Riddle
2225de12bb7SRiver Riddle // Diagnostics
2235de12bb7SRiver Riddle lspServer.publishDiagnostics =
2245de12bb7SRiver Riddle messageHandler.outgoingNotification<PublishDiagnosticsParams>(
2255de12bb7SRiver Riddle "textDocument/publishDiagnostics");
2265de12bb7SRiver Riddle
2275de12bb7SRiver Riddle // Run the main loop of the transport.
2285de12bb7SRiver Riddle if (llvm::Error error = transport.run(messageHandler)) {
2295de12bb7SRiver Riddle Logger::error("Transport error: {0}", error);
2305de12bb7SRiver Riddle llvm::consumeError(std::move(error));
2315de12bb7SRiver Riddle return failure();
2325de12bb7SRiver Riddle }
2335de12bb7SRiver Riddle return success(lspServer.shutdownRequestReceived);
2345de12bb7SRiver Riddle }
235