9
9
#include " DAP.h"
10
10
#include " EventHelper.h"
11
11
#include " JSONUtils.h"
12
+ #include " Protocol/ProtocolRequests.h"
12
13
#include " RequestHandler.h"
13
14
#include " lldb/API/SBEvent.h"
14
15
#include " lldb/API/SBListener.h"
15
16
#include " lldb/API/SBStream.h"
16
17
17
18
using namespace lldb ;
19
+ using namespace lldb_dap ::protocol;
18
20
19
21
namespace lldb_dap {
20
22
@@ -229,136 +231,46 @@ static void EventThreadFunction(DAP &dap) {
229
231
}
230
232
}
231
233
232
- // "InitializeRequest": {
233
- // "allOf": [ { "$ref": "#/definitions/Request" }, {
234
- // "type": "object",
235
- // "description": "Initialize request; value of command field is
236
- // 'initialize'.",
237
- // "properties": {
238
- // "command": {
239
- // "type": "string",
240
- // "enum": [ "initialize" ]
241
- // },
242
- // "arguments": {
243
- // "$ref": "#/definitions/InitializeRequestArguments"
244
- // }
245
- // },
246
- // "required": [ "command", "arguments" ]
247
- // }]
248
- // },
249
- // "InitializeRequestArguments": {
250
- // "type": "object",
251
- // "description": "Arguments for 'initialize' request.",
252
- // "properties": {
253
- // "clientID": {
254
- // "type": "string",
255
- // "description": "The ID of the (frontend) client using this adapter."
256
- // },
257
- // "adapterID": {
258
- // "type": "string",
259
- // "description": "The ID of the debug adapter."
260
- // },
261
- // "locale": {
262
- // "type": "string",
263
- // "description": "The ISO-639 locale of the (frontend) client using
264
- // this adapter, e.g. en-US or de-CH."
265
- // },
266
- // "linesStartAt1": {
267
- // "type": "boolean",
268
- // "description": "If true all line numbers are 1-based (default)."
269
- // },
270
- // "columnsStartAt1": {
271
- // "type": "boolean",
272
- // "description": "If true all column numbers are 1-based (default)."
273
- // },
274
- // "pathFormat": {
275
- // "type": "string",
276
- // "_enum": [ "path", "uri" ],
277
- // "description": "Determines in what format paths are specified. The
278
- // default is 'path', which is the native format."
279
- // },
280
- // "supportsVariableType": {
281
- // "type": "boolean",
282
- // "description": "Client supports the optional type attribute for
283
- // variables."
284
- // },
285
- // "supportsVariablePaging": {
286
- // "type": "boolean",
287
- // "description": "Client supports the paging of variables."
288
- // },
289
- // "supportsRunInTerminalRequest": {
290
- // "type": "boolean",
291
- // "description": "Client supports the runInTerminal request."
292
- // }
293
- // },
294
- // "required": [ "adapterID" ]
295
- // },
296
- // "InitializeResponse": {
297
- // "allOf": [ { "$ref": "#/definitions/Response" }, {
298
- // "type": "object",
299
- // "description": "Response to 'initialize' request.",
300
- // "properties": {
301
- // "body": {
302
- // "$ref": "#/definitions/Capabilities",
303
- // "description": "The capabilities of this debug adapter."
304
- // }
305
- // }
306
- // }]
307
- // }
308
- void InitializeRequestHandler::operator ()(
309
- const llvm::json::Object &request) const {
310
- llvm::json::Object response;
311
- FillResponse (request, response);
312
- llvm::json::Object body;
313
-
314
- const auto *arguments = request.getObject (" arguments" );
315
- // sourceInitFile option is not from formal DAP specification. It is only
316
- // used by unit tests to prevent sourcing .lldbinit files from environment
317
- // which may affect the outcome of tests.
318
- bool source_init_file =
319
- GetBoolean (arguments, " sourceInitFile" ).value_or (true );
234
+ // / Initialize request; value of command field is 'initialize'.
235
+ llvm::Expected<InitializeResponseBody> InitializeRequestHandler::Run (
236
+ const InitializeRequestArguments &arguments) const {
237
+ dap.clientFeatures = arguments.supportedFeatures ;
320
238
321
239
// Do not source init files until in/out/err are configured.
322
240
dap.debugger = lldb::SBDebugger::Create (false );
323
241
dap.debugger .SetInputFile (dap.in );
324
- auto out_fd = dap.out .GetWriteFileDescriptor ();
325
- if (llvm::Error err = out_fd.takeError ()) {
326
- response[" success" ] = false ;
327
- EmplaceSafeString (response, " message" , llvm::toString (std::move (err)));
328
- dap.SendJSON (llvm::json::Value (std::move (response)));
329
- return ;
330
- }
242
+
243
+ llvm::Expected<int > out_fd = dap.out .GetWriteFileDescriptor ();
244
+ if (!out_fd)
245
+ return out_fd.takeError ();
331
246
dap.debugger .SetOutputFile (lldb::SBFile (*out_fd, " w" , false ));
332
- auto err_fd = dap.err .GetWriteFileDescriptor ();
333
- if (llvm::Error err = err_fd.takeError ()) {
334
- response[" success" ] = false ;
335
- EmplaceSafeString (response, " message" , llvm::toString (std::move (err)));
336
- dap.SendJSON (llvm::json::Value (std::move (response)));
337
- return ;
338
- }
247
+
248
+ llvm::Expected<int > err_fd = dap.err .GetWriteFileDescriptor ();
249
+ if (!err_fd)
250
+ return err_fd.takeError ();
339
251
dap.debugger .SetErrorFile (lldb::SBFile (*err_fd, " w" , false ));
340
252
341
253
auto interp = dap.debugger .GetCommandInterpreter ();
342
254
343
- if (source_init_file) {
255
+ // The sourceInitFile option is not part of the DAP specification. It is an
256
+ // extension used by the test suite to prevent sourcing `.lldbinit` and
257
+ // changing its behavior.
258
+ if (arguments.lldbExtSourceInitFile .value_or (true )) {
344
259
dap.debugger .SkipLLDBInitFiles (false );
345
260
dap.debugger .SkipAppInitFiles (false );
346
261
lldb::SBCommandReturnObject init;
347
262
interp.SourceInitFileInGlobalDirectory (init);
348
263
interp.SourceInitFileInHomeDirectory (init);
349
264
}
350
265
351
- if (llvm::Error err = dap.RunPreInitCommands ()) {
352
- response[" success" ] = false ;
353
- EmplaceSafeString (response, " message" , llvm::toString (std::move (err)));
354
- dap.SendJSON (llvm::json::Value (std::move (response)));
355
- return ;
356
- }
266
+ if (llvm::Error err = dap.RunPreInitCommands ())
267
+ return err;
357
268
358
269
dap.PopulateExceptionBreakpoints ();
359
270
auto cmd = dap.debugger .GetCommandInterpreter ().AddMultiwordCommand (
360
271
" lldb-dap" , " Commands for managing lldb-dap." );
361
- if (GetBoolean (arguments, " supportsStartDebuggingRequest" ).value_or (false )) {
272
+ if (arguments.supportedFeatures .contains (
273
+ eClientFeatureStartDebuggingRequest)) {
362
274
cmd.AddCommand (
363
275
" start-debugging" , new StartDebuggingRequestHandler (dap),
364
276
" Sends a startDebugging request from the debug adapter to the client "
@@ -370,37 +282,15 @@ void InitializeRequestHandler::operator()(
370
282
cmd.AddCommand (" send-event" , new SendEventRequestHandler (dap),
371
283
" Sends an DAP event to the client." );
372
284
373
- dap.progress_event_thread =
374
- std::thread (ProgressEventThreadFunction, std::ref (dap));
285
+ if (arguments.supportedFeatures .contains (eClientFeatureProgressReporting))
286
+ dap.progress_event_thread =
287
+ std::thread (ProgressEventThreadFunction, std::ref (dap));
375
288
376
289
// Start our event thread so we can receive events from the debugger, target,
377
290
// process and more.
378
291
dap.event_thread = std::thread (EventThreadFunction, std::ref (dap));
379
292
380
- llvm::StringMap<bool > capabilities = dap.GetCapabilities ();
381
- for (auto &kv : capabilities)
382
- body.try_emplace (kv.getKey (), kv.getValue ());
383
-
384
- // Available filters or options for the setExceptionBreakpoints request.
385
- llvm::json::Array filters;
386
- for (const auto &exc_bp : *dap.exception_breakpoints )
387
- filters.emplace_back (CreateExceptionBreakpointFilter (exc_bp));
388
- body.try_emplace (" exceptionBreakpointFilters" , std::move (filters));
389
-
390
- llvm::json::Array completion_characters;
391
- completion_characters.emplace_back (" ." );
392
- completion_characters.emplace_back (" " );
393
- completion_characters.emplace_back (" \t " );
394
- body.try_emplace (" completionTriggerCharacters" ,
395
- std::move (completion_characters));
396
-
397
- // Put in non-DAP specification lldb specific information.
398
- llvm::json::Object lldb_json;
399
- lldb_json.try_emplace (" version" , dap.debugger .GetVersionString ());
400
- body.try_emplace (" __lldb" , std::move (lldb_json));
401
-
402
- response.try_emplace (" body" , std::move (body));
403
- dap.SendJSON (llvm::json::Value (std::move (response)));
293
+ return dap.GetCapabilities ();
404
294
}
405
295
406
296
} // namespace lldb_dap
0 commit comments