|
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
9 | 9 | #include "DAP.h" |
| 10 | +#include "DAPError.h" |
10 | 11 | #include "EventHelper.h" |
11 | 12 | #include "JSONUtils.h" |
12 | 13 | #include "LLDBUtils.h" |
|
18 | 19 |
|
19 | 20 | namespace lldb_dap { |
20 | 21 |
|
21 | | -// "LocationsRequest": { |
22 | | -// "allOf": [ { "$ref": "#/definitions/Request" }, { |
23 | | -// "type": "object", |
24 | | -// "description": "Looks up information about a location reference |
25 | | -// previously returned by the debug adapter.", |
26 | | -// "properties": { |
27 | | -// "command": { |
28 | | -// "type": "string", |
29 | | -// "enum": [ "locations" ] |
30 | | -// }, |
31 | | -// "arguments": { |
32 | | -// "$ref": "#/definitions/LocationsArguments" |
33 | | -// } |
34 | | -// }, |
35 | | -// "required": [ "command", "arguments" ] |
36 | | -// }] |
37 | | -// }, |
38 | | -// "LocationsArguments": { |
39 | | -// "type": "object", |
40 | | -// "description": "Arguments for `locations` request.", |
41 | | -// "properties": { |
42 | | -// "locationReference": { |
43 | | -// "type": "integer", |
44 | | -// "description": "Location reference to resolve." |
45 | | -// } |
46 | | -// }, |
47 | | -// "required": [ "locationReference" ] |
48 | | -// }, |
49 | | -// "LocationsResponse": { |
50 | | -// "allOf": [ { "$ref": "#/definitions/Response" }, { |
51 | | -// "type": "object", |
52 | | -// "description": "Response to `locations` request.", |
53 | | -// "properties": { |
54 | | -// "body": { |
55 | | -// "type": "object", |
56 | | -// "properties": { |
57 | | -// "source": { |
58 | | -// "$ref": "#/definitions/Source", |
59 | | -// "description": "The source containing the location; either |
60 | | -// `source.path` or `source.sourceReference` must be |
61 | | -// specified." |
62 | | -// }, |
63 | | -// "line": { |
64 | | -// "type": "integer", |
65 | | -// "description": "The line number of the location. The client |
66 | | -// capability `linesStartAt1` determines whether it |
67 | | -// is 0- or 1-based." |
68 | | -// }, |
69 | | -// "column": { |
70 | | -// "type": "integer", |
71 | | -// "description": "Position of the location within the `line`. It is |
72 | | -// measured in UTF-16 code units and the client |
73 | | -// capability `columnsStartAt1` determines whether |
74 | | -// it is 0- or 1-based. If no column is given, the |
75 | | -// first position in the start line is assumed." |
76 | | -// }, |
77 | | -// "endLine": { |
78 | | -// "type": "integer", |
79 | | -// "description": "End line of the location, present if the location |
80 | | -// refers to a range. The client capability |
81 | | -// `linesStartAt1` determines whether it is 0- or |
82 | | -// 1-based." |
83 | | -// }, |
84 | | -// "endColumn": { |
85 | | -// "type": "integer", |
86 | | -// "description": "End position of the location within `endLine`, |
87 | | -// present if the location refers to a range. It is |
88 | | -// measured in UTF-16 code units and the client |
89 | | -// capability `columnsStartAt1` determines whether |
90 | | -// it is 0- or 1-based." |
91 | | -// } |
92 | | -// }, |
93 | | -// "required": [ "source", "line" ] |
94 | | -// } |
95 | | -// } |
96 | | -// }] |
97 | | -// }, |
98 | | -void LocationsRequestHandler::operator()( |
99 | | - const llvm::json::Object &request) const { |
100 | | - llvm::json::Object response; |
101 | | - FillResponse(request, response); |
102 | | - auto *arguments = request.getObject("arguments"); |
103 | | - |
104 | | - const auto location_id = |
105 | | - GetInteger<uint64_t>(arguments, "locationReference").value_or(0); |
| 22 | +// Looks up information about a location reference previously returned by the |
| 23 | +// debug adapter. |
| 24 | +llvm::Expected<protocol::LocationsResponseBody> |
| 25 | +LocationsRequestHandler::Run(const protocol::LocationsArguments &args) const { |
| 26 | + protocol::LocationsResponseBody response; |
106 | 27 | // We use the lowest bit to distinguish between value location and declaration |
107 | 28 | // location |
108 | | - auto [var_ref, is_value_location] = UnpackLocation(location_id); |
| 29 | + auto [var_ref, is_value_location] = UnpackLocation(args.locationReference); |
109 | 30 | lldb::SBValue variable = dap.variables.GetVariable(var_ref); |
110 | | - if (!variable.IsValid()) { |
111 | | - response["success"] = false; |
112 | | - response["message"] = "Invalid variable reference"; |
113 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
114 | | - return; |
115 | | - } |
| 31 | + if (!variable.IsValid()) |
| 32 | + return llvm::make_error<DAPError>("Invalid variable reference"); |
116 | 33 |
|
117 | | - llvm::json::Object body; |
118 | 34 | if (is_value_location) { |
119 | 35 | // Get the value location |
120 | 36 | if (!variable.GetType().IsPointerType() && |
121 | | - !variable.GetType().IsReferenceType()) { |
122 | | - response["success"] = false; |
123 | | - response["message"] = |
124 | | - "Value locations are only available for pointers and references"; |
125 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
126 | | - return; |
127 | | - } |
| 37 | + !variable.GetType().IsReferenceType()) |
| 38 | + return llvm::make_error<DAPError>( |
| 39 | + "Value locations are only available for pointers and references"); |
128 | 40 |
|
129 | 41 | lldb::addr_t raw_addr = variable.GetValueAsAddress(); |
130 | 42 | lldb::SBAddress addr = dap.target.ResolveLoadAddress(raw_addr); |
131 | 43 | lldb::SBLineEntry line_entry = GetLineEntryForAddress(dap.target, addr); |
132 | 44 |
|
133 | | - if (!line_entry.IsValid()) { |
134 | | - response["success"] = false; |
135 | | - response["message"] = "Failed to resolve line entry for location"; |
136 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
137 | | - return; |
138 | | - } |
| 45 | + if (!line_entry.IsValid()) |
| 46 | + return llvm::make_error<DAPError>( |
| 47 | + "Failed to resolve line entry for location"); |
139 | 48 |
|
140 | | - const std::optional<protocol::Source> source = |
| 49 | + std::optional<protocol::Source> source = |
141 | 50 | CreateSource(line_entry.GetFileSpec()); |
142 | | - if (!source) { |
143 | | - response["success"] = false; |
144 | | - response["message"] = "Failed to resolve file path for location"; |
145 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
146 | | - return; |
147 | | - } |
| 51 | + if (!source) |
| 52 | + return llvm::make_error<DAPError>( |
| 53 | + "Failed to resolve file path for location"); |
148 | 54 |
|
149 | | - body.try_emplace("source", *source); |
150 | | - if (int line = line_entry.GetLine()) |
151 | | - body.try_emplace("line", line); |
152 | | - if (int column = line_entry.GetColumn()) |
153 | | - body.try_emplace("column", column); |
| 55 | + response.source = std::move(*source); |
| 56 | + response.line = line_entry.GetLine(); |
| 57 | + response.column = line_entry.GetColumn(); |
154 | 58 | } else { |
155 | 59 | // Get the declaration location |
156 | 60 | lldb::SBDeclaration decl = variable.GetDeclaration(); |
157 | | - if (!decl.IsValid()) { |
158 | | - response["success"] = false; |
159 | | - response["message"] = "No declaration location available"; |
160 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
161 | | - return; |
162 | | - } |
| 61 | + if (!decl.IsValid()) |
| 62 | + return llvm::make_error<DAPError>("No declaration location available"); |
163 | 63 |
|
164 | | - const std::optional<protocol::Source> source = |
165 | | - CreateSource(decl.GetFileSpec()); |
166 | | - if (!source) { |
167 | | - response["success"] = false; |
168 | | - response["message"] = "Failed to resolve file path for location"; |
169 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
170 | | - return; |
171 | | - } |
| 64 | + std::optional<protocol::Source> source = CreateSource(decl.GetFileSpec()); |
| 65 | + if (!source) |
| 66 | + return llvm::make_error<DAPError>( |
| 67 | + "Failed to resolve file path for location"); |
172 | 68 |
|
173 | | - body.try_emplace("source", *source); |
174 | | - if (int line = decl.GetLine()) |
175 | | - body.try_emplace("line", line); |
176 | | - if (int column = decl.GetColumn()) |
177 | | - body.try_emplace("column", column); |
| 69 | + response.source = std::move(*source); |
| 70 | + response.line = decl.GetLine(); |
| 71 | + response.column = decl.GetColumn(); |
178 | 72 | } |
179 | 73 |
|
180 | | - response.try_emplace("body", std::move(body)); |
181 | | - dap.SendJSON(llvm::json::Value(std::move(response))); |
| 74 | + return response; |
182 | 75 | } |
183 | 76 |
|
184 | 77 | } // namespace lldb_dap |
0 commit comments