[Mlir-commits] [llvm] [mlir] [LLVM][MLIR] Move LSP server support library from MLIR into LLVM (PR #155572)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Aug 27 01:37:20 PDT 2025
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/155572 at github.com>
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Bertik23 (Bertik23)
<details>
<summary>Changes</summary>
This PR moves the generic Language Server Protocol (LSP) server support code that was copied from clangd into MLIR, into the LLVM tree so it can be reused by multiple subprojects.
Centralizing the generic LSP support in LLVM lowers the barrier to building new LSP servers across the LLVM ecosystem and avoids each subproject maintaining its own copy.
The code originated in clangd and was copied into MLIR for its LSP server. MLIR had this code seperate to be reused by all of their LSP server. This PR relocates the MLIR copy into LLVM as a shared component into `LLVM/Support`. If this is not a suitable place, please suggest a better one.
A follow up to this move could be deduplication with the original clangd implementation and converge on a single shared LSP support library used by clangd, MLIR, and future servers.
### What changes
* `mlir/include/mlir/Tools/lsp-server-support/{Logging, Protocol, Transport}.h` moved to `llvm/include/llvm/Support/LSP`
* `mlir/lib/Tools/lsp-server-support/{Logging, Protocol, Transport}.cpp` moved to `llvm/lib/Support/LSP`
and their namespace was changed from `mlir` to `llvm`
I ran clang-tidy --fix and clang-format on the whole moved files (last two commits), as they are basically new files and should hold up to the code style used by LLVM.
MLIR LSP servers where updated to include these files from their new location and account for the namespace change.
This PR is made as part of the LLVM IR LSP project ([RFC](https://discourse.llvm.org/t/rfc-ir-visualization-with-vs-code-extension-using-an-lsp-server/87773))
---
Patch is 159.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155572.diff
42 Files Affected:
- (renamed) llvm/include/llvm/Support/LSP/Logging.h (+16-20)
- (renamed) llvm/include/llvm/Support/LSP/Protocol.h (+14-9)
- (added) llvm/include/llvm/Support/LSP/Transport.h (+289)
- (modified) llvm/lib/Support/CMakeLists.txt (+2)
- (added) llvm/lib/Support/LSP/CMakeLists.txt (+17)
- (renamed) llvm/lib/Support/LSP/Logging.cpp (+14-14)
- (added) llvm/lib/Support/LSP/Protocol.cpp (+1043)
- (added) llvm/lib/Support/LSP/Transport.cpp (+369)
- (modified) llvm/unittests/Support/CMakeLists.txt (+2)
- (added) llvm/unittests/Support/LSP/CMakeLists.txt (+7)
- (renamed) llvm/unittests/Support/LSP/Protocol.cpp (+3-3)
- (renamed) llvm/unittests/Support/LSP/Transport.cpp (+6-6)
- (modified) mlir/include/mlir/Tools/lsp-server-support/SourceMgrUtils.h (+3-1)
- (removed) mlir/include/mlir/Tools/lsp-server-support/Transport.h (-283)
- (modified) mlir/include/mlir/Tools/mlir-lsp-server/MlirLspRegistryFunction.h (+4-2)
- (modified) mlir/lib/Tools/lsp-server-support/CMakeLists.txt (-3)
- (modified) mlir/lib/Tools/lsp-server-support/CompilationDatabase.cpp (+3-2)
- (removed) mlir/lib/Tools/lsp-server-support/Protocol.cpp (-1043)
- (removed) mlir/lib/Tools/lsp-server-support/Transport.cpp (-369)
- (modified) mlir/lib/Tools/mlir-lsp-server/LSPServer.cpp (+3-2)
- (modified) mlir/lib/Tools/mlir-lsp-server/LSPServer.h (+4-2)
- (modified) mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp (+12-12)
- (modified) mlir/lib/Tools/mlir-lsp-server/MLIRServer.h (+2-10)
- (modified) mlir/lib/Tools/mlir-lsp-server/MlirLspServerMain.cpp (+2-2)
- (modified) mlir/lib/Tools/mlir-lsp-server/Protocol.cpp (+4-4)
- (modified) mlir/lib/Tools/mlir-lsp-server/Protocol.h (+3-3)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/LSPServer.cpp (+2-2)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/LSPServer.h (+4-2)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/MlirPdllLspServerMain.cpp (+4-3)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.cpp (+11-11)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/PDLLServer.h (+2-12)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/Protocol.cpp (+1)
- (modified) mlir/lib/Tools/mlir-pdll-lsp-server/Protocol.h (+2-1)
- (modified) mlir/lib/Tools/tblgen-lsp-server/LSPServer.cpp (+4-3)
- (modified) mlir/lib/Tools/tblgen-lsp-server/LSPServer.h (+4-2)
- (modified) mlir/lib/Tools/tblgen-lsp-server/TableGenLspServerMain.cpp (+2-2)
- (modified) mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp (+2-2)
- (modified) mlir/lib/Tools/tblgen-lsp-server/TableGenServer.h (+2-7)
- (modified) mlir/tools/mlir-lsp-server/mlir-lsp-server.cpp (+3-3)
- (modified) mlir/unittests/CMakeLists.txt (-1)
- (removed) mlir/unittests/Tools/CMakeLists.txt (-1)
- (removed) mlir/unittests/Tools/lsp-server-support/CMakeLists.txt (-7)
``````````diff
diff --git a/mlir/include/mlir/Tools/lsp-server-support/Logging.h b/llvm/include/llvm/Support/LSP/Logging.h
similarity index 59%
rename from mlir/include/mlir/Tools/lsp-server-support/Logging.h
rename to llvm/include/llvm/Support/LSP/Logging.h
index 9b090d05f7fa4..d1ecf113a5123 100644
--- a/mlir/include/mlir/Tools/lsp-server-support/Logging.h
+++ b/llvm/include/llvm/Support/LSP/Logging.h
@@ -6,16 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MLIR_TOOLS_LSPSERVERSUPPORT_LOGGING_H
-#define MLIR_TOOLS_LSPSERVERSUPPORT_LOGGING_H
+#ifndef LLVM_SUPPORT_LSP_LOGGING_H
+#define LLVM_SUPPORT_LSP_LOGGING_H
-#include "mlir/Support/LLVM.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormatVariadic.h"
#include <memory>
#include <mutex>
-namespace mlir {
+namespace llvm {
namespace lsp {
/// This class represents the main interface for logging, and allows for
@@ -26,21 +25,18 @@ class Logger {
enum class Level { Debug, Info, Error };
/// Set the severity level of the logger.
- static void setLogLevel(Level logLevel);
+ static void setLogLevel(Level LogLevel);
/// Initiate a log message at various severity levels. These should be called
/// after a call to `initialize`.
- template <typename... Ts>
- static void debug(const char *fmt, Ts &&...vals) {
- log(Level::Debug, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ template <typename... Ts> static void debug(const char *Fmt, Ts &&...Vals) {
+ log(Level::Debug, Fmt, llvm::formatv(Fmt, std::forward<Ts>(Vals)...));
}
- template <typename... Ts>
- static void info(const char *fmt, Ts &&...vals) {
- log(Level::Info, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ template <typename... Ts> static void info(const char *Fmt, Ts &&...Vals) {
+ log(Level::Info, Fmt, llvm::formatv(Fmt, std::forward<Ts>(Vals)...));
}
- template <typename... Ts>
- static void error(const char *fmt, Ts &&...vals) {
- log(Level::Error, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ template <typename... Ts> static void error(const char *Fmt, Ts &&...Vals) {
+ log(Level::Error, Fmt, llvm::formatv(Fmt, std::forward<Ts>(Vals)...));
}
private:
@@ -50,16 +46,16 @@ class Logger {
static Logger &get();
/// Start a log message with the given severity level.
- static void log(Level logLevel, const char *fmt,
- const llvm::formatv_object_base &message);
+ static void log(Level LogLevel, const char *Fmt,
+ const llvm::formatv_object_base &Message);
/// The minimum logging level. Messages with lower level are ignored.
- Level logLevel = Level::Error;
+ Level LogLevel = Level::Error;
/// A mutex used to guard logging.
- std::mutex mutex;
+ std::mutex Mutex;
};
} // namespace lsp
-} // namespace mlir
+} // namespace llvm
-#endif // MLIR_TOOLS_LSPSERVERSUPPORT_LOGGING_H
+#endif // LLVM_SUPPORT_LSP_LOGGING_H
diff --git a/mlir/include/mlir/Tools/lsp-server-support/Protocol.h b/llvm/include/llvm/Support/LSP/Protocol.h
similarity index 98%
rename from mlir/include/mlir/Tools/lsp-server-support/Protocol.h
rename to llvm/include/llvm/Support/LSP/Protocol.h
index cc06dbfedb42a..93b82f1e581f8 100644
--- a/mlir/include/mlir/Tools/lsp-server-support/Protocol.h
+++ b/llvm/include/llvm/Support/LSP/Protocol.h
@@ -20,20 +20,24 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MLIR_TOOLS_LSPSERVERSUPPORT_PROTOCOL_H
-#define MLIR_TOOLS_LSPSERVERSUPPORT_PROTOCOL_H
+#ifndef LLVM_SUPPORT_LSP_PROTOCOL_H
+#define LLVM_SUPPORT_LSP_PROTOCOL_H
-#include "mlir/Support/LLVM.h"
#include "llvm/Support/JSON.h"
+#include "llvm/Support/LogicalResult.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <bitset>
#include <optional>
#include <string>
#include <utility>
-#include <vector>
-namespace mlir {
+// This file is using the LSP syntax for identifier names which is different
+// from the LLVM coding standard. To avoid the clang-tidy warnings, we're
+// disabling one check here.
+// NOLINTBEGIN(readability-identifier-naming)
+
+namespace llvm {
namespace lsp {
enum class ErrorCode {
@@ -1241,12 +1245,11 @@ struct CodeAction {
llvm::json::Value toJSON(const CodeAction &);
} // namespace lsp
-} // namespace mlir
+} // namespace llvm
namespace llvm {
-template <>
-struct format_provider<mlir::lsp::Position> {
- static void format(const mlir::lsp::Position &pos, raw_ostream &os,
+template <> struct format_provider<llvm::lsp::Position> {
+ static void format(const llvm::lsp::Position &pos, raw_ostream &os,
StringRef style) {
assert(style.empty() && "style modifiers for this type are not supported");
os << pos;
@@ -1255,3 +1258,5 @@ struct format_provider<mlir::lsp::Position> {
} // namespace llvm
#endif
+
+// NOLINTEND(readability-identifier-naming)
diff --git a/llvm/include/llvm/Support/LSP/Transport.h b/llvm/include/llvm/Support/LSP/Transport.h
new file mode 100644
index 0000000000000..ccd7f213aa277
--- /dev/null
+++ b/llvm/include/llvm/Support/LSP/Transport.h
@@ -0,0 +1,289 @@
+//===--- Transport.h - Sending and Receiving LSP messages -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The language server protocol is usually implemented by writing messages as
+// JSON-RPC over the stdin/stdout of a subprocess. This file contains a JSON
+// transport interface that handles this communication.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LSP_TRANSPORT_H
+#define LLVM_SUPPORT_LSP_TRANSPORT_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/LSP/Logging.h"
+#include "llvm/Support/LSP/Protocol.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+namespace llvm {
+// Simple helper function that returns a string as printed from a op.
+template <typename T> static std::string debugString(T &&Op) {
+ std::string InstrStr;
+ llvm::raw_string_ostream Os(InstrStr);
+ Os << Op;
+ return Os.str();
+}
+namespace lsp {
+class MessageHandler;
+
+//===----------------------------------------------------------------------===//
+// JSONTransport
+//===----------------------------------------------------------------------===//
+
+/// The encoding style of the JSON-RPC messages (both input and output).
+enum JSONStreamStyle {
+ /// Encoding per the LSP specification, with mandatory Content-Length header.
+ Standard,
+ /// Messages are delimited by a '// -----' line. Comment lines start with //.
+ Delimited
+};
+
+/// An abstract class used by the JSONTransport to read JSON message.
+class JSONTransportInput {
+public:
+ explicit JSONTransportInput(JSONStreamStyle Style = JSONStreamStyle::Standard)
+ : Style(Style) {}
+ virtual ~JSONTransportInput() = default;
+
+ virtual bool hasError() const = 0;
+ virtual bool isEndOfInput() const = 0;
+
+ /// Read in a message from the input stream.
+ LogicalResult readMessage(std::string &Json) {
+ return Style == JSONStreamStyle::Delimited ? readDelimitedMessage(Json)
+ : readStandardMessage(Json);
+ }
+ virtual LogicalResult readDelimitedMessage(std::string &Json) = 0;
+ virtual LogicalResult readStandardMessage(std::string &Json) = 0;
+
+private:
+ /// The JSON stream style to use.
+ JSONStreamStyle Style;
+};
+
+/// Concrete implementation of the JSONTransportInput that reads from a file.
+class JSONTransportInputOverFile : public JSONTransportInput {
+public:
+ explicit JSONTransportInputOverFile(
+ std::FILE *In, JSONStreamStyle Style = JSONStreamStyle::Standard)
+ : JSONTransportInput(Style), In(In) {}
+
+ bool hasError() const final { return ferror(In); }
+ bool isEndOfInput() const final { return feof(In); }
+
+ LogicalResult readDelimitedMessage(std::string &Json) final;
+ LogicalResult readStandardMessage(std::string &Json) final;
+
+private:
+ std::FILE *In;
+};
+
+/// A transport class that performs the JSON-RPC communication with the LSP
+/// client.
+class JSONTransport {
+public:
+ JSONTransport(std::unique_ptr<JSONTransportInput> In, raw_ostream &Out,
+ bool PrettyOutput = false)
+ : In(std::move(In)), Out(Out), PrettyOutput(PrettyOutput) {}
+
+ JSONTransport(std::FILE *In, raw_ostream &Out,
+ JSONStreamStyle Style = JSONStreamStyle::Standard,
+ bool PrettyOutput = false)
+ : In(std::make_unique<JSONTransportInputOverFile>(In, Style)), Out(Out),
+ PrettyOutput(PrettyOutput) {}
+
+ /// The following methods are used to send a message to the LSP client.
+ void notify(StringRef Method, llvm::json::Value Params);
+ void call(StringRef Method, llvm::json::Value Params, llvm::json::Value Id);
+ void reply(llvm::json::Value Id, llvm::Expected<llvm::json::Value> Result);
+
+ /// Start executing the JSON-RPC transport.
+ llvm::Error run(MessageHandler &Handler);
+
+private:
+ /// Dispatches the given incoming json message to the message handler.
+ bool handleMessage(llvm::json::Value Msg, MessageHandler &Handler);
+ /// Writes the given message to the output stream.
+ void sendMessage(llvm::json::Value Msg);
+
+private:
+ /// The input to read a message from.
+ std::unique_ptr<JSONTransportInput> In;
+ SmallVector<char, 0> OutputBuffer;
+ /// The output file stream.
+ raw_ostream &Out;
+ /// If the output JSON should be formatted for easier readability.
+ bool PrettyOutput;
+};
+
+//===----------------------------------------------------------------------===//
+// MessageHandler
+//===----------------------------------------------------------------------===//
+
+/// A Callback<T> is a void function that accepts Expected<T>. This is
+/// accepted by functions that logically return T.
+template <typename T>
+using Callback = llvm::unique_function<void(llvm::Expected<T>)>;
+
+/// An OutgoingNotification<T> is a function used for outgoing notifications
+/// send to the client.
+template <typename T>
+using OutgoingNotification = llvm::unique_function<void(const T &)>;
+
+/// An OutgoingRequest<T> is a function used for outgoing requests to send to
+/// the client.
+template <typename T>
+using OutgoingRequest =
+ llvm::unique_function<void(const T &, llvm::json::Value Id)>;
+
+/// An `OutgoingRequestCallback` is invoked when an outgoing request to the
+/// client receives a response in turn. It is passed the original request's ID,
+/// as well as the response result.
+template <typename T>
+using OutgoingRequestCallback =
+ std::function<void(llvm::json::Value, llvm::Expected<T>)>;
+
+/// A handler used to process the incoming transport messages.
+class MessageHandler {
+public:
+ MessageHandler(JSONTransport &Transport) : Transport(Transport) {}
+
+ bool onNotify(StringRef Method, llvm::json::Value Value);
+ bool onCall(StringRef Method, llvm::json::Value Params, llvm::json::Value Id);
+ bool onReply(llvm::json::Value Id, llvm::Expected<llvm::json::Value> Result);
+
+ template <typename T>
+ static llvm::Expected<T> parse(const llvm::json::Value &Raw,
+ StringRef PayloadName, StringRef PayloadKind) {
+ T Result;
+ llvm::json::Path::Root Root;
+ if (fromJSON(Raw, Result, Root))
+ return std::move(Result);
+
+ // Dump the relevant parts of the broken message.
+ std::string Context;
+ llvm::raw_string_ostream Os(Context);
+ Root.printErrorContext(Raw, Os);
+
+ // Report the error (e.g. to the client).
+ return llvm::make_error<LSPError>(
+ llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind,
+ fmt_consume(Root.getError())),
+ ErrorCode::InvalidParams);
+ }
+
+ template <typename Param, typename Result, typename ThisT>
+ void method(llvm::StringLiteral Method, ThisT *ThisPtr,
+ void (ThisT::*Handler)(const Param &, Callback<Result>)) {
+ MethodHandlers[Method] = [Method, Handler,
+ ThisPtr](llvm::json::Value RawParams,
+ Callback<llvm::json::Value> Reply) {
+ llvm::Expected<Param> Parameter =
+ parse<Param>(RawParams, Method, "request");
+ if (!Parameter)
+ return Reply(Parameter.takeError());
+ (ThisPtr->*Handler)(*Parameter, std::move(Reply));
+ };
+ }
+
+ template <typename Param, typename ThisT>
+ void notification(llvm::StringLiteral Method, ThisT *ThisPtr,
+ void (ThisT::*Handler)(const Param &)) {
+ NotificationHandlers[Method] = [Method, Handler,
+ ThisPtr](llvm::json::Value RawParams) {
+ llvm::Expected<Param> Parameter =
+ parse<Param>(RawParams, Method, "notification");
+ if (!Parameter) {
+ return llvm::consumeError(llvm::handleErrors(
+ Parameter.takeError(), [](const LSPError &LspError) {
+ Logger::error("JSON parsing error: {0}",
+ LspError.message.c_str());
+ }));
+ }
+ (ThisPtr->*Handler)(*Parameter);
+ };
+ }
+
+ /// Create an OutgoingNotification object used for the given method.
+ template <typename T>
+ OutgoingNotification<T> outgoingNotification(llvm::StringLiteral Method) {
+ return [&, Method](const T &Params) {
+ std::lock_guard<std::mutex> TransportLock(TransportOutputMutex);
+ Logger::info("--> {0}", Method);
+ Transport.notify(Method, llvm::json::Value(Params));
+ };
+ }
+
+ /// Create an OutgoingRequest function that, when called, sends a request with
+ /// the given method via the transport. Should the outgoing request be
+ /// met with a response, the result JSON is parsed and the response callback
+ /// is invoked.
+ template <typename Param, typename Result>
+ OutgoingRequest<Param>
+ outgoingRequest(llvm::StringLiteral Method,
+ OutgoingRequestCallback<Result> Callback) {
+ return [&, Method, Callback](const Param &Parameter, llvm::json::Value Id) {
+ auto CallbackWrapper = [Method, Callback = std::move(Callback)](
+ llvm::json::Value Id,
+ llvm::Expected<llvm::json::Value> Value) {
+ if (!Value)
+ return Callback(std::move(Id), Value.takeError());
+
+ std::string ResponseName = llvm::formatv("reply:{0}({1})", Method, Id);
+ llvm::Expected<Result> ParseResult =
+ parse<Result>(*Value, ResponseName, "response");
+ if (!ParseResult)
+ return Callback(std::move(Id), ParseResult.takeError());
+
+ return Callback(std::move(Id), *ParseResult);
+ };
+
+ {
+ std::lock_guard<std::mutex> Lock(ResponseHandlersMutex);
+ ResponseHandlers.insert(
+ {debugString(Id), std::make_pair(Method.str(), CallbackWrapper)});
+ }
+
+ std::lock_guard<std::mutex> TransportLock(TransportOutputMutex);
+ Logger::info("--> {0}({1})", Method, Id);
+ Transport.call(Method, llvm::json::Value(Parameter), Id);
+ };
+ }
+
+private:
+ template <typename HandlerT>
+ using HandlerMap = llvm::StringMap<llvm::unique_function<HandlerT>>;
+
+ HandlerMap<void(llvm::json::Value)> NotificationHandlers;
+ HandlerMap<void(llvm::json::Value, Callback<llvm::json::Value>)>
+ MethodHandlers;
+
+ /// A pair of (1) the original request's method name, and (2) the callback
+ /// function to be invoked for responses.
+ using ResponseHandlerTy =
+ std::pair<std::string, OutgoingRequestCallback<llvm::json::Value>>;
+ /// A mapping from request/response ID to response handler.
+ llvm::StringMap<ResponseHandlerTy> ResponseHandlers;
+ /// Mutex to guard insertion into the response handler map.
+ std::mutex ResponseHandlersMutex;
+
+ JSONTransport &Transport;
+
+ /// Mutex to guard sending output messages to the transport.
+ std::mutex TransportOutputMutex;
+};
+
+} // namespace lsp
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 6646af6db5d3c..82a32ba817b10 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -135,6 +135,7 @@ if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
endif()
add_subdirectory(BLAKE3)
+add_subdirectory(LSP)
add_llvm_component_library(LLVMSupport
ABIBreak.cpp
@@ -288,6 +289,7 @@ add_llvm_component_library(LLVMSupport
${ALLOCATOR_FILES}
$<TARGET_OBJECTS:LLVMSupportBlake3>
+ $<TARGET_OBJECTS:LLVMSupportLSP>
# System
Atomic.cpp
diff --git a/llvm/lib/Support/LSP/CMakeLists.txt b/llvm/lib/Support/LSP/CMakeLists.txt
new file mode 100644
index 0000000000000..353e649105c17
--- /dev/null
+++ b/llvm/lib/Support/LSP/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_llvm_library(LLVMSupportLSP STATIC
+ Protocol.cpp
+ Transport.cpp
+ Logging.cpp
+)
+
+target_include_directories(LLVMSupportLSP
+ PUBLIC
+ $<BUILD_INTERFACE:${LLVM_MAIN_INCLUDE_DIR}>
+ $<BUILD_INTERFACE:${LLVM_LIBRARY_DIR}/Support/LSP>
+ $<INSTALL_INTERFACE:include> # for installation
+)
+
+target_link_libraries(LLVMSupportLSP
+ PUBLIC
+ LLVMSupport
+)
diff --git a/mlir/lib/Tools/lsp-server-support/Logging.cpp b/llvm/lib/Support/LSP/Logging.cpp
similarity index 55%
rename from mlir/lib/Tools/lsp-server-support/Logging.cpp
rename to llvm/lib/Support/LSP/Logging.cpp
index 373e2165c244d..b36621ae1c6c6 100644
--- a/mlir/lib/Tools/lsp-server-support/Logging.cpp
+++ b/llvm/lib/Support/LSP/Logging.cpp
@@ -6,36 +6,36 @@
//
//===----------------------------------------------------------------------===//
-#include "mlir/Tools/lsp-server-support/Logging.h"
+#include "llvm/Support/LSP/Logging.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/raw_ostream.h"
-using namespace mlir;
-using namespace mlir::lsp;
+using namespace llvm;
+using namespace llvm::lsp;
-void Logger::setLogLevel(Level logLevel) { get().logLevel = logLevel; }
+void Logger::setLogLevel(Level LogLevel) { get().LogLevel = LogLevel; }
Logger &Logger::get() {
- static Logger logger;
- return logger;
+ static Logger Logger;
+ return Logger;
}
-void Logger::log(Level logLevel, const char *fmt,
- const llvm::formatv_object_base &message) {
- Logger &logger = get();
+void Logger::log(Level LogLevel, const char *Fmt,
+ const llvm::formatv_object_base &Message) {
+ Logger &Logger = get();
// Ignore messages with log levels below the current setting in the logger.
- if (logLevel < logger.logLevel)
+ if (LogLevel < Logger.LogLevel)
return;
// An indicator character for each log level.
- const char *logLevelIndicators = "DIE";
+ const char *LogLevelIndicators = "DIE";
// Format the message and print to errs.
- llvm::sys::TimePoint<> timestamp = std::chrono::system_clock::now();
- std::lock_guard<std::mutex> logGuard(logger.mutex);
+ llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
+ std::lock_guard<std::mutex> LogGuard(Logger.Mutex);
llvm::errs() << llvm::formatv(
"{0}[{1:%H:%M:%S.%L}] {2}\n",
- logLevelIndicators[static_cast<unsigned>(logLevel)], timestamp, message);
+ LogLevelIndicators[static_cast<unsigned>(LogLevel)], Timestamp, Message);
llvm::errs().flush();
}
diff --git a/llvm/lib/Support/LSP/Protocol.cpp b/llvm/lib/Support/LSP/Protocol.cpp
new file mode 100644
index 0000000000000..f22126345a435
--- /dev/null
+++ b/llvm/lib/Support/LSP/Protocol.cpp
@@ -0,0 +1,1043 @@
+//===--- Protocol.cpp - Language Server Protocol Implementation -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the serialization code for the LSP structs.
+//
+//===-------------------------------------------------...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/155572
More information about the Mlir-commits
mailing list