CIRCT 21.0.0git
Loading...
Searching...
No Matches
LSPServer.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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"
11#include "mlir/Tools/lsp-server-support/Protocol.h"
12#include "mlir/Tools/lsp-server-support/Transport.h"
13#include <optional>
14
15#define DEBUG_TYPE "circt-verilog-lsp-server"
16
17using namespace mlir;
18using namespace mlir::lsp;
19
20//===----------------------------------------------------------------------===//
21// LSPServer
22//===----------------------------------------------------------------------===//
23
24namespace {
25struct LSPServer {
26 LSPServer(circt::lsp::VerilogServer &server, JSONTransport &transport)
27 : server(server), transport(transport) {}
28
29 //===--------------------------------------------------------------------===//
30 // Initialization
31 //===--------------------------------------------------------------------===//
32
33 void onInitialize(const InitializeParams &params,
34 Callback<llvm::json::Value> reply);
35 void onInitialized(const InitializedParams &params);
36 void onShutdown(const NoParams &params, Callback<std::nullptr_t> reply);
37
38 //===--------------------------------------------------------------------===//
39 // Document Change
40 //===--------------------------------------------------------------------===//
41
42 void onDocumentDidOpen(const DidOpenTextDocumentParams &params);
43 void onDocumentDidClose(const DidCloseTextDocumentParams &params);
44 void onDocumentDidChange(const DidChangeTextDocumentParams &params);
45
46 //===--------------------------------------------------------------------===//
47 // Fields
48 //===--------------------------------------------------------------------===//
49
51 JSONTransport &transport;
52
53 /// An outgoing notification used to send diagnostics to the client when they
54 /// are ready to be processed.
55 OutgoingNotification<PublishDiagnosticsParams> publishDiagnostics;
56
57 /// Used to indicate that the 'shutdown' request was received from the
58 /// Language Server client.
59 bool shutdownRequestReceived = false;
60};
61} // namespace
62
63//===----------------------------------------------------------------------===//
64// Initialization
65//===----------------------------------------------------------------------===//
66
67void LSPServer::onInitialize(const InitializeParams &params,
68 Callback<llvm::json::Value> reply) {
69 // Send a response with the capabilities of this server.
70 llvm::json::Object serverCaps{
71 {"textDocumentSync",
72 llvm::json::Object{
73 {"openClose", true},
74 {"change", (int)TextDocumentSyncKind::Incremental},
75 {"save", true},
76 }}};
77
78 llvm::json::Object result{
79 {{"serverInfo", llvm::json::Object{{"name", "circt-verilog-lsp-server"},
80 {"version", "0.0.1"}}},
81 {"capabilities", std::move(serverCaps)}}};
82 reply(std::move(result));
83}
84void LSPServer::onInitialized(const InitializedParams &) {}
85void LSPServer::onShutdown(const NoParams &, Callback<std::nullptr_t> reply) {
86 shutdownRequestReceived = true;
87 reply(nullptr);
88}
89
90//===----------------------------------------------------------------------===//
91// Document Change
92//===----------------------------------------------------------------------===//
93
94void LSPServer::onDocumentDidOpen(const DidOpenTextDocumentParams &params) {
95 PublishDiagnosticsParams diagParams(params.textDocument.uri,
96 params.textDocument.version);
97 server.addDocument(params.textDocument.uri, params.textDocument.text,
98 params.textDocument.version, diagParams.diagnostics);
99
100 // Publish any recorded diagnostics.
101 publishDiagnostics(diagParams);
102}
103
104void LSPServer::onDocumentDidClose(const DidCloseTextDocumentParams &params) {
105 std::optional<int64_t> version =
106 server.removeDocument(params.textDocument.uri);
107 if (!version)
108 return;
109
110 // Empty out the diagnostics shown for this document. This will clear out
111 // anything currently displayed by the client for this document (e.g. in the
112 // "Problems" pane of VSCode).
113 publishDiagnostics(
114 PublishDiagnosticsParams(params.textDocument.uri, *version));
115}
116
117void LSPServer::onDocumentDidChange(const DidChangeTextDocumentParams &params) {
118 PublishDiagnosticsParams diagParams(params.textDocument.uri,
119 params.textDocument.version);
120 server.updateDocument(params.textDocument.uri, params.contentChanges,
121 params.textDocument.version, diagParams.diagnostics);
122
123 // Publish any recorded diagnostics.
124 publishDiagnostics(diagParams);
125}
126
127//===----------------------------------------------------------------------===//
128// Entry Point
129//===----------------------------------------------------------------------===//
130
131LogicalResult circt::lsp::runVerilogLSPServer(VerilogServer &server,
132 JSONTransport &transport) {
133 LSPServer lspServer(server, transport);
134 MessageHandler messageHandler(transport);
135
136 // Initialization
137 messageHandler.method("initialize", &lspServer, &LSPServer::onInitialize);
138 messageHandler.notification("initialized", &lspServer,
139 &LSPServer::onInitialized);
140 messageHandler.method("shutdown", &lspServer, &LSPServer::onShutdown);
141
142 // Document Changes
143 messageHandler.notification("textDocument/didOpen", &lspServer,
144 &LSPServer::onDocumentDidOpen);
145 messageHandler.notification("textDocument/didClose", &lspServer,
146 &LSPServer::onDocumentDidClose);
147 messageHandler.notification("textDocument/didChange", &lspServer,
148 &LSPServer::onDocumentDidChange);
149
150 // Diagnostics
151 lspServer.publishDiagnostics =
152 messageHandler.outgoingNotification<PublishDiagnosticsParams>(
153 "textDocument/publishDiagnostics");
154
155 // Run the main loop of the transport.
156 if (llvm::Error error = transport.run(messageHandler)) {
157 Logger::error("Transport error: {0}", error);
158 llvm::consumeError(std::move(error));
159 return failure();
160 }
161
162 return success(lspServer.shutdownRequestReceived);
163}
static std::unique_ptr< RpcServer > server
This class implements all of the Verilog related functionality necessary for a language server.
llvm::LogicalResult runVerilogLSPServer(VerilogServer &server, mlir::lsp::JSONTransport &transport)
Run the main loop of the LSP server using the given Verilog server and transport.