diff --git a/lldb/source/Plugins/Protocol/MCP/Protocol.h b/lldb/include/lldb/Protocol/MCP/Protocol.h similarity index 96% rename from lldb/source/Plugins/Protocol/MCP/Protocol.h rename to lldb/include/lldb/Protocol/MCP/Protocol.h index ce74836e62541..c43b06809bd3f 100644 --- a/lldb/source/Plugins/Protocol/MCP/Protocol.h +++ b/lldb/include/lldb/Protocol/MCP/Protocol.h @@ -11,15 +11,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H -#define LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H +#ifndef LLDB_PROTOCOL_MCP_PROTOCOL_H +#define LLDB_PROTOCOL_MCP_PROTOCOL_H #include "llvm/Support/JSON.h" #include #include #include -namespace lldb_private::mcp::protocol { +namespace lldb_protocol::mcp { static llvm::StringLiteral kVersion = "2024-11-05"; @@ -183,6 +183,6 @@ llvm::json::Value toJSON(const Message &); using ToolArguments = std::variant; -} // namespace lldb_private::mcp::protocol +} // namespace lldb_protocol::mcp #endif diff --git a/lldb/source/CMakeLists.txt b/lldb/source/CMakeLists.txt index 51c9f9c90826e..ae02227ca3578 100644 --- a/lldb/source/CMakeLists.txt +++ b/lldb/source/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(Host) add_subdirectory(Initialization) add_subdirectory(Interpreter) add_subdirectory(Plugins) +add_subdirectory(Protocol) add_subdirectory(Symbol) add_subdirectory(Target) add_subdirectory(Utility) diff --git a/lldb/source/Plugins/Protocol/MCP/CMakeLists.txt b/lldb/source/Plugins/Protocol/MCP/CMakeLists.txt index e104fb527e57a..2740c0825a8c2 100644 --- a/lldb/source/Plugins/Protocol/MCP/CMakeLists.txt +++ b/lldb/source/Plugins/Protocol/MCP/CMakeLists.txt @@ -1,6 +1,5 @@ add_lldb_library(lldbPluginProtocolServerMCP PLUGIN MCPError.cpp - Protocol.cpp ProtocolServerMCP.cpp Resource.cpp Tool.cpp @@ -10,5 +9,6 @@ add_lldb_library(lldbPluginProtocolServerMCP PLUGIN LINK_LIBS lldbHost + lldbProtocolMCP lldbUtility ) diff --git a/lldb/source/Plugins/Protocol/MCP/MCPError.cpp b/lldb/source/Plugins/Protocol/MCP/MCPError.cpp index 659b53a14fe23..1e358058fa86c 100644 --- a/lldb/source/Plugins/Protocol/MCP/MCPError.cpp +++ b/lldb/source/Plugins/Protocol/MCP/MCPError.cpp @@ -11,7 +11,7 @@ #include "llvm/Support/raw_ostream.h" #include -namespace lldb_private::mcp { +using namespace lldb_private::mcp; char MCPError::ID; char UnsupportedURI::ID; @@ -25,8 +25,8 @@ std::error_code MCPError::convertToErrorCode() const { return llvm::inconvertibleErrorCode(); } -protocol::Error MCPError::toProtcolError() const { - protocol::Error error; +lldb_protocol::mcp::Error MCPError::toProtcolError() const { + lldb_protocol::mcp::Error error; error.error.code = m_error_code; error.error.message = m_message; return error; @@ -41,5 +41,3 @@ void UnsupportedURI::log(llvm::raw_ostream &OS) const { std::error_code UnsupportedURI::convertToErrorCode() const { return llvm::inconvertibleErrorCode(); } - -} // namespace lldb_private::mcp diff --git a/lldb/source/Plugins/Protocol/MCP/MCPError.h b/lldb/source/Plugins/Protocol/MCP/MCPError.h index f4db13d6deade..c93e959574938 100644 --- a/lldb/source/Plugins/Protocol/MCP/MCPError.h +++ b/lldb/source/Plugins/Protocol/MCP/MCPError.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "Protocol.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include @@ -24,7 +24,7 @@ class MCPError : public llvm::ErrorInfo { const std::string &getMessage() const { return m_message; } - protocol::Error toProtcolError() const; + lldb_protocol::mcp::Error toProtcolError() const; static constexpr int64_t kResourceNotFound = -32002; static constexpr int64_t kInternalError = -32603; diff --git a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp index 0e5a3631e6387..4d517ee8158c4 100644 --- a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp +++ b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp @@ -42,10 +42,11 @@ ProtocolServerMCP::ProtocolServerMCP() : ProtocolServer() { AddRequestHandler("resources/read", std::bind(&ProtocolServerMCP::ResourcesReadHandler, this, std::placeholders::_1)); - AddNotificationHandler( - "notifications/initialized", [](const protocol::Notification &) { - LLDB_LOG(GetLog(LLDBLog::Host), "MCP initialization complete"); - }); + AddNotificationHandler("notifications/initialized", + [](const lldb_protocol::mcp::Notification &) { + LLDB_LOG(GetLog(LLDBLog::Host), + "MCP initialization complete"); + }); AddTool( std::make_unique("lldb_command", "Run an lldb command.")); @@ -72,11 +73,11 @@ llvm::StringRef ProtocolServerMCP::GetPluginDescriptionStatic() { return "MCP Server."; } -llvm::Expected -ProtocolServerMCP::Handle(protocol::Request request) { +llvm::Expected +ProtocolServerMCP::Handle(lldb_protocol::mcp::Request request) { auto it = m_request_handlers.find(request.method); if (it != m_request_handlers.end()) { - llvm::Expected response = it->second(request); + llvm::Expected response = it->second(request); if (!response) return response; response->id = request.id; @@ -87,7 +88,7 @@ ProtocolServerMCP::Handle(protocol::Request request) { llvm::formatv("no handler for request: {0}", request.method).str()); } -void ProtocolServerMCP::Handle(protocol::Notification notification) { +void ProtocolServerMCP::Handle(lldb_protocol::mcp::Notification notification) { auto it = m_notification_handlers.find(notification.method); if (it != m_notification_handlers.end()) { it->second(notification); @@ -133,7 +134,7 @@ llvm::Error ProtocolServerMCP::ReadCallback(Client &client) { for (std::string::size_type pos; (pos = client.buffer.find('\n')) != std::string::npos;) { - llvm::Expected> message = + llvm::Expected> message = HandleData(StringRef(client.buffer.data(), pos)); client.buffer = client.buffer.erase(0, pos + 1); if (!message) @@ -208,19 +209,19 @@ llvm::Error ProtocolServerMCP::Stop() { return llvm::Error::success(); } -llvm::Expected> +llvm::Expected> ProtocolServerMCP::HandleData(llvm::StringRef data) { - auto message = llvm::json::parse(/*JSON=*/data); + auto message = llvm::json::parse(/*JSON=*/data); if (!message) return message.takeError(); - if (const protocol::Request *request = - std::get_if(&(*message))) { - llvm::Expected response = Handle(*request); + if (const lldb_protocol::mcp::Request *request = + std::get_if(&(*message))) { + llvm::Expected response = Handle(*request); // Handle failures by converting them into an Error message. if (!response) { - protocol::Error protocol_error; + lldb_protocol::mcp::Error protocol_error; llvm::handleAllErrors( response.takeError(), [&](const MCPError &err) { protocol_error = err.toProtcolError(); }, @@ -235,23 +236,23 @@ ProtocolServerMCP::HandleData(llvm::StringRef data) { return *response; } - if (const protocol::Notification *notification = - std::get_if(&(*message))) { + if (const lldb_protocol::mcp::Notification *notification = + std::get_if(&(*message))) { Handle(*notification); return std::nullopt; } - if (std::get_if(&(*message))) + if (std::get_if(&(*message))) return llvm::createStringError("unexpected MCP message: error"); - if (std::get_if(&(*message))) + if (std::get_if(&(*message))) return llvm::createStringError("unexpected MCP message: response"); llvm_unreachable("all message types handled"); } -protocol::Capabilities ProtocolServerMCP::GetCapabilities() { - protocol::Capabilities capabilities; +lldb_protocol::mcp::Capabilities ProtocolServerMCP::GetCapabilities() { + lldb_protocol::mcp::Capabilities capabilities; capabilities.tools.listChanged = true; // FIXME: Support sending notifications when a debugger/target are // added/removed. @@ -288,20 +289,22 @@ void ProtocolServerMCP::AddNotificationHandler(llvm::StringRef method, m_notification_handlers[method] = std::move(handler); } -llvm::Expected -ProtocolServerMCP::InitializeHandler(const protocol::Request &request) { - protocol::Response response; +llvm::Expected +ProtocolServerMCP::InitializeHandler( + const lldb_protocol::mcp::Request &request) { + lldb_protocol::mcp::Response response; response.result.emplace(llvm::json::Object{ - {"protocolVersion", protocol::kVersion}, + {"protocolVersion", lldb_protocol::mcp::kVersion}, {"capabilities", GetCapabilities()}, {"serverInfo", llvm::json::Object{{"name", kName}, {"version", kVersion}}}}); return response; } -llvm::Expected -ProtocolServerMCP::ToolsListHandler(const protocol::Request &request) { - protocol::Response response; +llvm::Expected +ProtocolServerMCP::ToolsListHandler( + const lldb_protocol::mcp::Request &request) { + lldb_protocol::mcp::Response response; llvm::json::Array tools; for (const auto &tool : m_tools) @@ -312,9 +315,10 @@ ProtocolServerMCP::ToolsListHandler(const protocol::Request &request) { return response; } -llvm::Expected -ProtocolServerMCP::ToolsCallHandler(const protocol::Request &request) { - protocol::Response response; +llvm::Expected +ProtocolServerMCP::ToolsCallHandler( + const lldb_protocol::mcp::Request &request) { + lldb_protocol::mcp::Response response; if (!request.params) return llvm::createStringError("no tool parameters"); @@ -335,11 +339,11 @@ ProtocolServerMCP::ToolsCallHandler(const protocol::Request &request) { if (it == m_tools.end()) return llvm::createStringError(llvm::formatv("no tool \"{0}\"", tool_name)); - protocol::ToolArguments tool_args; + lldb_protocol::mcp::ToolArguments tool_args; if (const json::Value *args = param_obj->get("arguments")) tool_args = *args; - llvm::Expected text_result = + llvm::Expected text_result = it->second->Call(tool_args); if (!text_result) return text_result.takeError(); @@ -349,16 +353,17 @@ ProtocolServerMCP::ToolsCallHandler(const protocol::Request &request) { return response; } -llvm::Expected -ProtocolServerMCP::ResourcesListHandler(const protocol::Request &request) { - protocol::Response response; +llvm::Expected +ProtocolServerMCP::ResourcesListHandler( + const lldb_protocol::mcp::Request &request) { + lldb_protocol::mcp::Response response; llvm::json::Array resources; std::lock_guard guard(m_server_mutex); for (std::unique_ptr &resource_provider_up : m_resource_providers) { - for (const protocol::Resource &resource : + for (const lldb_protocol::mcp::Resource &resource : resource_provider_up->GetResources()) resources.push_back(resource); } @@ -368,9 +373,10 @@ ProtocolServerMCP::ResourcesListHandler(const protocol::Request &request) { return response; } -llvm::Expected -ProtocolServerMCP::ResourcesReadHandler(const protocol::Request &request) { - protocol::Response response; +llvm::Expected +ProtocolServerMCP::ResourcesReadHandler( + const lldb_protocol::mcp::Request &request) { + lldb_protocol::mcp::Response response; if (!request.params) return llvm::createStringError("no resource parameters"); @@ -390,7 +396,7 @@ ProtocolServerMCP::ResourcesReadHandler(const protocol::Request &request) { std::lock_guard guard(m_server_mutex); for (std::unique_ptr &resource_provider_up : m_resource_providers) { - llvm::Expected result = + llvm::Expected result = resource_provider_up->ReadResource(uri_str); if (result.errorIsA()) { llvm::consumeError(result.takeError()); @@ -399,7 +405,7 @@ ProtocolServerMCP::ResourcesReadHandler(const protocol::Request &request) { if (!result) return result.takeError(); - protocol::Response response; + lldb_protocol::mcp::Response response; response.result.emplace(std::move(*result)); return response; } diff --git a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h index e273f6e2a8d37..611e62af5c8cb 100644 --- a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h +++ b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h @@ -9,12 +9,12 @@ #ifndef LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOLSERVERMCP_H #define LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOLSERVERMCP_H -#include "Protocol.h" #include "Resource.h" #include "Tool.h" #include "lldb/Core/ProtocolServer.h" #include "lldb/Host/MainLoop.h" #include "lldb/Host/Socket.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/ADT/StringMap.h" #include @@ -41,10 +41,11 @@ class ProtocolServerMCP : public ProtocolServer { Socket *GetSocket() const override { return m_listener.get(); } protected: - using RequestHandler = std::function( - const protocol::Request &)>; + using RequestHandler = + std::function( + const lldb_protocol::mcp::Request &)>; using NotificationHandler = - std::function; + std::function; void AddTool(std::unique_ptr tool); void AddResourceProvider(std::unique_ptr resource_provider); @@ -56,26 +57,27 @@ class ProtocolServerMCP : public ProtocolServer { private: void AcceptCallback(std::unique_ptr socket); - llvm::Expected> + llvm::Expected> HandleData(llvm::StringRef data); - llvm::Expected Handle(protocol::Request request); - void Handle(protocol::Notification notification); + llvm::Expected + Handle(lldb_protocol::mcp::Request request); + void Handle(lldb_protocol::mcp::Notification notification); - llvm::Expected - InitializeHandler(const protocol::Request &); + llvm::Expected + InitializeHandler(const lldb_protocol::mcp::Request &); - llvm::Expected - ToolsListHandler(const protocol::Request &); - llvm::Expected - ToolsCallHandler(const protocol::Request &); + llvm::Expected + ToolsListHandler(const lldb_protocol::mcp::Request &); + llvm::Expected + ToolsCallHandler(const lldb_protocol::mcp::Request &); - llvm::Expected - ResourcesListHandler(const protocol::Request &); - llvm::Expected - ResourcesReadHandler(const protocol::Request &); + llvm::Expected + ResourcesListHandler(const lldb_protocol::mcp::Request &); + llvm::Expected + ResourcesReadHandler(const lldb_protocol::mcp::Request &); - protocol::Capabilities GetCapabilities(); + lldb_protocol::mcp::Capabilities GetCapabilities(); llvm::StringLiteral kName = "lldb-mcp"; llvm::StringLiteral kVersion = "0.1.0"; diff --git a/lldb/source/Plugins/Protocol/MCP/Resource.cpp b/lldb/source/Plugins/Protocol/MCP/Resource.cpp index d75d5b6dd6a41..bc39e1b0c0ed2 100644 --- a/lldb/source/Plugins/Protocol/MCP/Resource.cpp +++ b/lldb/source/Plugins/Protocol/MCP/Resource.cpp @@ -10,6 +10,7 @@ #include "lldb/Core/Module.h" #include "lldb/Target/Platform.h" +using namespace lldb_private; using namespace lldb_private::mcp; namespace { @@ -64,11 +65,11 @@ static llvm::Error createUnsupportedURIError(llvm::StringRef uri) { return llvm::make_error(uri.str()); } -protocol::Resource +lldb_protocol::mcp::Resource DebuggerResourceProvider::GetDebuggerResource(Debugger &debugger) { const lldb::user_id_t debugger_id = debugger.GetID(); - protocol::Resource resource; + lldb_protocol::mcp::Resource resource; resource.uri = llvm::formatv("lldb://debugger/{0}", debugger_id); resource.name = debugger.GetInstanceName(); resource.description = @@ -78,7 +79,7 @@ DebuggerResourceProvider::GetDebuggerResource(Debugger &debugger) { return resource; } -protocol::Resource +lldb_protocol::mcp::Resource DebuggerResourceProvider::GetTargetResource(size_t target_idx, Target &target) { const size_t debugger_id = target.GetDebugger().GetID(); @@ -87,7 +88,7 @@ DebuggerResourceProvider::GetTargetResource(size_t target_idx, Target &target) { if (Module *exe_module = target.GetExecutableModulePointer()) target_name = exe_module->GetFileSpec().GetFilename().GetString(); - protocol::Resource resource; + lldb_protocol::mcp::Resource resource; resource.uri = llvm::formatv("lldb://debugger/{0}/target/{1}", debugger_id, target_idx); resource.name = target_name; @@ -98,8 +99,9 @@ DebuggerResourceProvider::GetTargetResource(size_t target_idx, Target &target) { return resource; } -std::vector DebuggerResourceProvider::GetResources() const { - std::vector resources; +std::vector +DebuggerResourceProvider::GetResources() const { + std::vector resources; const size_t num_debuggers = Debugger::GetNumDebuggers(); for (size_t i = 0; i < num_debuggers; ++i) { @@ -121,7 +123,7 @@ std::vector DebuggerResourceProvider::GetResources() const { return resources; } -llvm::Expected +llvm::Expected DebuggerResourceProvider::ReadResource(llvm::StringRef uri) const { auto [protocol, path] = uri.split("://"); @@ -158,7 +160,7 @@ DebuggerResourceProvider::ReadResource(llvm::StringRef uri) const { return ReadDebuggerResource(uri, debugger_idx); } -llvm::Expected +llvm::Expected DebuggerResourceProvider::ReadDebuggerResource(llvm::StringRef uri, lldb::user_id_t debugger_id) { lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(debugger_id); @@ -170,17 +172,17 @@ DebuggerResourceProvider::ReadDebuggerResource(llvm::StringRef uri, debugger_resource.name = debugger_sp->GetInstanceName(); debugger_resource.num_targets = debugger_sp->GetTargetList().GetNumTargets(); - protocol::ResourceContents contents; + lldb_protocol::mcp::ResourceContents contents; contents.uri = uri; contents.mimeType = kMimeTypeJSON; contents.text = llvm::formatv("{0}", toJSON(debugger_resource)); - protocol::ResourceResult result; + lldb_protocol::mcp::ResourceResult result; result.contents.push_back(contents); return result; } -llvm::Expected +llvm::Expected DebuggerResourceProvider::ReadTargetResource(llvm::StringRef uri, lldb::user_id_t debugger_id, size_t target_idx) { @@ -206,12 +208,12 @@ DebuggerResourceProvider::ReadTargetResource(llvm::StringRef uri, if (lldb::PlatformSP platform_sp = target_sp->GetPlatform()) target_resource.platform = platform_sp->GetName(); - protocol::ResourceContents contents; + lldb_protocol::mcp::ResourceContents contents; contents.uri = uri; contents.mimeType = kMimeTypeJSON; contents.text = llvm::formatv("{0}", toJSON(target_resource)); - protocol::ResourceResult result; + lldb_protocol::mcp::ResourceResult result; result.contents.push_back(contents); return result; } diff --git a/lldb/source/Plugins/Protocol/MCP/Resource.h b/lldb/source/Plugins/Protocol/MCP/Resource.h index 5ac38e7e878ff..0066f2f8e1b0e 100644 --- a/lldb/source/Plugins/Protocol/MCP/Resource.h +++ b/lldb/source/Plugins/Protocol/MCP/Resource.h @@ -9,7 +9,7 @@ #ifndef LLDB_PLUGINS_PROTOCOL_MCP_RESOURCE_H #define LLDB_PLUGINS_PROTOCOL_MCP_RESOURCE_H -#include "Protocol.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "lldb/lldb-private.h" #include @@ -20,8 +20,8 @@ class ResourceProvider { ResourceProvider() = default; virtual ~ResourceProvider() = default; - virtual std::vector GetResources() const = 0; - virtual llvm::Expected + virtual std::vector GetResources() const = 0; + virtual llvm::Expected ReadResource(llvm::StringRef uri) const = 0; }; @@ -30,18 +30,19 @@ class DebuggerResourceProvider : public ResourceProvider { using ResourceProvider::ResourceProvider; virtual ~DebuggerResourceProvider() = default; - virtual std::vector GetResources() const override; - virtual llvm::Expected + virtual std::vector + GetResources() const override; + virtual llvm::Expected ReadResource(llvm::StringRef uri) const override; private: - static protocol::Resource GetDebuggerResource(Debugger &debugger); - static protocol::Resource GetTargetResource(size_t target_idx, - Target &target); + static lldb_protocol::mcp::Resource GetDebuggerResource(Debugger &debugger); + static lldb_protocol::mcp::Resource GetTargetResource(size_t target_idx, + Target &target); - static llvm::Expected + static llvm::Expected ReadDebuggerResource(llvm::StringRef uri, lldb::user_id_t debugger_id); - static llvm::Expected + static llvm::Expected ReadTargetResource(llvm::StringRef uri, lldb::user_id_t debugger_id, size_t target_idx); }; diff --git a/lldb/source/Plugins/Protocol/MCP/Tool.cpp b/lldb/source/Plugins/Protocol/MCP/Tool.cpp index bbc19a1e51942..9df5ce843e0ff 100644 --- a/lldb/source/Plugins/Protocol/MCP/Tool.cpp +++ b/lldb/source/Plugins/Protocol/MCP/Tool.cpp @@ -11,6 +11,8 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +using namespace lldb_private; +using namespace lldb_protocol; using namespace lldb_private::mcp; using namespace llvm; @@ -28,11 +30,11 @@ bool fromJSON(const llvm::json::Value &V, CommandToolArguments &A, } /// Helper function to create a TextResult from a string output. -static lldb_private::mcp::protocol::TextResult -createTextResult(std::string output, bool is_error = false) { - lldb_private::mcp::protocol::TextResult text_result; +static lldb_protocol::mcp::TextResult createTextResult(std::string output, + bool is_error = false) { + lldb_protocol::mcp::TextResult text_result; text_result.content.emplace_back( - lldb_private::mcp::protocol::TextContent{{std::move(output)}}); + lldb_protocol::mcp::TextContent{{std::move(output)}}); text_result.isError = is_error; return text_result; } @@ -42,8 +44,8 @@ createTextResult(std::string output, bool is_error = false) { Tool::Tool(std::string name, std::string description) : m_name(std::move(name)), m_description(std::move(description)) {} -protocol::ToolDefinition Tool::GetDefinition() const { - protocol::ToolDefinition definition; +lldb_protocol::mcp::ToolDefinition Tool::GetDefinition() const { + lldb_protocol::mcp::ToolDefinition definition; definition.name = m_name; definition.description = m_description; @@ -53,8 +55,8 @@ protocol::ToolDefinition Tool::GetDefinition() const { return definition; } -llvm::Expected -CommandTool::Call(const protocol::ToolArguments &args) { +llvm::Expected +CommandTool::Call(const lldb_protocol::mcp::ToolArguments &args) { if (!std::holds_alternative(args)) return createStringError("CommandTool requires arguments"); diff --git a/lldb/source/Plugins/Protocol/MCP/Tool.h b/lldb/source/Plugins/Protocol/MCP/Tool.h index d0f639adad24e..ec1d83a510964 100644 --- a/lldb/source/Plugins/Protocol/MCP/Tool.h +++ b/lldb/source/Plugins/Protocol/MCP/Tool.h @@ -9,8 +9,8 @@ #ifndef LLDB_PLUGINS_PROTOCOL_MCP_TOOL_H #define LLDB_PLUGINS_PROTOCOL_MCP_TOOL_H -#include "Protocol.h" #include "lldb/Core/Debugger.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/Support/JSON.h" #include @@ -21,14 +21,14 @@ class Tool { Tool(std::string name, std::string description); virtual ~Tool() = default; - virtual llvm::Expected - Call(const protocol::ToolArguments &args) = 0; + virtual llvm::Expected + Call(const lldb_protocol::mcp::ToolArguments &args) = 0; virtual std::optional GetSchema() const { return llvm::json::Object{{"type", "object"}}; } - protocol::ToolDefinition GetDefinition() const; + lldb_protocol::mcp::ToolDefinition GetDefinition() const; const std::string &GetName() { return m_name; } @@ -42,8 +42,8 @@ class CommandTool : public mcp::Tool { using mcp::Tool::Tool; ~CommandTool() = default; - virtual llvm::Expected - Call(const protocol::ToolArguments &args) override; + virtual llvm::Expected + Call(const lldb_protocol::mcp::ToolArguments &args) override; virtual std::optional GetSchema() const override; }; diff --git a/lldb/source/Protocol/CMakeLists.txt b/lldb/source/Protocol/CMakeLists.txt new file mode 100644 index 0000000000000..93b347d4cc9d8 --- /dev/null +++ b/lldb/source/Protocol/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(MCP) diff --git a/lldb/source/Protocol/MCP/CMakeLists.txt b/lldb/source/Protocol/MCP/CMakeLists.txt new file mode 100644 index 0000000000000..b197dc4c0430a --- /dev/null +++ b/lldb/source/Protocol/MCP/CMakeLists.txt @@ -0,0 +1,8 @@ +add_lldb_library(lldbProtocolMCP NO_PLUGIN_DEPENDENCIES + Protocol.cpp + + LINK_COMPONENTS + Support + LINK_LIBS + lldbUtility +) diff --git a/lldb/source/Plugins/Protocol/MCP/Protocol.cpp b/lldb/source/Protocol/MCP/Protocol.cpp similarity index 97% rename from lldb/source/Plugins/Protocol/MCP/Protocol.cpp rename to lldb/source/Protocol/MCP/Protocol.cpp index 274ba6fac01ec..d579b88037e63 100644 --- a/lldb/source/Plugins/Protocol/MCP/Protocol.cpp +++ b/lldb/source/Protocol/MCP/Protocol.cpp @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "Protocol.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/Support/JSON.h" using namespace llvm; -namespace lldb_private::mcp::protocol { +namespace lldb_protocol::mcp { static bool mapRaw(const json::Value &Params, StringLiteral Prop, std::optional &V, json::Path P) { @@ -228,7 +228,7 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) { // A message without an ID is a Notification. if (!O->get("id")) { - protocol::Notification N; + Notification N; if (!fromJSON(V, N, P)) return false; M = std::move(N); @@ -236,7 +236,7 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) { } if (O->get("error")) { - protocol::Error E; + Error E; if (!fromJSON(V, E, P)) return false; M = std::move(E); @@ -244,7 +244,7 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) { } if (O->get("result")) { - protocol::Response R; + Response R; if (!fromJSON(V, R, P)) return false; M = std::move(R); @@ -252,7 +252,7 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) { } if (O->get("method")) { - protocol::Request R; + Request R; if (!fromJSON(V, R, P)) return false; M = std::move(R); @@ -263,4 +263,4 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) { return false; } -} // namespace lldb_private::mcp::protocol +} // namespace lldb_protocol::mcp diff --git a/lldb/unittests/CMakeLists.txt b/lldb/unittests/CMakeLists.txt index b48b9bafe3bc3..5533c73c3de87 100644 --- a/lldb/unittests/CMakeLists.txt +++ b/lldb/unittests/CMakeLists.txt @@ -61,25 +61,26 @@ add_subdirectory(Disassembler) add_subdirectory(Editline) add_subdirectory(Expression) add_subdirectory(Host) -add_subdirectory(Interpreter) add_subdirectory(Instruction) +add_subdirectory(Interpreter) add_subdirectory(Language) add_subdirectory(ObjectFile) add_subdirectory(Platform) add_subdirectory(Process) +add_subdirectory(Protocol) add_subdirectory(ScriptInterpreter) add_subdirectory(Signals) add_subdirectory(Symbol) add_subdirectory(SymbolFile) add_subdirectory(Target) -add_subdirectory(tools) +add_subdirectory(Thread) add_subdirectory(UnwindAssembly) add_subdirectory(Utility) -add_subdirectory(Thread) add_subdirectory(ValueObject) +add_subdirectory(tools) if(LLDB_ENABLE_PROTOCOL_SERVERS) - add_subdirectory(Protocol) + add_subdirectory(ProtocolServer) endif() if(LLDB_CAN_USE_DEBUGSERVER AND LLDB_TOOL_DEBUGSERVER_BUILD AND NOT LLDB_USE_SYSTEM_DEBUGSERVER) diff --git a/lldb/unittests/Protocol/CMakeLists.txt b/lldb/unittests/Protocol/CMakeLists.txt index 801662b0544d8..bbac69611e011 100644 --- a/lldb/unittests/Protocol/CMakeLists.txt +++ b/lldb/unittests/Protocol/CMakeLists.txt @@ -1,12 +1,9 @@ add_lldb_unittest(ProtocolTests ProtocolMCPTest.cpp - ProtocolMCPServerTest.cpp LINK_LIBS - lldbCore - lldbUtility lldbHost - lldbPluginPlatformMacOSX - lldbPluginProtocolServerMCP + lldbProtocolMCP + lldbUtility LLVMTestingSupport ) diff --git a/lldb/unittests/Protocol/ProtocolMCPTest.cpp b/lldb/unittests/Protocol/ProtocolMCPTest.cpp index ce8120cbfe9b9..1dca0e5fc5bb8 100644 --- a/lldb/unittests/Protocol/ProtocolMCPTest.cpp +++ b/lldb/unittests/Protocol/ProtocolMCPTest.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "Plugins/Protocol/MCP/Protocol.h" #include "TestingSupport/TestUtilities.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" using namespace lldb; using namespace lldb_private; -using namespace lldb_private::mcp::protocol; +using namespace lldb_protocol::mcp; TEST(ProtocolMCPTest, Request) { Request request; diff --git a/lldb/unittests/ProtocolServer/CMakeLists.txt b/lldb/unittests/ProtocolServer/CMakeLists.txt new file mode 100644 index 0000000000000..6117430b35bf0 --- /dev/null +++ b/lldb/unittests/ProtocolServer/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_unittest(ProtocolServerTests + ProtocolMCPServerTest.cpp + + LINK_LIBS + lldbCore + lldbUtility + lldbHost + lldbPluginPlatformMacOSX + lldbPluginProtocolServerMCP + LLVMTestingSupport + ) diff --git a/lldb/unittests/Protocol/ProtocolMCPServerTest.cpp b/lldb/unittests/ProtocolServer/ProtocolMCPServerTest.cpp similarity index 94% rename from lldb/unittests/Protocol/ProtocolMCPServerTest.cpp rename to lldb/unittests/ProtocolServer/ProtocolMCPServerTest.cpp index 51eb6275e811a..b1cc21a5b0c37 100644 --- a/lldb/unittests/Protocol/ProtocolMCPServerTest.cpp +++ b/lldb/unittests/ProtocolServer/ProtocolMCPServerTest.cpp @@ -16,13 +16,14 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Host/JSONTransport.h" #include "lldb/Host/Socket.h" +#include "lldb/Protocol/MCP/Protocol.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" using namespace llvm; using namespace lldb; using namespace lldb_private; -using namespace lldb_private::mcp::protocol; +using namespace lldb_protocol::mcp; namespace { class TestProtocolServerMCP : public lldb_private::mcp::ProtocolServerMCP { @@ -47,8 +48,7 @@ class TestTool : public mcp::Tool { public: using mcp::Tool::Tool; - virtual llvm::Expected - Call(const ToolArguments &args) override { + virtual llvm::Expected Call(const ToolArguments &args) override { std::string argument; if (const json::Object *args_obj = std::get(args).getAsObject()) { @@ -57,8 +57,8 @@ class TestTool : public mcp::Tool { } } - mcp::protocol::TextResult text_result; - text_result.content.emplace_back(mcp::protocol::TextContent{{argument}}); + TextResult text_result; + text_result.content.emplace_back(TextContent{{argument}}); return text_result; } }; @@ -100,8 +100,7 @@ class ErrorTool : public mcp::Tool { public: using mcp::Tool::Tool; - virtual llvm::Expected - Call(const ToolArguments &args) override { + virtual llvm::Expected Call(const ToolArguments &args) override { return llvm::createStringError("error"); } }; @@ -111,10 +110,9 @@ class FailTool : public mcp::Tool { public: using mcp::Tool::Tool; - virtual llvm::Expected - Call(const ToolArguments &args) override { - mcp::protocol::TextResult text_result; - text_result.content.emplace_back(mcp::protocol::TextContent{{"failed"}}); + virtual llvm::Expected Call(const ToolArguments &args) override { + TextResult text_result; + text_result.content.emplace_back(TextContent{{"failed"}}); text_result.isError = true; return text_result; } @@ -309,8 +307,7 @@ TEST_F(ProtocolServerMCPTest, NotificationInitialized) { std::mutex mutex; m_server_up->AddNotificationHandler( - "notifications/initialized", - [&](const mcp::protocol::Notification ¬ification) { + "notifications/initialized", [&](const Notification ¬ification) { { std::lock_guard lock(mutex); handler_called = true;