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
1416namespace 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