feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -144,9 +144,7 @@ Dictionary DebugAdapterParser::req_initialize(const Dictionary &p_params) const
|
|||
// Send all current breakpoints
|
||||
List<String> breakpoints;
|
||||
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
|
||||
for (List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
|
||||
String breakpoint = E->get();
|
||||
|
||||
for (const String &breakpoint : breakpoints) {
|
||||
String path = breakpoint.left(breakpoint.find_char(':', 6)); // Skip initial part of path, aka "res://"
|
||||
int line = breakpoint.substr(path.size()).to_int();
|
||||
|
||||
|
|
@ -301,12 +299,11 @@ Dictionary DebugAdapterParser::req_threads(const Dictionary &p_params) const {
|
|||
Dictionary response = prepare_success_response(p_params), body;
|
||||
response["body"] = body;
|
||||
|
||||
Array arr;
|
||||
DAP::Thread thread;
|
||||
|
||||
thread.id = 1; // Hardcoded because Godot only supports debugging one thread at the moment
|
||||
thread.name = "Main";
|
||||
arr.push_back(thread.to_json());
|
||||
Array arr = { thread.to_json() };
|
||||
body["threads"] = arr;
|
||||
|
||||
return response;
|
||||
|
|
@ -325,8 +322,7 @@ Dictionary DebugAdapterParser::req_stackTrace(const Dictionary &p_params) const
|
|||
|
||||
Array arr;
|
||||
DebugAdapterProtocol *dap = DebugAdapterProtocol::get_singleton();
|
||||
for (const KeyValue<DAP::StackFrame, List<int>> &E : dap->stackframe_list) {
|
||||
DAP::StackFrame sf = E.key;
|
||||
for (DAP::StackFrame sf : dap->stackframe_list) {
|
||||
if (!lines_at_one) {
|
||||
sf.line--;
|
||||
}
|
||||
|
|
@ -360,7 +356,7 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) co
|
|||
|
||||
// If path contains \, it's a Windows path, so we need to convert it to /, and make the drive letter uppercase
|
||||
if (source.path.contains_char('\\')) {
|
||||
source.path = source.path.replace("\\", "/");
|
||||
source.path = source.path.replace_char('\\', '/');
|
||||
source.path = source.path.substr(0, 1).to_upper() + source.path.substr(1);
|
||||
}
|
||||
|
||||
|
|
@ -372,6 +368,8 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) co
|
|||
lines.push_back(breakpoint.line + !lines_at_one);
|
||||
}
|
||||
|
||||
// Always update the source checksum for the requested path, as it might have been modified externally.
|
||||
DebugAdapterProtocol::get_singleton()->update_source(source.path);
|
||||
Array updated_breakpoints = DebugAdapterProtocol::get_singleton()->update_breakpoints(source.path, lines);
|
||||
body["breakpoints"] = updated_breakpoints;
|
||||
|
||||
|
|
@ -383,13 +381,12 @@ Dictionary DebugAdapterParser::req_breakpointLocations(const Dictionary &p_param
|
|||
response["body"] = body;
|
||||
Dictionary args = p_params["arguments"];
|
||||
|
||||
Array locations;
|
||||
DAP::BreakpointLocation location;
|
||||
location.line = args["line"];
|
||||
if (args.has("endLine")) {
|
||||
location.endLine = args["endLine"];
|
||||
}
|
||||
locations.push_back(location.to_json());
|
||||
Array locations = { location.to_json() };
|
||||
|
||||
body["breakpoints"] = locations;
|
||||
return response;
|
||||
|
|
@ -403,15 +400,13 @@ Dictionary DebugAdapterParser::req_scopes(const Dictionary &p_params) const {
|
|||
int frame_id = args["frameId"];
|
||||
Array scope_list;
|
||||
|
||||
DAP::StackFrame frame;
|
||||
frame.id = frame_id;
|
||||
HashMap<DAP::StackFrame, List<int>, DAP::StackFrame>::Iterator E = DebugAdapterProtocol::get_singleton()->stackframe_list.find(frame);
|
||||
HashMap<DebugAdapterProtocol::DAPStackFrameID, Vector<int>>::Iterator E = DebugAdapterProtocol::get_singleton()->scope_list.find(frame_id);
|
||||
if (E) {
|
||||
ERR_FAIL_COND_V(E->value.size() != 3, prepare_error_response(p_params, DAP::ErrorType::UNKNOWN));
|
||||
List<int>::ConstIterator itr = E->value.begin();
|
||||
for (int i = 0; i < 3; ++itr, ++i) {
|
||||
const Vector<int> &scope_ids = E->value;
|
||||
ERR_FAIL_COND_V(scope_ids.size() != 3, prepare_error_response(p_params, DAP::ErrorType::UNKNOWN));
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
DAP::Scope scope;
|
||||
scope.variablesReference = *itr;
|
||||
scope.variablesReference = scope_ids[i];
|
||||
switch (i) {
|
||||
case 0:
|
||||
scope.name = "Locals";
|
||||
|
|
@ -595,8 +590,7 @@ Dictionary DebugAdapterParser::ev_stopped_breakpoint(const int &p_id) const {
|
|||
body["reason"] = "breakpoint";
|
||||
body["description"] = "Breakpoint";
|
||||
|
||||
Array breakpoints;
|
||||
breakpoints.push_back(p_id);
|
||||
Array breakpoints = { p_id };
|
||||
body["hitBreakpointIds"] = breakpoints;
|
||||
|
||||
return event;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEBUG_ADAPTER_PARSER_H
|
||||
#define DEBUG_ADAPTER_PARSER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/debugger/remote_debugger.h"
|
||||
|
|
@ -49,7 +48,7 @@ private:
|
|||
// If path contains \, it's a Windows path, so we need to convert it to /, and check as case-insensitive.
|
||||
if (p_path.contains_char('\\')) {
|
||||
String project_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
String path = p_path.replace("\\", "/");
|
||||
String path = p_path.replace_char('\\', '/');
|
||||
return path.containsn(project_path);
|
||||
}
|
||||
return p_path.begins_with(ProjectSettings::get_singleton()->get_resource_path());
|
||||
|
|
@ -103,5 +102,3 @@ public:
|
|||
Dictionary ev_custom_data(const String &p_msg, const Array &p_data) const;
|
||||
Dictionary ev_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) const;
|
||||
};
|
||||
|
||||
#endif // DEBUG_ADAPTER_PARSER_H
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ Error DAPeer::handle_data() {
|
|||
// End of headers
|
||||
if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
|
||||
r[l - 3] = '\0'; // Null terminate to read string
|
||||
String header;
|
||||
header.parse_utf8(r);
|
||||
String header = String::utf8(r);
|
||||
content_length = header.substr(16).to_int();
|
||||
has_header = true;
|
||||
req_pos = 0;
|
||||
|
|
@ -93,8 +92,7 @@ Error DAPeer::handle_data() {
|
|||
}
|
||||
|
||||
// Parse data
|
||||
String msg;
|
||||
msg.parse_utf8((const char *)req_buf, req_pos);
|
||||
String msg = String::utf8((const char *)req_buf, req_pos);
|
||||
|
||||
// Apply a timestamp if it there's none yet
|
||||
if (!timestamp) {
|
||||
|
|
@ -118,12 +116,12 @@ Error DAPeer::send_data() {
|
|||
if (!data.has("seq")) {
|
||||
data["seq"] = ++seq;
|
||||
}
|
||||
String formatted_data = format_output(data);
|
||||
const Vector<uint8_t> &formatted_data = format_output(data);
|
||||
|
||||
int data_sent = 0;
|
||||
while (data_sent < formatted_data.length()) {
|
||||
while (data_sent < formatted_data.size()) {
|
||||
int curr_sent = 0;
|
||||
Error err = connection->put_partial_data((const uint8_t *)formatted_data.utf8().get_data(), formatted_data.size() - data_sent - 1, curr_sent);
|
||||
Error err = connection->put_partial_data(formatted_data.ptr() + data_sent, formatted_data.size() - data_sent, curr_sent);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -134,15 +132,12 @@ Error DAPeer::send_data() {
|
|||
return OK;
|
||||
}
|
||||
|
||||
String DAPeer::format_output(const Dictionary &p_params) const {
|
||||
String response = Variant(p_params).to_json_string();
|
||||
String header = "Content-Length: ";
|
||||
CharString charstr = response.utf8();
|
||||
size_t len = charstr.length();
|
||||
header += itos(len);
|
||||
header += "\r\n\r\n";
|
||||
Vector<uint8_t> DAPeer::format_output(const Dictionary &p_params) const {
|
||||
const Vector<uint8_t> &content = Variant(p_params).to_json_string().to_utf8_buffer();
|
||||
Vector<uint8_t> response = vformat("Content-Length: %d\r\n\r\n", content.size()).to_utf8_buffer();
|
||||
|
||||
return header + response;
|
||||
response.append_array(content);
|
||||
return response;
|
||||
}
|
||||
|
||||
Error DebugAdapterProtocol::on_client_connected() {
|
||||
|
|
@ -176,6 +171,7 @@ void DebugAdapterProtocol::reset_current_info() {
|
|||
void DebugAdapterProtocol::reset_ids() {
|
||||
breakpoint_id = 0;
|
||||
breakpoint_list.clear();
|
||||
breakpoint_source_list.clear();
|
||||
|
||||
reset_stack_info();
|
||||
}
|
||||
|
|
@ -185,6 +181,7 @@ void DebugAdapterProtocol::reset_stack_info() {
|
|||
variable_id = 1;
|
||||
|
||||
stackframe_list.clear();
|
||||
scope_list.clear();
|
||||
variable_list.clear();
|
||||
object_list.clear();
|
||||
object_pending_set.clear();
|
||||
|
|
@ -205,9 +202,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
x.value = rtos(vec.x);
|
||||
y.value = rtos(vec.y);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
Array arr = { x.to_json(), y.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -230,11 +225,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
w.value = rtos(rect.size.x);
|
||||
h.value = rtos(rect.size.y);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
arr.push_back(w.to_json());
|
||||
arr.push_back(h.to_json());
|
||||
Array arr = { x.to_json(), y.to_json(), w.to_json(), h.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -254,10 +245,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
y.value = rtos(vec.y);
|
||||
z.value = rtos(vec.z);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
arr.push_back(z.to_json());
|
||||
Array arr = { x.to_json(), y.to_json(), z.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -279,10 +267,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
y.variablesReference = parse_variant(transform.columns[1]);
|
||||
origin.variablesReference = parse_variant(transform.columns[2]);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
arr.push_back(origin.to_json());
|
||||
Array arr = { x.to_json(), y.to_json(), origin.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -298,9 +283,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
normal.value = plane.normal;
|
||||
normal.variablesReference = parse_variant(plane.normal);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(d.to_json());
|
||||
arr.push_back(normal.to_json());
|
||||
Array arr = { d.to_json(), normal.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -322,11 +305,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
z.value = rtos(quat.z);
|
||||
w.value = rtos(quat.w);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
arr.push_back(z.to_json());
|
||||
arr.push_back(w.to_json());
|
||||
Array arr = { x.to_json(), y.to_json(), z.to_json(), w.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -344,9 +323,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
position.variablesReference = parse_variant(aabb.position);
|
||||
size.variablesReference = parse_variant(aabb.size);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(position.to_json());
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { position.to_json(), size.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -368,10 +345,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
y.variablesReference = parse_variant(basis.rows[1]);
|
||||
z.variablesReference = parse_variant(basis.rows[2]);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(x.to_json());
|
||||
arr.push_back(y.to_json());
|
||||
arr.push_back(z.to_json());
|
||||
Array arr = { x.to_json(), y.to_json(), z.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -388,9 +362,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
basis.variablesReference = parse_variant(transform.basis);
|
||||
origin.variablesReference = parse_variant(transform.origin);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(basis.to_json());
|
||||
arr.push_back(origin.to_json());
|
||||
Array arr = { basis.to_json(), origin.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -412,11 +384,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
b.value = rtos(color.b);
|
||||
a.value = rtos(color.a);
|
||||
|
||||
Array arr;
|
||||
arr.push_back(r.to_json());
|
||||
arr.push_back(g.to_json());
|
||||
arr.push_back(b.to_json());
|
||||
arr.push_back(a.to_json());
|
||||
Array arr = { r.to_json(), g.to_json(), b.to_json(), a.to_json() };
|
||||
variable_list.insert(id, arr);
|
||||
return id;
|
||||
}
|
||||
|
|
@ -428,8 +396,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -447,10 +414,10 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
Dictionary dictionary = p_var;
|
||||
Array arr;
|
||||
|
||||
for (int i = 0; i < dictionary.size(); i++) {
|
||||
for (const KeyValue<Variant, Variant> &kv : dictionary) {
|
||||
DAP::Variable var;
|
||||
var.name = dictionary.get_key_at_index(i);
|
||||
Variant value = dictionary.get_value_at_index(i);
|
||||
var.name = kv.key;
|
||||
Variant value = kv.value;
|
||||
var.type = Variant::get_type_name(value.get_type());
|
||||
var.value = value;
|
||||
var.variablesReference = parse_variant(value);
|
||||
|
|
@ -467,8 +434,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -488,8 +454,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -509,8 +474,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -530,8 +494,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -551,8 +514,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -572,8 +534,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -593,8 +554,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -615,8 +575,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -637,8 +596,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
|
|||
size.type = Variant::get_type_name(Variant::INT);
|
||||
size.value = itos(array.size());
|
||||
|
||||
Array arr;
|
||||
arr.push_back(size.to_json());
|
||||
Array arr = { size.to_json() };
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
DAP::Variable var;
|
||||
|
|
@ -843,7 +801,9 @@ bool DebugAdapterProtocol::request_remote_object(const ObjectID &p_object_id) {
|
|||
return false;
|
||||
}
|
||||
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->request_remote_object(p_object_id);
|
||||
TypedArray<uint64_t> arr;
|
||||
arr.append(p_object_id);
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->request_remote_objects(arr);
|
||||
object_pending_set.insert(p_object_id);
|
||||
|
||||
return true;
|
||||
|
|
@ -861,6 +821,30 @@ bool DebugAdapterProtocol::request_remote_evaluate(const String &p_eval, int p_s
|
|||
return true;
|
||||
}
|
||||
|
||||
const DAP::Source &DebugAdapterProtocol::fetch_source(const String &p_path) {
|
||||
const String &global_path = ProjectSettings::get_singleton()->globalize_path(p_path);
|
||||
|
||||
HashMap<String, DAP::Source>::Iterator E = breakpoint_source_list.find(global_path);
|
||||
if (E != breakpoint_source_list.end()) {
|
||||
return E->value;
|
||||
}
|
||||
DAP::Source &added_source = breakpoint_source_list.insert(global_path, DAP::Source())->value;
|
||||
added_source.name = global_path.get_file();
|
||||
added_source.path = global_path;
|
||||
added_source.compute_checksums();
|
||||
|
||||
return added_source;
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::update_source(const String &p_path) {
|
||||
const String &global_path = ProjectSettings::get_singleton()->globalize_path(p_path);
|
||||
|
||||
HashMap<String, DAP::Source>::Iterator E = breakpoint_source_list.find(global_path);
|
||||
if (E != breakpoint_source_list.end()) {
|
||||
E->value.compute_checksums();
|
||||
}
|
||||
}
|
||||
|
||||
bool DebugAdapterProtocol::process_message(const String &p_text) {
|
||||
JSON json;
|
||||
ERR_FAIL_COND_V_MSG(json.parse(p_text) != OK, true, "Malformed message!");
|
||||
|
|
@ -878,8 +862,7 @@ bool DebugAdapterProtocol::process_message(const String &p_text) {
|
|||
if (parser->has_method(command)) {
|
||||
_current_request = params["command"];
|
||||
|
||||
Array args;
|
||||
args.push_back(params);
|
||||
Array args = { params };
|
||||
Dictionary response = parser->callv(command, args);
|
||||
if (!response.is_empty()) {
|
||||
_current_peer->res_queue.push_front(response);
|
||||
|
|
@ -904,66 +887,66 @@ void DebugAdapterProtocol::notify_process() {
|
|||
String launch_mode = _current_peer->attached ? "attach" : "launch";
|
||||
|
||||
Dictionary event = parser->ev_process(launch_mode);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_terminated() {
|
||||
Dictionary event = parser->ev_terminated();
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
if ((_current_request == "launch" || _current_request == "restart") && _current_peer == E->get()) {
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
if ((_current_request == "launch" || _current_request == "restart") && _current_peer == peer) {
|
||||
continue;
|
||||
}
|
||||
E->get()->res_queue.push_back(event);
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_exited(const int &p_exitcode) {
|
||||
Dictionary event = parser->ev_exited(p_exitcode);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
if ((_current_request == "launch" || _current_request == "restart") && _current_peer == E->get()) {
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
if ((_current_request == "launch" || _current_request == "restart") && _current_peer == peer) {
|
||||
continue;
|
||||
}
|
||||
E->get()->res_queue.push_back(event);
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_stopped_paused() {
|
||||
Dictionary event = parser->ev_stopped_paused();
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_stopped_exception(const String &p_error) {
|
||||
Dictionary event = parser->ev_stopped_exception(p_error);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_stopped_breakpoint(const int &p_id) {
|
||||
Dictionary event = parser->ev_stopped_breakpoint(p_id);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_stopped_step() {
|
||||
Dictionary event = parser->ev_stopped_step();
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_continued() {
|
||||
Dictionary event = parser->ev_continued();
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
if (_current_request == "continue" && E->get() == _current_peer) {
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
if (_current_request == "continue" && peer == _current_peer) {
|
||||
continue;
|
||||
}
|
||||
E->get()->res_queue.push_back(event);
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
|
||||
reset_stack_info();
|
||||
|
|
@ -971,15 +954,14 @@ void DebugAdapterProtocol::notify_continued() {
|
|||
|
||||
void DebugAdapterProtocol::notify_output(const String &p_message, RemoteDebugger::MessageType p_type) {
|
||||
Dictionary event = parser->ev_output(p_message, p_type);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->res_queue.push_back(event);
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::notify_custom_data(const String &p_msg, const Array &p_data) {
|
||||
Dictionary event = parser->ev_custom_data(p_msg, p_data);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
Ref<DAPeer> peer = E->get();
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
if (peer->supportsCustomData) {
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
|
|
@ -988,11 +970,11 @@ void DebugAdapterProtocol::notify_custom_data(const String &p_msg, const Array &
|
|||
|
||||
void DebugAdapterProtocol::notify_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) {
|
||||
Dictionary event = parser->ev_breakpoint(p_breakpoint, p_enabled);
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
if (_current_request == "setBreakpoints" && E->get() == _current_peer) {
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
if (_current_request == "setBreakpoints" && peer == _current_peer) {
|
||||
continue;
|
||||
}
|
||||
E->get()->res_queue.push_back(event);
|
||||
peer->res_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1001,23 +983,40 @@ Array DebugAdapterProtocol::update_breakpoints(const String &p_path, const Array
|
|||
|
||||
// Add breakpoints
|
||||
for (int i = 0; i < p_lines.size(); i++) {
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, p_lines[i], true);
|
||||
DAP::Breakpoint breakpoint;
|
||||
DAP::Breakpoint breakpoint(fetch_source(p_path));
|
||||
breakpoint.line = p_lines[i];
|
||||
breakpoint.source.path = p_path;
|
||||
|
||||
ERR_FAIL_COND_V(!breakpoint_list.find(breakpoint), Array());
|
||||
updated_breakpoints.push_back(breakpoint_list.find(breakpoint)->get().to_json());
|
||||
// Avoid duplicated entries.
|
||||
List<DAP::Breakpoint>::Element *E = breakpoint_list.find(breakpoint);
|
||||
if (E) {
|
||||
updated_breakpoints.push_back(E->get().to_json());
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, p_lines[i], true);
|
||||
|
||||
// Breakpoints are inserted at the end of the breakpoint list.
|
||||
List<DAP::Breakpoint>::Element *added_breakpoint = breakpoint_list.back();
|
||||
ERR_FAIL_NULL_V(added_breakpoint, Array());
|
||||
ERR_FAIL_COND_V(!(added_breakpoint->get() == breakpoint), Array());
|
||||
updated_breakpoints.push_back(added_breakpoint->get().to_json());
|
||||
}
|
||||
|
||||
// Remove breakpoints
|
||||
for (List<DAP::Breakpoint>::Element *E = breakpoint_list.front(); E; E = E->next()) {
|
||||
DAP::Breakpoint b = E->get();
|
||||
if (b.source.path == p_path && !p_lines.has(b.line)) {
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, b.line, false);
|
||||
// Must be deferred because we are iterating the breakpoint list.
|
||||
Vector<int> to_remove;
|
||||
|
||||
for (const DAP::Breakpoint &b : breakpoint_list) {
|
||||
if (b.source->path == p_path && !p_lines.has(b.line)) {
|
||||
to_remove.push_back(b.line);
|
||||
}
|
||||
}
|
||||
|
||||
// Safe to remove queued data now.
|
||||
for (const int &line : to_remove) {
|
||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->_set_breakpoint(p_path, line, false);
|
||||
}
|
||||
|
||||
return updated_breakpoints;
|
||||
}
|
||||
|
||||
|
|
@ -1032,6 +1031,7 @@ void DebugAdapterProtocol::on_debug_paused() {
|
|||
void DebugAdapterProtocol::on_debug_stopped() {
|
||||
notify_exited();
|
||||
notify_terminated();
|
||||
reset_ids();
|
||||
}
|
||||
|
||||
void DebugAdapterProtocol::on_debug_output(const String &p_message, int p_type) {
|
||||
|
|
@ -1059,10 +1059,8 @@ void DebugAdapterProtocol::on_debug_breaked(const bool &p_reallydid, const bool
|
|||
}
|
||||
|
||||
void DebugAdapterProtocol::on_debug_breakpoint_toggled(const String &p_path, const int &p_line, const bool &p_enabled) {
|
||||
DAP::Breakpoint breakpoint;
|
||||
DAP::Breakpoint breakpoint(fetch_source(p_path));
|
||||
breakpoint.verified = true;
|
||||
breakpoint.source.path = ProjectSettings::get_singleton()->globalize_path(p_path);
|
||||
breakpoint.source.compute_checksums();
|
||||
breakpoint.line = p_line;
|
||||
|
||||
if (p_enabled) {
|
||||
|
|
@ -1085,8 +1083,7 @@ void DebugAdapterProtocol::on_debug_stack_dump(const Array &p_stack_dump) {
|
|||
if (_processing_breakpoint && !p_stack_dump.is_empty()) {
|
||||
// Find existing breakpoint
|
||||
Dictionary d = p_stack_dump[0];
|
||||
DAP::Breakpoint breakpoint;
|
||||
breakpoint.source.path = ProjectSettings::get_singleton()->globalize_path(d["file"]);
|
||||
DAP::Breakpoint breakpoint(fetch_source(d["file"]));
|
||||
breakpoint.line = d["line"];
|
||||
|
||||
List<DAP::Breakpoint>::Element *E = breakpoint_list.find(breakpoint);
|
||||
|
|
@ -1099,25 +1096,26 @@ void DebugAdapterProtocol::on_debug_stack_dump(const Array &p_stack_dump) {
|
|||
|
||||
stackframe_id = 0;
|
||||
stackframe_list.clear();
|
||||
scope_list.clear();
|
||||
|
||||
// Fill in stacktrace information
|
||||
for (int i = 0; i < p_stack_dump.size(); i++) {
|
||||
Dictionary stack_info = p_stack_dump[i];
|
||||
DAP::StackFrame stackframe;
|
||||
|
||||
DAP::StackFrame stackframe(fetch_source(stack_info["file"]));
|
||||
stackframe.id = stackframe_id++;
|
||||
stackframe.name = stack_info["function"];
|
||||
stackframe.line = stack_info["line"];
|
||||
stackframe.column = 0;
|
||||
stackframe.source.path = ProjectSettings::get_singleton()->globalize_path(stack_info["file"]);
|
||||
stackframe.source.compute_checksums();
|
||||
|
||||
// Information for "Locals", "Members" and "Globals" variables respectively
|
||||
List<int> scope_ids;
|
||||
Vector<int> scope_ids;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
scope_ids.push_back(variable_id++);
|
||||
}
|
||||
|
||||
stackframe_list.insert(stackframe, scope_ids);
|
||||
stackframe_list.push_back(stackframe);
|
||||
scope_list.insert(stackframe.id, scope_ids);
|
||||
}
|
||||
|
||||
_current_frame = 0;
|
||||
|
|
@ -1126,12 +1124,9 @@ void DebugAdapterProtocol::on_debug_stack_dump(const Array &p_stack_dump) {
|
|||
|
||||
void DebugAdapterProtocol::on_debug_stack_frame_vars(const int &p_size) {
|
||||
_remaining_vars = p_size;
|
||||
DAP::StackFrame frame;
|
||||
frame.id = _current_frame;
|
||||
ERR_FAIL_COND(!stackframe_list.has(frame));
|
||||
List<int> scope_ids = stackframe_list.find(frame)->value;
|
||||
for (List<int>::Element *E = scope_ids.front(); E; E = E->next()) {
|
||||
int var_id = E->get();
|
||||
ERR_FAIL_COND(!scope_list.has(_current_frame));
|
||||
Vector<int> scope_ids = scope_list.find(_current_frame)->value;
|
||||
for (const int &var_id : scope_ids) {
|
||||
if (variable_list.has(var_id)) {
|
||||
variable_list.find(var_id)->value.clear();
|
||||
} else {
|
||||
|
|
@ -1144,11 +1139,9 @@ void DebugAdapterProtocol::on_debug_stack_frame_var(const Array &p_data) {
|
|||
DebuggerMarshalls::ScriptStackVariable stack_var;
|
||||
stack_var.deserialize(p_data);
|
||||
|
||||
ERR_FAIL_COND(stackframe_list.is_empty());
|
||||
DAP::StackFrame frame;
|
||||
frame.id = _current_frame;
|
||||
ERR_FAIL_COND(!scope_list.has(_current_frame));
|
||||
Vector<int> scope_ids = scope_list.find(_current_frame)->value;
|
||||
|
||||
List<int> scope_ids = stackframe_list.find(frame)->value;
|
||||
ERR_FAIL_COND(scope_ids.size() != 3);
|
||||
ERR_FAIL_INDEX(stack_var.type, 4);
|
||||
int var_id = scope_ids.get(stack_var.type);
|
||||
|
|
@ -1192,8 +1185,7 @@ void DebugAdapterProtocol::poll() {
|
|||
on_client_connected();
|
||||
}
|
||||
List<Ref<DAPeer>> to_delete;
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
Ref<DAPeer> peer = E->get();
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->connection->poll();
|
||||
StreamPeerTCP::Status status = peer->connection->get_status();
|
||||
if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) {
|
||||
|
|
@ -1211,8 +1203,8 @@ void DebugAdapterProtocol::poll() {
|
|||
}
|
||||
}
|
||||
|
||||
for (List<Ref<DAPeer>>::Element *E = to_delete.front(); E; E = E->next()) {
|
||||
on_client_disconnected(E->get());
|
||||
for (const Ref<DAPeer> &peer : to_delete) {
|
||||
on_client_disconnected(peer);
|
||||
}
|
||||
to_delete.clear();
|
||||
}
|
||||
|
|
@ -1225,8 +1217,8 @@ Error DebugAdapterProtocol::start(int p_port, const IPAddress &p_bind_ip) {
|
|||
}
|
||||
|
||||
void DebugAdapterProtocol::stop() {
|
||||
for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) {
|
||||
E->get()->connection->disconnect_from_host();
|
||||
for (const Ref<DAPeer> &peer : clients) {
|
||||
peer->connection->disconnect_from_host();
|
||||
}
|
||||
|
||||
clients.clear();
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEBUG_ADAPTER_PROTOCOL_H
|
||||
#define DEBUG_ADAPTER_PROTOCOL_H
|
||||
#pragma once
|
||||
|
||||
#include "core/debugger/debugger_marshalls.h"
|
||||
#include "core/io/stream_peer_tcp.h"
|
||||
|
|
@ -68,7 +67,7 @@ struct DAPeer : RefCounted {
|
|||
|
||||
Error handle_data();
|
||||
Error send_data();
|
||||
String format_output(const Dictionary &p_params) const;
|
||||
Vector<uint8_t> format_output(const Dictionary &p_params) const;
|
||||
};
|
||||
|
||||
class DebugAdapterProtocol : public Object {
|
||||
|
|
@ -77,6 +76,7 @@ class DebugAdapterProtocol : public Object {
|
|||
friend class DebugAdapterParser;
|
||||
|
||||
using DAPVarID = int;
|
||||
using DAPStackFrameID = int;
|
||||
|
||||
private:
|
||||
static DebugAdapterProtocol *singleton;
|
||||
|
|
@ -110,6 +110,9 @@ private:
|
|||
bool request_remote_object(const ObjectID &p_object_id);
|
||||
bool request_remote_evaluate(const String &p_eval, int p_stack_frame);
|
||||
|
||||
const DAP::Source &fetch_source(const String &p_path);
|
||||
void update_source(const String &p_path);
|
||||
|
||||
bool _initialized = false;
|
||||
bool _processing_breakpoint = false;
|
||||
bool _stepping = false;
|
||||
|
|
@ -126,7 +129,9 @@ private:
|
|||
int stackframe_id = 0;
|
||||
DAPVarID variable_id = 0;
|
||||
List<DAP::Breakpoint> breakpoint_list;
|
||||
HashMap<DAP::StackFrame, List<int>, DAP::StackFrame> stackframe_list;
|
||||
HashMap<String, DAP::Source> breakpoint_source_list;
|
||||
List<DAP::StackFrame> stackframe_list;
|
||||
HashMap<DAPStackFrameID, Vector<int>> scope_list;
|
||||
HashMap<DAPVarID, Array> variable_list;
|
||||
|
||||
HashMap<ObjectID, DAPVarID> object_list;
|
||||
|
|
@ -168,5 +173,3 @@ public:
|
|||
DebugAdapterProtocol();
|
||||
~DebugAdapterProtocol();
|
||||
};
|
||||
|
||||
#endif // DEBUG_ADAPTER_PROTOCOL_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEBUG_ADAPTER_SERVER_H
|
||||
#define DEBUG_ADAPTER_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "debug_adapter_protocol.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
|
|
@ -54,5 +53,3 @@ public:
|
|||
void start();
|
||||
void stop();
|
||||
};
|
||||
|
||||
#endif // DEBUG_ADAPTER_SERVER_H
|
||||
|
|
|
|||
|
|
@ -28,11 +28,9 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DEBUG_ADAPTER_TYPES_H
|
||||
#define DEBUG_ADAPTER_TYPES_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/json.h"
|
||||
#include "core/variant/dictionary.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
namespace DAP {
|
||||
|
||||
|
|
@ -69,6 +67,8 @@ public:
|
|||
void compute_checksums() {
|
||||
ERR_FAIL_COND(path.is_empty());
|
||||
|
||||
_checksums.clear();
|
||||
|
||||
// MD5
|
||||
Checksum md5;
|
||||
md5.algorithm = "MD5";
|
||||
|
|
@ -102,18 +102,24 @@ public:
|
|||
struct Breakpoint {
|
||||
int id = 0;
|
||||
bool verified = false;
|
||||
Source source;
|
||||
const Source *source = nullptr;
|
||||
int line = 0;
|
||||
|
||||
Breakpoint() = default; // Empty constructor is invalid, but is necessary because Godot's collections don't support rvalues.
|
||||
Breakpoint(const Source &p_source) :
|
||||
source(&p_source) {}
|
||||
|
||||
bool operator==(const Breakpoint &p_other) const {
|
||||
return source.path == p_other.source.path && line == p_other.line;
|
||||
return source == p_other.source && line == p_other.line;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Dictionary to_json() const {
|
||||
Dictionary dict;
|
||||
dict["id"] = id;
|
||||
dict["verified"] = verified;
|
||||
dict["source"] = source.to_json();
|
||||
if (source) {
|
||||
dict["source"] = source->to_json();
|
||||
}
|
||||
dict["line"] = line;
|
||||
|
||||
return dict;
|
||||
|
|
@ -159,9 +165,7 @@ struct Capabilities {
|
|||
dict["supportsTerminateRequest"] = supportsTerminateRequest;
|
||||
dict["supportsBreakpointLocationsRequest"] = supportsBreakpointLocationsRequest;
|
||||
|
||||
Array arr;
|
||||
arr.push_back(supportedChecksumAlgorithms[0]);
|
||||
arr.push_back(supportedChecksumAlgorithms[1]);
|
||||
Array arr = { supportedChecksumAlgorithms[0], supportedChecksumAlgorithms[1] };
|
||||
dict["supportedChecksumAlgorithms"] = arr;
|
||||
|
||||
return dict;
|
||||
|
|
@ -215,30 +219,25 @@ struct SourceBreakpoint {
|
|||
struct StackFrame {
|
||||
int id = 0;
|
||||
String name;
|
||||
Source source;
|
||||
const Source *source = nullptr;
|
||||
int line = 0;
|
||||
int column = 0;
|
||||
|
||||
StackFrame() = default; // Empty constructor is invalid, but is necessary because Godot's collections don't support rvalues.
|
||||
StackFrame(const Source &p_source) :
|
||||
source(&p_source) {}
|
||||
|
||||
static uint32_t hash(const StackFrame &p_frame) {
|
||||
return hash_murmur3_one_32(p_frame.id);
|
||||
}
|
||||
bool operator==(const StackFrame &p_other) const {
|
||||
return id == p_other.id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void from_json(const Dictionary &p_params) {
|
||||
id = p_params["id"];
|
||||
name = p_params["name"];
|
||||
source.from_json(p_params["source"]);
|
||||
line = p_params["line"];
|
||||
column = p_params["column"];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Dictionary to_json() const {
|
||||
Dictionary dict;
|
||||
dict["id"] = id;
|
||||
dict["name"] = name;
|
||||
dict["source"] = source.to_json();
|
||||
if (source) {
|
||||
dict["source"] = source->to_json();
|
||||
}
|
||||
dict["line"] = line;
|
||||
dict["column"] = column;
|
||||
|
||||
|
|
@ -277,5 +276,3 @@ struct Variable {
|
|||
};
|
||||
|
||||
} // namespace DAP
|
||||
|
||||
#endif // DEBUG_ADAPTER_TYPES_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue