@@ -108,6 +108,10 @@ Dictionary DebugAdapterParser::prepare_error_response(const Dictionary &p_params
108108			error = " missing_device"  ;
109109			error_desc = " There's no connected device with specified id."  ;
110110			break ;
111+ 		case  DAP::ErrorType::MALFORMED_REQUEST:
112+ 			error = " malformed_request"  ;
113+ 			error_desc = " The request is malformed ({details})."  ;
114+ 			break ;
111115		case  DAP::ErrorType::UNKNOWN:
112116		default :
113117			error = " unknown"  ;
@@ -124,6 +128,12 @@ Dictionary DebugAdapterParser::prepare_error_response(const Dictionary &p_params
124128	return  response;
125129}
126130
131+ Dictionary DebugAdapterParser::prepare_malformed_error_response (const  Dictionary &p_params, const  String &p_error) const  {
132+ 	Dictionary variables;
133+ 	variables[" details"  ] = p_error;
134+ 	return  prepare_error_response (p_params, DAP::ErrorType::MALFORMED_REQUEST, variables);
135+ }
136+ 
127137Dictionary DebugAdapterParser::req_initialize (const  Dictionary &p_params) const  {
128138	Dictionary response = prepare_success_response (p_params);
129139	Dictionary args = p_params[" arguments"  ];
@@ -303,36 +313,39 @@ Dictionary DebugAdapterParser::req_pause(const Dictionary &p_params) const {
303313	EditorRunBar::get_singleton ()->get_pause_button ()->set_pressed (true );
304314	EditorDebuggerNode::get_singleton ()->_paused ();
305315
306- 	DebugAdapterProtocol::get_singleton ()->notify_stopped_paused ();
307- 
308316	return  prepare_success_response (p_params);
309317}
310318
311319Dictionary DebugAdapterParser::req_continue (const  Dictionary &p_params) const  {
312320	EditorRunBar::get_singleton ()->get_pause_button ()->set_pressed (false );
313321	EditorDebuggerNode::get_singleton ()->_paused ();
314322
315- 	DebugAdapterProtocol::get_singleton ()->notify_continued ();
316- 
317323	return  prepare_success_response (p_params);
318324}
319325
320326Dictionary DebugAdapterParser::req_threads (const  Dictionary &p_params) const  {
321327	Dictionary response = prepare_success_response (p_params), body;
322328	response[" body"  ] = body;
323329
324- 	DAP::Thread thread;
325- 
326- 	thread.id  = 1 ; //  Hardcoded because Godot only supports debugging one thread at the moment
327- 	thread.name  = " Main"  ;
328- 	Array arr = { thread.to_json () };
329- 	body[" threads"  ] = arr;
330+ 	Array threads;
331+ 	for  (const  KeyValue<Thread::ID, Ref<DebugAdapterProtocol::ThreadData>> &thread_data : DebugAdapterProtocol::get_singleton ()->thread_data_list ) {
332+ 		DAP::Thread thread;
333+ 		thread.id  = thread_data.key ;
334+ 		thread.name  = thread_data.value ->name ;
335+ 		threads.push_back (thread.to_json ());
336+ 	}
330337
338+ 	body[" threads"  ] = threads;
331339	return  response;
332340}
333341
334342Dictionary DebugAdapterParser::req_stackTrace (const  Dictionary &p_params) const  {
335- 	if  (DebugAdapterProtocol::get_singleton ()->_processing_stackdump ) {
343+ 	Dictionary args = p_params[" arguments"  ];
344+ 	Thread::ID thread_id = args[" threadId"  ];
345+ 	ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_data_list .has (thread_id), prepare_malformed_error_response (p_params, vformat (" Unknown thread id: %d"  , thread_id)));
346+ 	const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_data_list [thread_id];
347+ 
348+ 	if  (thread->processing_stackdump ) {
336349		return  Dictionary ();
337350	}
338351
@@ -343,16 +356,8 @@ Dictionary DebugAdapterParser::req_stackTrace(const Dictionary &p_params) const
343356	bool  columns_at_one = DebugAdapterProtocol::get_singleton ()->get_current_peer ()->columnsStartAt1 ;
344357
345358	Array arr;
346- 	DebugAdapterProtocol *dap = DebugAdapterProtocol::get_singleton ();
347- 	for  (DAP::StackFrame sf : dap->stackframe_list ) {
348- 		if  (!lines_at_one) {
349- 			sf.line --;
350- 		}
351- 		if  (!columns_at_one) {
352- 			sf.column --;
353- 		}
354- 
355- 		arr.push_back (sf.to_json ());
359+ 	for  (const  DAP::StackFrame &sf : thread->stackframe_list ) {
360+ 		arr.push_back (sf.to_json (lines_at_one, columns_at_one));
356361	}
357362
358363	body[" stackFrames"  ] = arr;
@@ -415,16 +420,21 @@ Dictionary DebugAdapterParser::req_breakpointLocations(const Dictionary &p_param
415420}
416421
417422Dictionary DebugAdapterParser::req_scopes (const  Dictionary &p_params) const  {
423+ 	using  DAPRemoteID = DebugAdapterProtocol::DAPRemoteID;
424+ 	Dictionary args = p_params[" arguments"  ];
425+ 	DAPRemoteID frame_id = args[" frameId"  ];
426+ 
427+ 	ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup .has (frame_id), prepare_malformed_error_response (p_params, vformat (" Unknown frame id: %d"  , frame_id)));
428+ 	const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup [frame_id];
429+ 	ERR_FAIL_COND_V (!thread->godot_stackframe_ids .has (frame_id), prepare_malformed_error_response (p_params, vformat (" Unknown frame id: %d"  , frame_id)));
430+ 
418431	Dictionary response = prepare_success_response (p_params), body;
419432	response[" body"  ] = body;
420433
421- 	Dictionary args = p_params[" arguments"  ];
422- 	int  frame_id = args[" frameId"  ];
423434	Array scope_list;
424- 
425- 	HashMap<DebugAdapterProtocol::DAPStackFrameID, Vector<int >>::Iterator E = DebugAdapterProtocol::get_singleton ()->scope_list .find (frame_id);
435+ 	HashMap<DAPRemoteID, Vector<DAPRemoteID>>::Iterator E = DebugAdapterProtocol::get_singleton ()->scope_list .find (frame_id);
426436	if  (E) {
427- 		const  Vector<int > &scope_ids = E->value ;
437+ 		const  Vector<DAPRemoteID > &scope_ids = E->value ;
428438		ERR_FAIL_COND_V (scope_ids.size () != 3 , prepare_error_response (p_params, DAP::ErrorType::UNKNOWN));
429439		for  (int  i = 0 ; i < 3 ; ++i) {
430440			DAP::Scope scope;
@@ -447,35 +457,38 @@ Dictionary DebugAdapterParser::req_scopes(const Dictionary &p_params) const {
447457		}
448458	}
449459
450- 	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->request_stack_dump (frame_id);
451- 	DebugAdapterProtocol::get_singleton ()->_current_frame  = frame_id;
460+ 	int  godot_frame_id = thread->godot_stackframe_ids [frame_id];
461+ 	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->request_stack_dump (godot_frame_id);
462+ 	thread->current_frame  = frame_id;
452463
453464	body[" scopes"  ] = scope_list;
454465	return  response;
455466}
456467
457468Dictionary DebugAdapterParser::req_variables (const  Dictionary &p_params) const  {
469+ 	Dictionary args = p_params[" arguments"  ];
470+ 	DebugAdapterProtocol::DAPRemoteID variable_id = args[" variablesReference"  ];
471+ 
472+ 	ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup .has (variable_id), prepare_malformed_error_response (p_params, vformat (" Unknown variable id: %d"  , variable_id)));
473+ 	const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup [variable_id];
474+ 
458475	//  If _remaining_vars > 0, the debuggee is still sending a stack dump to the editor.
459- 	if  (DebugAdapterProtocol::get_singleton ()-> _remaining_vars  > 0 ) {
476+ 	if  (thread-> remaining_vars  > 0 ) {
460477		return  Dictionary ();
461478	}
462479
463- 	Dictionary args = p_params[" arguments"  ];
464- 	int  variable_id = args[" variablesReference"  ];
465- 
466480	if  (HashMap<int , Array>::Iterator E = DebugAdapterProtocol::get_singleton ()->variable_list .find (variable_id); E) {
467481		Dictionary response = prepare_success_response (p_params);
468482		Dictionary body;
469483		response[" body"  ] = body;
470484
471485		if  (!DebugAdapterProtocol::get_singleton ()->get_current_peer ()->supportsVariableType ) {
472- 			for  (int  i = 0 ; i < E->value .size (); i++) {
473- 				Dictionary variable = E->value [i];
486+ 			for  (Dictionary variable : E->value ) {
474487				variable.erase (" type"  );
475488			}
476489		}
477490
478- 		body[" variables"  ] = E ? E ->value  :  Array () ;
491+ 		body[" variables"  ] = E->value ;
479492		return  response;
480493	} else  {
481494		//  If the requested variable is an object, it needs to be requested from the debuggee.
@@ -485,29 +498,55 @@ Dictionary DebugAdapterParser::req_variables(const Dictionary &p_params) const {
485498			return  prepare_error_response (p_params, DAP::ErrorType::UNKNOWN);
486499		}
487500
488- 		DebugAdapterProtocol::get_singleton ()->request_remote_object (object_id);
501+ 		DebugAdapterProtocol::get_singleton ()->request_remote_object (object_id, *thread );
489502	}
490503	return  Dictionary ();
491504}
492505
493506Dictionary DebugAdapterParser::req_next (const  Dictionary &p_params) const  {
507+ 	Dictionary args = p_params[" arguments"  ];
508+ 
509+ 	Thread::ID thread_id = args[" threadId"  ];
510+ 	ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_data_list .has (thread_id), prepare_malformed_error_response (p_params, vformat (" Unknown thread id: %d"  , thread_id)));
511+ 	const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_data_list [thread_id];
512+ 
513+ 	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->debug_select_thread (thread_id);
494514	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->debug_next ();
495- 	DebugAdapterProtocol::get_singleton ()-> _stepping  = true ;
515+ 	thread-> stepping  = true ;
496516
497517	return  prepare_success_response (p_params);
498518}
499519
500520Dictionary DebugAdapterParser::req_stepIn (const  Dictionary &p_params) const  {
521+ 	Dictionary args = p_params[" arguments"  ];
522+ 
523+ 	Thread::ID thread_id = args[" threadId"  ];
524+ 	ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_data_list .has (thread_id), prepare_malformed_error_response (p_params, vformat (" Unknown thread id: %d"  , thread_id)));
525+ 	const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_data_list [thread_id];
526+ 
527+ 	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->debug_select_thread (thread_id);
501528	EditorDebuggerNode::get_singleton ()->get_default_debugger ()->debug_step ();
502- 	DebugAdapterProtocol::get_singleton ()-> _stepping  = true ;
529+ 	thread-> stepping  = true ;
503530
504531	return  prepare_success_response (p_params);
505532}
506533
507534Dictionary DebugAdapterParser::req_evaluate (const  Dictionary &p_params) const  {
508535	Dictionary args = p_params[" arguments"  ];
509536	String expression = args[" expression"  ];
510- 	int  frame_id = args.has (" frameId"  ) ? static_cast <int >(args[" frameId"  ]) : DebugAdapterProtocol::get_singleton ()->_current_frame ;
537+ 
538+ 	int  godot_frame_id;
539+ 	if  (args.has (" frameId"  )) {
540+ 		DebugAdapterProtocol::DAPRemoteID frame_id = static_cast <int >(args[" frameId"  ]);
541+ 
542+ 		ERR_FAIL_COND_V (!DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup .has (frame_id), prepare_malformed_error_response (p_params, vformat (" Unknown frame id: %d"  , frame_id)));
543+ 		const  Ref<DebugAdapterProtocol::ThreadData> &thread = DebugAdapterProtocol::get_singleton ()->thread_remote_data_lookup [frame_id];
544+ 		ERR_FAIL_COND_V (!thread->godot_stackframe_ids .has (frame_id), prepare_malformed_error_response (p_params, vformat (" Unknown frame id: %d"  , frame_id)));
545+ 		godot_frame_id = thread->godot_stackframe_ids [frame_id];
546+ 	} else  {
547+ 		//  If no frame is specified, assume it is top frame, which is 0 on Godot.
548+ 		godot_frame_id = 0 ;
549+ 	}
511550
512551	if  (HashMap<String, DAP::Variable>::Iterator E = DebugAdapterProtocol::get_singleton ()->eval_list .find (expression); E) {
513552		Dictionary response = prepare_success_response (p_params);
@@ -523,7 +562,7 @@ Dictionary DebugAdapterParser::req_evaluate(const Dictionary &p_params) const {
523562		DebugAdapterProtocol::get_singleton ()->eval_list .erase (E->key );
524563		return  response;
525564	} else  {
526- 		DebugAdapterProtocol::get_singleton ()->request_remote_evaluate (expression, frame_id );
565+ 		DebugAdapterProtocol::get_singleton ()->request_remote_evaluate (expression, godot_frame_id );
527566	}
528567	return  Dictionary ();
529568}
@@ -564,7 +603,7 @@ Dictionary DebugAdapterParser::ev_terminated() const {
564603	return  event;
565604}
566605
567- Dictionary DebugAdapterParser::ev_exited (const   int  & p_exitcode) const  {
606+ Dictionary DebugAdapterParser::ev_exited (int  p_exitcode) const  {
568607	Dictionary event = prepare_base_event (), body;
569608	event[" event"  ] = " exited"  ;
570609	event[" body"  ] = body;
@@ -574,18 +613,18 @@ Dictionary DebugAdapterParser::ev_exited(const int &p_exitcode) const {
574613	return  event;
575614}
576615
577- Dictionary DebugAdapterParser::ev_stopped () const  {
616+ Dictionary DebugAdapterParser::ev_stopped (Thread::ID p_thread_id ) const  {
578617	Dictionary event = prepare_base_event (), body;
579618	event[" event"  ] = " stopped"  ;
580619	event[" body"  ] = body;
581620
582- 	body[" threadId"  ] = 1 ;
621+ 	body[" threadId"  ] = p_thread_id ;
583622
584623	return  event;
585624}
586625
587- Dictionary DebugAdapterParser::ev_stopped_paused () const  {
588- 	Dictionary event = ev_stopped ();
626+ Dictionary DebugAdapterParser::ev_stopped_paused (Thread::ID thread_id ) const  {
627+ 	Dictionary event = ev_stopped (thread_id );
589628	Dictionary body = event[" body"  ];
590629
591630	body[" reason"  ] = " paused"  ;
@@ -594,8 +633,8 @@ Dictionary DebugAdapterParser::ev_stopped_paused() const {
594633	return  event;
595634}
596635
597- Dictionary DebugAdapterParser::ev_stopped_exception (const  String &p_error) const  {
598- 	Dictionary event = ev_stopped ();
636+ Dictionary DebugAdapterParser::ev_stopped_exception (const  String &p_error, Thread::ID p_thread_id ) const  {
637+ 	Dictionary event = ev_stopped (p_thread_id );
599638	Dictionary body = event[" body"  ];
600639
601640	body[" reason"  ] = " exception"  ;
@@ -605,8 +644,8 @@ Dictionary DebugAdapterParser::ev_stopped_exception(const String &p_error) const
605644	return  event;
606645}
607646
608- Dictionary DebugAdapterParser::ev_stopped_breakpoint (const   int  & p_id) const  {
609- 	Dictionary event = ev_stopped ();
647+ Dictionary DebugAdapterParser::ev_stopped_breakpoint (int  p_id, Thread::ID p_thread_id ) const  {
648+ 	Dictionary event = ev_stopped (p_thread_id );
610649	Dictionary body = event[" body"  ];
611650
612651	body[" reason"  ] = " breakpoint"  ;
@@ -618,8 +657,8 @@ Dictionary DebugAdapterParser::ev_stopped_breakpoint(const int &p_id) const {
618657	return  event;
619658}
620659
621- Dictionary DebugAdapterParser::ev_stopped_step () const  {
622- 	Dictionary event = ev_stopped ();
660+ Dictionary DebugAdapterParser::ev_stopped_step (Thread::ID p_thread_id ) const  {
661+ 	Dictionary event = ev_stopped (p_thread_id );
623662	Dictionary body = event[" body"  ];
624663
625664	body[" reason"  ] = " step"  ;
@@ -628,12 +667,12 @@ Dictionary DebugAdapterParser::ev_stopped_step() const {
628667	return  event;
629668}
630669
631- Dictionary DebugAdapterParser::ev_continued () const  {
670+ Dictionary DebugAdapterParser::ev_continued (Thread::ID p_thread_id ) const  {
632671	Dictionary event = prepare_base_event (), body;
633672	event[" event"  ] = " continued"  ;
634673	event[" body"  ] = body;
635674
636- 	body[" threadId"  ] = 1 ;
675+ 	body[" threadId"  ] = p_thread_id ;
637676
638677	return  event;
639678}
@@ -649,7 +688,7 @@ Dictionary DebugAdapterParser::ev_output(const String &p_message, RemoteDebugger
649688	return  event;
650689}
651690
652- Dictionary DebugAdapterParser::ev_breakpoint (const  DAP::Breakpoint &p_breakpoint, const   bool  & p_enabled) const  {
691+ Dictionary DebugAdapterParser::ev_breakpoint (const  DAP::Breakpoint &p_breakpoint, bool  p_enabled) const  {
653692	Dictionary event = prepare_base_event (), body;
654693	event[" event"  ] = " breakpoint"  ;
655694	event[" body"  ] = body;
0 commit comments