152b34df9SRiver Riddle //===- LSPServer.cpp - PDLL Language Server -------------------------------===//
252b34df9SRiver Riddle //
352b34df9SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
452b34df9SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
552b34df9SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
652b34df9SRiver Riddle //
752b34df9SRiver Riddle //===----------------------------------------------------------------------===//
852b34df9SRiver Riddle
952b34df9SRiver Riddle #include "LSPServer.h"
1052b34df9SRiver Riddle
1152b34df9SRiver Riddle #include "PDLLServer.h"
1201652d88SRiver Riddle #include "Protocol.h"
13305d7185SRiver Riddle #include "mlir/Tools/lsp-server-support/Logging.h"
14305d7185SRiver Riddle #include "mlir/Tools/lsp-server-support/Transport.h"
1552b34df9SRiver Riddle #include "llvm/ADT/FunctionExtras.h"
1652b34df9SRiver Riddle #include "llvm/ADT/StringMap.h"
17a1fe1f5fSKazu Hirata #include <optional>
1852b34df9SRiver Riddle
1952b34df9SRiver Riddle #define DEBUG_TYPE "pdll-lsp-server"
2052b34df9SRiver Riddle
2152b34df9SRiver Riddle using namespace mlir;
2252b34df9SRiver Riddle using namespace mlir::lsp;
2352b34df9SRiver Riddle
2452b34df9SRiver Riddle //===----------------------------------------------------------------------===//
2552b34df9SRiver Riddle // LSPServer
2652b34df9SRiver Riddle //===----------------------------------------------------------------------===//
2752b34df9SRiver Riddle
2852b34df9SRiver Riddle namespace {
2952b34df9SRiver Riddle struct LSPServer {
LSPServer__anonf47c9d3e0111::LSPServer3052b34df9SRiver Riddle LSPServer(PDLLServer &server, JSONTransport &transport)
3152b34df9SRiver Riddle : server(server), transport(transport) {}
3252b34df9SRiver Riddle
3352b34df9SRiver Riddle //===--------------------------------------------------------------------===//
3452b34df9SRiver Riddle // Initialization
3552b34df9SRiver Riddle
3652b34df9SRiver Riddle void onInitialize(const InitializeParams ¶ms,
3752b34df9SRiver Riddle Callback<llvm::json::Value> reply);
3852b34df9SRiver Riddle void onInitialized(const InitializedParams ¶ms);
3952b34df9SRiver Riddle void onShutdown(const NoParams ¶ms, Callback<std::nullptr_t> reply);
4052b34df9SRiver Riddle
4152b34df9SRiver Riddle //===--------------------------------------------------------------------===//
4252b34df9SRiver Riddle // Document Change
4352b34df9SRiver Riddle
4452b34df9SRiver Riddle void onDocumentDidOpen(const DidOpenTextDocumentParams ¶ms);
4552b34df9SRiver Riddle void onDocumentDidClose(const DidCloseTextDocumentParams ¶ms);
4652b34df9SRiver Riddle void onDocumentDidChange(const DidChangeTextDocumentParams ¶ms);
4752b34df9SRiver Riddle
4852b34df9SRiver Riddle //===--------------------------------------------------------------------===//
4952b34df9SRiver Riddle // Definitions and References
5052b34df9SRiver Riddle
5152b34df9SRiver Riddle void onGoToDefinition(const TextDocumentPositionParams ¶ms,
5252b34df9SRiver Riddle Callback<std::vector<Location>> reply);
5352b34df9SRiver Riddle void onReference(const ReferenceParams ¶ms,
5452b34df9SRiver Riddle Callback<std::vector<Location>> reply);
5552b34df9SRiver Riddle
5609af7fefSRiver Riddle //===----------------------------------------------------------------------===//
5709af7fefSRiver Riddle // DocumentLink
5809af7fefSRiver Riddle
5909af7fefSRiver Riddle void onDocumentLink(const DocumentLinkParams ¶ms,
6009af7fefSRiver Riddle Callback<std::vector<DocumentLink>> reply);
6109af7fefSRiver Riddle
6252b34df9SRiver Riddle //===--------------------------------------------------------------------===//
6341ae2114SRiver Riddle // Hover
6441ae2114SRiver Riddle
6541ae2114SRiver Riddle void onHover(const TextDocumentPositionParams ¶ms,
661da3a795SFangrui Song Callback<std::optional<Hover>> reply);
6741ae2114SRiver Riddle
6841ae2114SRiver Riddle //===--------------------------------------------------------------------===//
698dd4272cSRiver Riddle // Document Symbols
708dd4272cSRiver Riddle
718dd4272cSRiver Riddle void onDocumentSymbol(const DocumentSymbolParams ¶ms,
728dd4272cSRiver Riddle Callback<std::vector<DocumentSymbol>> reply);
738dd4272cSRiver Riddle
748dd4272cSRiver Riddle //===--------------------------------------------------------------------===//
75008de486SRiver Riddle // Code Completion
76008de486SRiver Riddle
77008de486SRiver Riddle void onCompletion(const CompletionParams ¶ms,
78008de486SRiver Riddle Callback<CompletionList> reply);
79008de486SRiver Riddle
80008de486SRiver Riddle //===--------------------------------------------------------------------===//
81469c5894SRiver Riddle // Signature Help
82469c5894SRiver Riddle
83469c5894SRiver Riddle void onSignatureHelp(const TextDocumentPositionParams ¶ms,
84469c5894SRiver Riddle Callback<SignatureHelp> reply);
85469c5894SRiver Riddle
86469c5894SRiver Riddle //===--------------------------------------------------------------------===//
875919eab5SRiver Riddle // Inlay Hints
885919eab5SRiver Riddle
895919eab5SRiver Riddle void onInlayHint(const InlayHintsParams ¶ms,
905919eab5SRiver Riddle Callback<std::vector<InlayHint>> reply);
915919eab5SRiver Riddle
925919eab5SRiver Riddle //===--------------------------------------------------------------------===//
9301652d88SRiver Riddle // PDLL View Output
9401652d88SRiver Riddle
9501652d88SRiver Riddle void onPDLLViewOutput(const PDLLViewOutputParams ¶ms,
961da3a795SFangrui Song Callback<std::optional<PDLLViewOutputResult>> reply);
9701652d88SRiver Riddle
9801652d88SRiver Riddle //===--------------------------------------------------------------------===//
9952b34df9SRiver Riddle // Fields
10052b34df9SRiver Riddle //===--------------------------------------------------------------------===//
10152b34df9SRiver Riddle
10252b34df9SRiver Riddle PDLLServer &server;
10352b34df9SRiver Riddle JSONTransport &transport;
10452b34df9SRiver Riddle
10552b34df9SRiver Riddle /// An outgoing notification used to send diagnostics to the client when they
10652b34df9SRiver Riddle /// are ready to be processed.
107*a8c88de0SBrian Gesiak OutgoingNotification<PublishDiagnosticsParams> publishDiagnostics;
10852b34df9SRiver Riddle
10952b34df9SRiver Riddle /// Used to indicate that the 'shutdown' request was received from the
11052b34df9SRiver Riddle /// Language Server client.
11152b34df9SRiver Riddle bool shutdownRequestReceived = false;
11252b34df9SRiver Riddle };
11352b34df9SRiver Riddle } // namespace
11452b34df9SRiver Riddle
11552b34df9SRiver Riddle //===----------------------------------------------------------------------===//
11652b34df9SRiver Riddle // Initialization
11752b34df9SRiver Riddle
onInitialize(const InitializeParams & params,Callback<llvm::json::Value> reply)11852b34df9SRiver Riddle void LSPServer::onInitialize(const InitializeParams ¶ms,
11952b34df9SRiver Riddle Callback<llvm::json::Value> reply) {
12052b34df9SRiver Riddle // Send a response with the capabilities of this server.
12152b34df9SRiver Riddle llvm::json::Object serverCaps{
12252b34df9SRiver Riddle {"textDocumentSync",
12352b34df9SRiver Riddle llvm::json::Object{
12452b34df9SRiver Riddle {"openClose", true},
1256187178eSRiver Riddle {"change", (int)TextDocumentSyncKind::Incremental},
12652b34df9SRiver Riddle {"save", true},
12752b34df9SRiver Riddle }},
128008de486SRiver Riddle {"completionProvider",
129008de486SRiver Riddle llvm::json::Object{
130008de486SRiver Riddle {"allCommitCharacters",
131e213e5a9SRiver Riddle {"\t", "(", ")", "[", "]", "{", "}", "<", ">",
132e213e5a9SRiver Riddle ":", ";", ",", "+", "-", "/", "*", "%", "^",
133e213e5a9SRiver Riddle "&", "#", "?", ".", "=", "\"", "'", "|"}},
134008de486SRiver Riddle {"resolveProvider", false},
13541d2c6dfSRiver Riddle {"triggerCharacters",
13641d2c6dfSRiver Riddle {".", ">", "(", "{", ",", "<", ":", "[", " ", "\"", "/"}},
137008de486SRiver Riddle }},
138469c5894SRiver Riddle {"signatureHelpProvider",
139469c5894SRiver Riddle llvm::json::Object{
140469c5894SRiver Riddle {"triggerCharacters", {"(", ","}},
141469c5894SRiver Riddle }},
14252b34df9SRiver Riddle {"definitionProvider", true},
14352b34df9SRiver Riddle {"referencesProvider", true},
14409af7fefSRiver Riddle {"documentLinkProvider",
14509af7fefSRiver Riddle llvm::json::Object{
14609af7fefSRiver Riddle {"resolveProvider", false},
14709af7fefSRiver Riddle }},
14841ae2114SRiver Riddle {"hoverProvider", true},
1498dd4272cSRiver Riddle {"documentSymbolProvider", true},
1505919eab5SRiver Riddle {"inlayHintProvider", true},
15152b34df9SRiver Riddle };
15252b34df9SRiver Riddle
15352b34df9SRiver Riddle llvm::json::Object result{
15452b34df9SRiver Riddle {{"serverInfo", llvm::json::Object{{"name", "mlir-pdll-lsp-server"},
15552b34df9SRiver Riddle {"version", "0.0.1"}}},
15652b34df9SRiver Riddle {"capabilities", std::move(serverCaps)}}};
15752b34df9SRiver Riddle reply(std::move(result));
15852b34df9SRiver Riddle }
onInitialized(const InitializedParams &)15952b34df9SRiver Riddle void LSPServer::onInitialized(const InitializedParams &) {}
onShutdown(const NoParams &,Callback<std::nullptr_t> reply)16052b34df9SRiver Riddle void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
16152b34df9SRiver Riddle shutdownRequestReceived = true;
16252b34df9SRiver Riddle reply(nullptr);
16352b34df9SRiver Riddle }
16452b34df9SRiver Riddle
16552b34df9SRiver Riddle //===----------------------------------------------------------------------===//
16652b34df9SRiver Riddle // Document Change
16752b34df9SRiver Riddle
onDocumentDidOpen(const DidOpenTextDocumentParams & params)16852b34df9SRiver Riddle void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams ¶ms) {
16952b34df9SRiver Riddle PublishDiagnosticsParams diagParams(params.textDocument.uri,
17052b34df9SRiver Riddle params.textDocument.version);
1716187178eSRiver Riddle server.addDocument(params.textDocument.uri, params.textDocument.text,
1726187178eSRiver Riddle params.textDocument.version, diagParams.diagnostics);
17352b34df9SRiver Riddle
17452b34df9SRiver Riddle // Publish any recorded diagnostics.
17552b34df9SRiver Riddle publishDiagnostics(diagParams);
17652b34df9SRiver Riddle }
onDocumentDidClose(const DidCloseTextDocumentParams & params)17752b34df9SRiver Riddle void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams ¶ms) {
1780a81ace0SKazu Hirata std::optional<int64_t> version =
1790a81ace0SKazu Hirata server.removeDocument(params.textDocument.uri);
18052b34df9SRiver Riddle if (!version)
18152b34df9SRiver Riddle return;
18252b34df9SRiver Riddle
18352b34df9SRiver Riddle // Empty out the diagnostics shown for this document. This will clear out
18452b34df9SRiver Riddle // anything currently displayed by the client for this document (e.g. in the
18552b34df9SRiver Riddle // "Problems" pane of VSCode).
18652b34df9SRiver Riddle publishDiagnostics(
18752b34df9SRiver Riddle PublishDiagnosticsParams(params.textDocument.uri, *version));
18852b34df9SRiver Riddle }
onDocumentDidChange(const DidChangeTextDocumentParams & params)18952b34df9SRiver Riddle void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams ¶ms) {
19052b34df9SRiver Riddle PublishDiagnosticsParams diagParams(params.textDocument.uri,
19152b34df9SRiver Riddle params.textDocument.version);
1926187178eSRiver Riddle server.updateDocument(params.textDocument.uri, params.contentChanges,
19352b34df9SRiver Riddle params.textDocument.version, diagParams.diagnostics);
19452b34df9SRiver Riddle
19552b34df9SRiver Riddle // Publish any recorded diagnostics.
19652b34df9SRiver Riddle publishDiagnostics(diagParams);
19752b34df9SRiver Riddle }
19852b34df9SRiver Riddle
19952b34df9SRiver Riddle //===----------------------------------------------------------------------===//
20052b34df9SRiver Riddle // Definitions and References
20152b34df9SRiver Riddle
onGoToDefinition(const TextDocumentPositionParams & params,Callback<std::vector<Location>> reply)20252b34df9SRiver Riddle void LSPServer::onGoToDefinition(const TextDocumentPositionParams ¶ms,
20352b34df9SRiver Riddle Callback<std::vector<Location>> reply) {
20452b34df9SRiver Riddle std::vector<Location> locations;
20552b34df9SRiver Riddle server.getLocationsOf(params.textDocument.uri, params.position, locations);
20652b34df9SRiver Riddle reply(std::move(locations));
20752b34df9SRiver Riddle }
20852b34df9SRiver Riddle
onReference(const ReferenceParams & params,Callback<std::vector<Location>> reply)20952b34df9SRiver Riddle void LSPServer::onReference(const ReferenceParams ¶ms,
21052b34df9SRiver Riddle Callback<std::vector<Location>> reply) {
21152b34df9SRiver Riddle std::vector<Location> locations;
21252b34df9SRiver Riddle server.findReferencesOf(params.textDocument.uri, params.position, locations);
21352b34df9SRiver Riddle reply(std::move(locations));
21452b34df9SRiver Riddle }
21552b34df9SRiver Riddle
21652b34df9SRiver Riddle //===----------------------------------------------------------------------===//
21709af7fefSRiver Riddle // DocumentLink
21809af7fefSRiver Riddle
onDocumentLink(const DocumentLinkParams & params,Callback<std::vector<DocumentLink>> reply)21909af7fefSRiver Riddle void LSPServer::onDocumentLink(const DocumentLinkParams ¶ms,
22009af7fefSRiver Riddle Callback<std::vector<DocumentLink>> reply) {
22109af7fefSRiver Riddle std::vector<DocumentLink> links;
22209af7fefSRiver Riddle server.getDocumentLinks(params.textDocument.uri, links);
22309af7fefSRiver Riddle reply(std::move(links));
22409af7fefSRiver Riddle }
22509af7fefSRiver Riddle
22609af7fefSRiver Riddle //===----------------------------------------------------------------------===//
22741ae2114SRiver Riddle // Hover
22841ae2114SRiver Riddle
onHover(const TextDocumentPositionParams & params,Callback<std::optional<Hover>> reply)22941ae2114SRiver Riddle void LSPServer::onHover(const TextDocumentPositionParams ¶ms,
2301da3a795SFangrui Song Callback<std::optional<Hover>> reply) {
23141ae2114SRiver Riddle reply(server.findHover(params.textDocument.uri, params.position));
23241ae2114SRiver Riddle }
23341ae2114SRiver Riddle
23441ae2114SRiver Riddle //===----------------------------------------------------------------------===//
2358dd4272cSRiver Riddle // Document Symbols
2368dd4272cSRiver Riddle
onDocumentSymbol(const DocumentSymbolParams & params,Callback<std::vector<DocumentSymbol>> reply)2378dd4272cSRiver Riddle void LSPServer::onDocumentSymbol(const DocumentSymbolParams ¶ms,
2388dd4272cSRiver Riddle Callback<std::vector<DocumentSymbol>> reply) {
2398dd4272cSRiver Riddle std::vector<DocumentSymbol> symbols;
2408dd4272cSRiver Riddle server.findDocumentSymbols(params.textDocument.uri, symbols);
2418dd4272cSRiver Riddle reply(std::move(symbols));
2428dd4272cSRiver Riddle }
2438dd4272cSRiver Riddle
2448dd4272cSRiver Riddle //===----------------------------------------------------------------------===//
245008de486SRiver Riddle // Code Completion
246008de486SRiver Riddle
onCompletion(const CompletionParams & params,Callback<CompletionList> reply)247008de486SRiver Riddle void LSPServer::onCompletion(const CompletionParams ¶ms,
248008de486SRiver Riddle Callback<CompletionList> reply) {
249008de486SRiver Riddle reply(server.getCodeCompletion(params.textDocument.uri, params.position));
250008de486SRiver Riddle }
251008de486SRiver Riddle
252008de486SRiver Riddle //===----------------------------------------------------------------------===//
253469c5894SRiver Riddle // Signature Help
254469c5894SRiver Riddle
onSignatureHelp(const TextDocumentPositionParams & params,Callback<SignatureHelp> reply)255469c5894SRiver Riddle void LSPServer::onSignatureHelp(const TextDocumentPositionParams ¶ms,
256469c5894SRiver Riddle Callback<SignatureHelp> reply) {
257469c5894SRiver Riddle reply(server.getSignatureHelp(params.textDocument.uri, params.position));
258469c5894SRiver Riddle }
259469c5894SRiver Riddle
260469c5894SRiver Riddle //===----------------------------------------------------------------------===//
2615919eab5SRiver Riddle // Inlay Hints
2625919eab5SRiver Riddle
onInlayHint(const InlayHintsParams & params,Callback<std::vector<InlayHint>> reply)2635919eab5SRiver Riddle void LSPServer::onInlayHint(const InlayHintsParams ¶ms,
2645919eab5SRiver Riddle Callback<std::vector<InlayHint>> reply) {
2655919eab5SRiver Riddle std::vector<InlayHint> hints;
2665919eab5SRiver Riddle server.getInlayHints(params.textDocument.uri, params.range, hints);
2675919eab5SRiver Riddle reply(std::move(hints));
2685919eab5SRiver Riddle }
2695919eab5SRiver Riddle
2705919eab5SRiver Riddle //===----------------------------------------------------------------------===//
27101652d88SRiver Riddle // PDLL ViewOutput
27201652d88SRiver Riddle
onPDLLViewOutput(const PDLLViewOutputParams & params,Callback<std::optional<PDLLViewOutputResult>> reply)27301652d88SRiver Riddle void LSPServer::onPDLLViewOutput(
27401652d88SRiver Riddle const PDLLViewOutputParams ¶ms,
2751da3a795SFangrui Song Callback<std::optional<PDLLViewOutputResult>> reply) {
27601652d88SRiver Riddle reply(server.getPDLLViewOutput(params.uri, params.kind));
27701652d88SRiver Riddle }
27801652d88SRiver Riddle
27901652d88SRiver Riddle //===----------------------------------------------------------------------===//
28052b34df9SRiver Riddle // Entry Point
28152b34df9SRiver Riddle //===----------------------------------------------------------------------===//
28252b34df9SRiver Riddle
runPdllLSPServer(PDLLServer & server,JSONTransport & transport)28352b34df9SRiver Riddle LogicalResult mlir::lsp::runPdllLSPServer(PDLLServer &server,
28452b34df9SRiver Riddle JSONTransport &transport) {
28552b34df9SRiver Riddle LSPServer lspServer(server, transport);
28652b34df9SRiver Riddle MessageHandler messageHandler(transport);
28752b34df9SRiver Riddle
28852b34df9SRiver Riddle // Initialization
28952b34df9SRiver Riddle messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
29052b34df9SRiver Riddle messageHandler.notification("initialized", &lspServer,
29152b34df9SRiver Riddle &LSPServer::onInitialized);
29252b34df9SRiver Riddle messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
29352b34df9SRiver Riddle
29452b34df9SRiver Riddle // Document Changes
29552b34df9SRiver Riddle messageHandler.notification("textDocument/didOpen", &lspServer,
29652b34df9SRiver Riddle &LSPServer::onDocumentDidOpen);
29752b34df9SRiver Riddle messageHandler.notification("textDocument/didClose", &lspServer,
29852b34df9SRiver Riddle &LSPServer::onDocumentDidClose);
29952b34df9SRiver Riddle messageHandler.notification("textDocument/didChange", &lspServer,
30052b34df9SRiver Riddle &LSPServer::onDocumentDidChange);
30152b34df9SRiver Riddle
30252b34df9SRiver Riddle // Definitions and References
30352b34df9SRiver Riddle messageHandler.method("textDocument/definition", &lspServer,
30452b34df9SRiver Riddle &LSPServer::onGoToDefinition);
30552b34df9SRiver Riddle messageHandler.method("textDocument/references", &lspServer,
30652b34df9SRiver Riddle &LSPServer::onReference);
30752b34df9SRiver Riddle
30809af7fefSRiver Riddle // Document Link
30909af7fefSRiver Riddle messageHandler.method("textDocument/documentLink", &lspServer,
31009af7fefSRiver Riddle &LSPServer::onDocumentLink);
31109af7fefSRiver Riddle
31241ae2114SRiver Riddle // Hover
31341ae2114SRiver Riddle messageHandler.method("textDocument/hover", &lspServer, &LSPServer::onHover);
31441ae2114SRiver Riddle
3158dd4272cSRiver Riddle // Document Symbols
3168dd4272cSRiver Riddle messageHandler.method("textDocument/documentSymbol", &lspServer,
3178dd4272cSRiver Riddle &LSPServer::onDocumentSymbol);
3188dd4272cSRiver Riddle
319008de486SRiver Riddle // Code Completion
320008de486SRiver Riddle messageHandler.method("textDocument/completion", &lspServer,
321008de486SRiver Riddle &LSPServer::onCompletion);
322008de486SRiver Riddle
323469c5894SRiver Riddle // Signature Help
324469c5894SRiver Riddle messageHandler.method("textDocument/signatureHelp", &lspServer,
325469c5894SRiver Riddle &LSPServer::onSignatureHelp);
326469c5894SRiver Riddle
3275919eab5SRiver Riddle // Inlay Hints
3285919eab5SRiver Riddle messageHandler.method("textDocument/inlayHint", &lspServer,
3295919eab5SRiver Riddle &LSPServer::onInlayHint);
3305919eab5SRiver Riddle
33101652d88SRiver Riddle // PDLL ViewOutput
33201652d88SRiver Riddle messageHandler.method("pdll/viewOutput", &lspServer,
33301652d88SRiver Riddle &LSPServer::onPDLLViewOutput);
33401652d88SRiver Riddle
33552b34df9SRiver Riddle // Diagnostics
33652b34df9SRiver Riddle lspServer.publishDiagnostics =
33752b34df9SRiver Riddle messageHandler.outgoingNotification<PublishDiagnosticsParams>(
33852b34df9SRiver Riddle "textDocument/publishDiagnostics");
33952b34df9SRiver Riddle
34052b34df9SRiver Riddle // Run the main loop of the transport.
34152b34df9SRiver Riddle if (llvm::Error error = transport.run(messageHandler)) {
34252b34df9SRiver Riddle Logger::error("Transport error: {0}", error);
34352b34df9SRiver Riddle llvm::consumeError(std::move(error));
34452b34df9SRiver Riddle return failure();
34552b34df9SRiver Riddle }
34652b34df9SRiver Riddle return success(lspServer.shutdownRequestReceived);
34752b34df9SRiver Riddle }
348