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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of mlir/lib/Tools/mlir-pdll-lsp-server/LSPServer.cpp