Skip to content

Commit daff2ac

Browse files
committed
migrate breakpoints requests handler implementations
1 parent 1c18401 commit daff2ac

13 files changed

+162
-781
lines changed

lldb/tools/lldb-dap/Breakpoint.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "lldb/API/SBLineEntry.h"
1515
#include "lldb/API/SBMutex.h"
1616
#include "llvm/ADT/StringExtras.h"
17-
#include "llvm/Support/JSON.h"
1817
#include <cstddef>
1918
#include <cstdint>
2019
#include <mutex>
@@ -30,13 +29,16 @@ void Breakpoint::SetHitCondition() {
3029
m_bp.SetIgnoreCount(hitCount - 1);
3130
}
3231

33-
void Breakpoint::CreateJsonObject(llvm::json::Object &object) {
32+
protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() {
33+
protocol::Breakpoint breakpoint;
34+
3435
// Each breakpoint location is treated as a separate breakpoint for VS code.
3536
// They don't have the notion of a single breakpoint with multiple locations.
3637
if (!m_bp.IsValid())
37-
return;
38-
object.try_emplace("verified", m_bp.GetNumResolvedLocations() > 0);
39-
object.try_emplace("id", m_bp.GetID());
38+
return breakpoint;
39+
40+
breakpoint.verified = m_bp.GetNumResolvedLocations() > 0;
41+
breakpoint.id = m_bp.GetID();
4042
// VS Code DAP doesn't currently allow one breakpoint to have multiple
4143
// locations so we just report the first one. If we report all locations
4244
// then the IDE starts showing the wrong line numbers and locations for
@@ -60,16 +62,18 @@ void Breakpoint::CreateJsonObject(llvm::json::Object &object) {
6062
if (bp_addr.IsValid()) {
6163
std::string formatted_addr =
6264
"0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget()));
63-
object.try_emplace("instructionReference", formatted_addr);
65+
breakpoint.instructionReference = formatted_addr;
6466
auto line_entry = bp_addr.GetLineEntry();
6567
const auto line = line_entry.GetLine();
6668
if (line != UINT32_MAX)
67-
object.try_emplace("line", line);
69+
breakpoint.line = line;
6870
const auto column = line_entry.GetColumn();
6971
if (column != 0)
70-
object.try_emplace("column", column);
71-
object.try_emplace("source", CreateSource(line_entry));
72+
breakpoint.column = column;
73+
breakpoint.source = CreateSource(line_entry);
7274
}
75+
76+
return breakpoint;
7377
}
7478

7579
bool Breakpoint::MatchesName(const char *name) {

lldb/tools/lldb-dap/Breakpoint.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class Breakpoint : public BreakpointBase {
2626

2727
void SetCondition() override;
2828
void SetHitCondition() override;
29-
void CreateJsonObject(llvm::json::Object &object) override;
29+
30+
protocol::Breakpoint ToProtocolBreakpoint() override;
3031

3132
bool MatchesName(const char *name);
3233
void SetBreakpoint();

lldb/tools/lldb-dap/BreakpointBase.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "BreakpointBase.h"
10-
#include "JSONUtils.h"
11-
#include "llvm/ADT/StringRef.h"
1210

1311
using namespace lldb_dap;
1412

lldb/tools/lldb-dap/BreakpointBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLDB_TOOLS_LLDB_DAP_BREAKPOINTBASE_H
1111

1212
#include "DAPForward.h"
13+
#include "Protocol/ProtocolTypes.h"
1314
#include <optional>
1415
#include <string>
1516

@@ -24,7 +25,7 @@ class BreakpointBase {
2425

2526
virtual void SetCondition() = 0;
2627
virtual void SetHitCondition() = 0;
27-
virtual void CreateJsonObject(llvm::json::Object &object) = 0;
28+
virtual protocol::Breakpoint ToProtocolBreakpoint() = 0;
2829

2930
void UpdateBreakpoint(const BreakpointBase &request_bp);
3031

lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp

Lines changed: 35 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -9,153 +9,49 @@
99
#include "DAP.h"
1010
#include "EventHelper.h"
1111
#include "JSONUtils.h"
12+
#include "Protocol/ProtocolRequests.h"
1213
#include "RequestHandler.h"
14+
#include <vector>
1315

1416
namespace lldb_dap {
1517

16-
// "SetBreakpointsRequest": {
17-
// "allOf": [ { "$ref": "#/definitions/Request" }, {
18-
// "type": "object",
19-
// "description": "SetBreakpoints request; value of command field is
20-
// 'setBreakpoints'. Sets multiple breakpoints for a single source and
21-
// clears all previous breakpoints in that source. To clear all breakpoint
22-
// for a source, specify an empty array. When a breakpoint is hit, a
23-
// StoppedEvent (event type 'breakpoint') is generated.", "properties": {
24-
// "command": {
25-
// "type": "string",
26-
// "enum": [ "setBreakpoints" ]
27-
// },
28-
// "arguments": {
29-
// "$ref": "#/definitions/SetBreakpointsArguments"
30-
// }
31-
// },
32-
// "required": [ "command", "arguments" ]
33-
// }]
34-
// },
35-
// "SetBreakpointsArguments": {
36-
// "type": "object",
37-
// "description": "Arguments for 'setBreakpoints' request.",
38-
// "properties": {
39-
// "source": {
40-
// "$ref": "#/definitions/Source",
41-
// "description": "The source location of the breakpoints; either
42-
// source.path or source.reference must be specified."
43-
// },
44-
// "breakpoints": {
45-
// "type": "array",
46-
// "items": {
47-
// "$ref": "#/definitions/SourceBreakpoint"
48-
// },
49-
// "description": "The code locations of the breakpoints."
50-
// },
51-
// "lines": {
52-
// "type": "array",
53-
// "items": {
54-
// "type": "integer"
55-
// },
56-
// "description": "Deprecated: The code locations of the breakpoints."
57-
// },
58-
// "sourceModified": {
59-
// "type": "boolean",
60-
// "description": "A value of true indicates that the underlying source
61-
// has been modified which results in new breakpoint locations."
62-
// }
63-
// },
64-
// "required": [ "source" ]
65-
// },
66-
// "SetBreakpointsResponse": {
67-
// "allOf": [ { "$ref": "#/definitions/Response" }, {
68-
// "type": "object",
69-
// "description": "Response to 'setBreakpoints' request. Returned is
70-
// information about each breakpoint created by this request. This includes
71-
// the actual code location and whether the breakpoint could be verified.
72-
// The breakpoints returned are in the same order as the elements of the
73-
// 'breakpoints' (or the deprecated 'lines') in the
74-
// SetBreakpointsArguments.", "properties": {
75-
// "body": {
76-
// "type": "object",
77-
// "properties": {
78-
// "breakpoints": {
79-
// "type": "array",
80-
// "items": {
81-
// "$ref": "#/definitions/Breakpoint"
82-
// },
83-
// "description": "Information about the breakpoints. The array
84-
// elements are in the same order as the elements of the
85-
// 'breakpoints' (or the deprecated 'lines') in the
86-
// SetBreakpointsArguments."
87-
// }
88-
// },
89-
// "required": [ "breakpoints" ]
90-
// }
91-
// },
92-
// "required": [ "body" ]
93-
// }]
94-
// },
95-
// "SourceBreakpoint": {
96-
// "type": "object",
97-
// "description": "Properties of a breakpoint or logpoint passed to the
98-
// setBreakpoints request.", "properties": {
99-
// "line": {
100-
// "type": "integer",
101-
// "description": "The source line of the breakpoint or logpoint."
102-
// },
103-
// "column": {
104-
// "type": "integer",
105-
// "description": "An optional source column of the breakpoint."
106-
// },
107-
// "condition": {
108-
// "type": "string",
109-
// "description": "An optional expression for conditional breakpoints."
110-
// },
111-
// "hitCondition": {
112-
// "type": "string",
113-
// "description": "An optional expression that controls how many hits of
114-
// the breakpoint are ignored. The backend is expected to interpret the
115-
// expression as needed."
116-
// },
117-
// "logMessage": {
118-
// "type": "string",
119-
// "description": "If this attribute exists and is non-empty, the backend
120-
// must not 'break' (stop) but log the message instead. Expressions within
121-
// {} are interpolated."
122-
// }
123-
// },
124-
// "required": [ "line" ]
125-
// }
126-
void SetBreakpointsRequestHandler::operator()(
127-
const llvm::json::Object &request) const {
128-
llvm::json::Object response;
129-
lldb::SBError error;
130-
FillResponse(request, response);
131-
const auto *arguments = request.getObject("arguments");
132-
const auto *source = arguments->getObject("source");
133-
const auto path = GetString(source, "path").value_or("");
134-
const auto *breakpoints = arguments->getArray("breakpoints");
135-
llvm::json::Array response_breakpoints;
18+
/// Sets multiple breakpoints for a single source and clears all previous
19+
/// breakpoints in that source. To clear all breakpoint for a source, specify an
20+
/// empty array. When a breakpoint is hit, a `stopped` event (with reason
21+
/// `breakpoint`) is generated.
22+
llvm::Expected<protocol::SetBreakpointsResponseBody>
23+
SetBreakpointsRequestHandler::Run(
24+
const protocol::SetBreakpointsArguments &args) const {
25+
const auto &source = args.source;
26+
const auto path = source.path.value_or("");
27+
std::vector<protocol::Breakpoint> response_breakpoints;
13628

13729
// Decode the source breakpoint infos for this "setBreakpoints" request
13830
SourceBreakpointMap request_bps;
13931
// "breakpoints" may be unset, in which case we treat it the same as being set
14032
// to an empty array.
141-
if (breakpoints) {
142-
for (const auto &bp : *breakpoints) {
143-
const auto *bp_obj = bp.getAsObject();
144-
if (bp_obj) {
145-
SourceBreakpoint src_bp(dap, *bp_obj);
146-
std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(),
147-
src_bp.GetColumn());
148-
request_bps.try_emplace(bp_pos, src_bp);
149-
const auto [iv, inserted] =
150-
dap.source_breakpoints[path].try_emplace(bp_pos, src_bp);
151-
// We check if this breakpoint already exists to update it
152-
if (inserted)
153-
iv->getSecond().SetBreakpoint(path.data());
154-
else
155-
iv->getSecond().UpdateBreakpoint(src_bp);
156-
AppendBreakpoint(&iv->getSecond(), response_breakpoints, path,
157-
src_bp.GetLine());
158-
}
33+
if (args.breakpoints) {
34+
for (const auto &bp : *args.breakpoints) {
35+
SourceBreakpoint src_bp(dap, bp);
36+
std::pair<uint32_t, uint32_t> bp_pos(src_bp.GetLine(),
37+
src_bp.GetColumn());
38+
request_bps.try_emplace(bp_pos, src_bp);
39+
const auto [iv, inserted] =
40+
dap.source_breakpoints[path].try_emplace(bp_pos, src_bp);
41+
// We check if this breakpoint already exists to update it
42+
if (inserted)
43+
iv->getSecond().SetBreakpoint(path.data());
44+
else
45+
iv->getSecond().UpdateBreakpoint(src_bp);
46+
47+
protocol::Breakpoint response_bp = iv->getSecond().ToProtocolBreakpoint();
48+
if (!path.empty() && !response_bp.source)
49+
response_bp.source = CreateSource(path);
50+
if (!response_bp.line)
51+
response_bp.line = src_bp.GetLine();
52+
if (!response_bp.column)
53+
response_bp.column = src_bp.GetColumn();
54+
response_breakpoints.push_back(response_bp);
15955
}
16056
}
16157

@@ -174,10 +70,7 @@ void SetBreakpointsRequestHandler::operator()(
17470
}
17571
}
17672

177-
llvm::json::Object body;
178-
body.try_emplace("breakpoints", std::move(response_breakpoints));
179-
response.try_emplace("body", std::move(body));
180-
dap.SendJSON(llvm::json::Value(std::move(response)));
73+
return protocol::SetBreakpointsResponseBody{std::move(response_breakpoints)};
18174
}
18275

18376
} // namespace lldb_dap

0 commit comments

Comments
 (0)