Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Protocol/MCP/Tool.cpp
213845 views
1
//===- Tool.cpp -----------------------------------------------------------===//
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 "Tool.h"
10
#include "lldb/Core/Module.h"
11
#include "lldb/Interpreter/CommandInterpreter.h"
12
#include "lldb/Interpreter/CommandReturnObject.h"
13
14
using namespace lldb_private::mcp;
15
using namespace llvm;
16
17
namespace {
18
struct CommandToolArguments {
19
uint64_t debugger_id;
20
std::string arguments;
21
};
22
23
bool fromJSON(const llvm::json::Value &V, CommandToolArguments &A,
24
llvm::json::Path P) {
25
llvm::json::ObjectMapper O(V, P);
26
return O && O.map("debugger_id", A.debugger_id) &&
27
O.mapOptional("arguments", A.arguments);
28
}
29
30
/// Helper function to create a TextResult from a string output.
31
static lldb_private::mcp::protocol::TextResult
32
createTextResult(std::string output, bool is_error = false) {
33
lldb_private::mcp::protocol::TextResult text_result;
34
text_result.content.emplace_back(
35
lldb_private::mcp::protocol::TextContent{{std::move(output)}});
36
text_result.isError = is_error;
37
return text_result;
38
}
39
40
} // namespace
41
42
Tool::Tool(std::string name, std::string description)
43
: m_name(std::move(name)), m_description(std::move(description)) {}
44
45
protocol::ToolDefinition Tool::GetDefinition() const {
46
protocol::ToolDefinition definition;
47
definition.name = m_name;
48
definition.description = m_description;
49
50
if (std::optional<llvm::json::Value> input_schema = GetSchema())
51
definition.inputSchema = *input_schema;
52
53
return definition;
54
}
55
56
llvm::Expected<protocol::TextResult>
57
CommandTool::Call(const protocol::ToolArguments &args) {
58
if (!std::holds_alternative<json::Value>(args))
59
return createStringError("CommandTool requires arguments");
60
61
json::Path::Root root;
62
63
CommandToolArguments arguments;
64
if (!fromJSON(std::get<json::Value>(args), arguments, root))
65
return root.getError();
66
67
lldb::DebuggerSP debugger_sp =
68
Debugger::FindDebuggerWithID(arguments.debugger_id);
69
if (!debugger_sp)
70
return createStringError(
71
llvm::formatv("no debugger with id {0}", arguments.debugger_id));
72
73
// FIXME: Disallow certain commands and their aliases.
74
CommandReturnObject result(/*colors=*/false);
75
debugger_sp->GetCommandInterpreter().HandleCommand(
76
arguments.arguments.c_str(), eLazyBoolYes, result);
77
78
std::string output;
79
llvm::StringRef output_str = result.GetOutputString();
80
if (!output_str.empty())
81
output += output_str.str();
82
83
std::string err_str = result.GetErrorString();
84
if (!err_str.empty()) {
85
if (!output.empty())
86
output += '\n';
87
output += err_str;
88
}
89
90
return createTextResult(output, !result.Succeeded());
91
}
92
93
std::optional<llvm::json::Value> CommandTool::GetSchema() const {
94
llvm::json::Object id_type{{"type", "number"}};
95
llvm::json::Object str_type{{"type", "string"}};
96
llvm::json::Object properties{{"debugger_id", std::move(id_type)},
97
{"arguments", std::move(str_type)}};
98
llvm::json::Array required{"debugger_id"};
99
llvm::json::Object schema{{"type", "object"},
100
{"properties", std::move(properties)},
101
{"required", std::move(required)}};
102
return schema;
103
}
104
105