99#include " DAP.h"
1010#include " EventHelper.h"
1111#include " JSONUtils.h"
12+ #include " Protocol/ProtocolRequests.h"
1213#include " RequestHandler.h"
1314#include " lldb/API/SBEvent.h"
1415#include " lldb/API/SBListener.h"
1516#include " lldb/API/SBStream.h"
1617
1718using namespace lldb ;
19+ using namespace lldb_dap ::protocol;
1820
1921namespace lldb_dap {
2022
@@ -229,136 +231,46 @@ static void EventThreadFunction(DAP &dap) {
229231 }
230232}
231233
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 ;
320238
321239 // Do not source init files until in/out/err are configured.
322240 dap.debugger = lldb::SBDebugger::Create (false );
323241 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 ();
331246 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 ();
339251 dap.debugger .SetErrorFile (lldb::SBFile (*err_fd, " w" , false ));
340252
341253 auto interp = dap.debugger .GetCommandInterpreter ();
342254
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 )) {
344259 dap.debugger .SkipLLDBInitFiles (false );
345260 dap.debugger .SkipAppInitFiles (false );
346261 lldb::SBCommandReturnObject init;
347262 interp.SourceInitFileInGlobalDirectory (init);
348263 interp.SourceInitFileInHomeDirectory (init);
349264 }
350265
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;
357268
358269 dap.PopulateExceptionBreakpoints ();
359270 auto cmd = dap.debugger .GetCommandInterpreter ().AddMultiwordCommand (
360271 " lldb-dap" , " Commands for managing lldb-dap." );
361- if (GetBoolean (arguments, " supportsStartDebuggingRequest" ).value_or (false )) {
272+ if (arguments.supportedFeatures .contains (
273+ eClientFeatureStartDebuggingRequest)) {
362274 cmd.AddCommand (
363275 " start-debugging" , new StartDebuggingRequestHandler (dap),
364276 " Sends a startDebugging request from the debug adapter to the client "
@@ -370,37 +282,15 @@ void InitializeRequestHandler::operator()(
370282 cmd.AddCommand (" send-event" , new SendEventRequestHandler (dap),
371283 " Sends an DAP event to the client." );
372284
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));
375288
376289 // Start our event thread so we can receive events from the debugger, target,
377290 // process and more.
378291 dap.event_thread = std::thread (EventThreadFunction, std::ref (dap));
379292
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 ();
404294}
405295
406296} // namespace lldb_dap
0 commit comments