Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Protocol/MCP/Tool.cpp
213845 views
//===- Tool.cpp -----------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "Tool.h"9#include "lldb/Core/Module.h"10#include "lldb/Interpreter/CommandInterpreter.h"11#include "lldb/Interpreter/CommandReturnObject.h"1213using namespace lldb_private::mcp;14using namespace llvm;1516namespace {17struct CommandToolArguments {18uint64_t debugger_id;19std::string arguments;20};2122bool fromJSON(const llvm::json::Value &V, CommandToolArguments &A,23llvm::json::Path P) {24llvm::json::ObjectMapper O(V, P);25return O && O.map("debugger_id", A.debugger_id) &&26O.mapOptional("arguments", A.arguments);27}2829/// Helper function to create a TextResult from a string output.30static lldb_private::mcp::protocol::TextResult31createTextResult(std::string output, bool is_error = false) {32lldb_private::mcp::protocol::TextResult text_result;33text_result.content.emplace_back(34lldb_private::mcp::protocol::TextContent{{std::move(output)}});35text_result.isError = is_error;36return text_result;37}3839} // namespace4041Tool::Tool(std::string name, std::string description)42: m_name(std::move(name)), m_description(std::move(description)) {}4344protocol::ToolDefinition Tool::GetDefinition() const {45protocol::ToolDefinition definition;46definition.name = m_name;47definition.description = m_description;4849if (std::optional<llvm::json::Value> input_schema = GetSchema())50definition.inputSchema = *input_schema;5152return definition;53}5455llvm::Expected<protocol::TextResult>56CommandTool::Call(const protocol::ToolArguments &args) {57if (!std::holds_alternative<json::Value>(args))58return createStringError("CommandTool requires arguments");5960json::Path::Root root;6162CommandToolArguments arguments;63if (!fromJSON(std::get<json::Value>(args), arguments, root))64return root.getError();6566lldb::DebuggerSP debugger_sp =67Debugger::FindDebuggerWithID(arguments.debugger_id);68if (!debugger_sp)69return createStringError(70llvm::formatv("no debugger with id {0}", arguments.debugger_id));7172// FIXME: Disallow certain commands and their aliases.73CommandReturnObject result(/*colors=*/false);74debugger_sp->GetCommandInterpreter().HandleCommand(75arguments.arguments.c_str(), eLazyBoolYes, result);7677std::string output;78llvm::StringRef output_str = result.GetOutputString();79if (!output_str.empty())80output += output_str.str();8182std::string err_str = result.GetErrorString();83if (!err_str.empty()) {84if (!output.empty())85output += '\n';86output += err_str;87}8889return createTextResult(output, !result.Succeeded());90}9192std::optional<llvm::json::Value> CommandTool::GetSchema() const {93llvm::json::Object id_type{{"type", "number"}};94llvm::json::Object str_type{{"type", "string"}};95llvm::json::Object properties{{"debugger_id", std::move(id_type)},96{"arguments", std::move(str_type)}};97llvm::json::Array required{"debugger_id"};98llvm::json::Object schema{{"type", "object"},99{"properties", std::move(properties)},100{"required", std::move(required)}};101return schema;102}103104105