summaryrefslogtreecommitdiffstats
path: root/editor/debugger
diff options
context:
space:
mode:
authorRicardo Subtil <ricasubtil@gmail.com>2024-09-30 14:15:09 +0100
committerRicardo Subtil <ricasubtil@gmail.com>2024-10-03 21:28:38 +0100
commit0d098d3cca7ce8aa98ff341c5ebbd26895d6e97d (patch)
treec28bdb35cde40e40a4616dbb5b149a97afc4cd9d /editor/debugger
parent6aac039ee7803375bfc46f2c43794c9807ab9dd5 (diff)
downloadredot-engine-0d098d3cca7ce8aa98ff341c5ebbd26895d6e97d.tar.gz
Support REPL expressions through DAP `evaluate` request
Diffstat (limited to 'editor/debugger')
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_parser.cpp27
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.cpp34
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.h7
-rw-r--r--editor/debugger/editor_expression_evaluator.cpp5
-rw-r--r--editor/debugger/script_editor_debugger.cpp7
-rw-r--r--editor/debugger/script_editor_debugger.h2
6 files changed, 71 insertions, 11 deletions
diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp
index 8e2f037a1c..1dbb2c7084 100644
--- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp
@@ -30,6 +30,8 @@
#include "debug_adapter_parser.h"
+#include "core/variant/variant.h"
+#include "editor/debugger/debug_adapter/debug_adapter_types.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/export/editor_export_platform.h"
@@ -487,16 +489,27 @@ Dictionary DebugAdapterParser::req_stepIn(const Dictionary &p_params) const {
}
Dictionary DebugAdapterParser::req_evaluate(const Dictionary &p_params) const {
- Dictionary response = prepare_success_response(p_params), body;
- response["body"] = body;
-
Dictionary args = p_params["arguments"];
+ String expression = args["expression"];
+ int frame_id = args.has("frameId") ? static_cast<int>(args["frameId"]) : DebugAdapterProtocol::get_singleton()->_current_frame;
- String value = EditorDebuggerNode::get_singleton()->get_var_value(args["expression"]);
- body["result"] = value;
- body["variablesReference"] = 0;
+ if (HashMap<String, DAP::Variable>::Iterator E = DebugAdapterProtocol::get_singleton()->eval_list.find(expression); E) {
+ Dictionary response = prepare_success_response(p_params);
+ Dictionary body;
+ response["body"] = body;
- return response;
+ DAP::Variable var = E->value;
+
+ body["result"] = var.value;
+ body["variablesReference"] = var.variablesReference;
+
+ // Since an evaluation can alter the state of the debuggee, they are volatile, and should only be used once
+ DebugAdapterProtocol::get_singleton()->eval_list.erase(E->key);
+ return response;
+ } else {
+ DebugAdapterProtocol::get_singleton()->request_remote_evaluate(expression, frame_id);
+ }
+ return Dictionary();
}
Dictionary DebugAdapterParser::req_godot_put_msg(const Dictionary &p_params) const {
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
index a130464fe0..066cf63301 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
@@ -799,6 +799,22 @@ void DebugAdapterProtocol::parse_object(SceneDebuggerObject &p_obj) {
variable_list.insert(object_list[object_id], properties);
}
+void DebugAdapterProtocol::parse_evaluation(DebuggerMarshalls::ScriptStackVariable &p_var) {
+ // If the eval is not on the pending list, we weren't expecting it. Ignore it.
+ String eval = p_var.name;
+ if (!eval_pending_list.erase(eval)) {
+ return;
+ }
+
+ DAP::Variable variable;
+ variable.name = p_var.name;
+ variable.value = p_var.value;
+ variable.type = Variant::get_type_name(p_var.value.get_type());
+ variable.variablesReference = parse_variant(p_var.value);
+
+ eval_list.insert(variable.name, variable);
+}
+
const Variant DebugAdapterProtocol::parse_object_variable(const SceneDebuggerObject::SceneDebuggerProperty &p_property) {
const PropertyInfo &info = p_property.first;
const Variant &value = p_property.second;
@@ -833,6 +849,18 @@ bool DebugAdapterProtocol::request_remote_object(const ObjectID &p_object_id) {
return true;
}
+bool DebugAdapterProtocol::request_remote_evaluate(const String &p_eval, int p_stack_frame) {
+ // If the eval is already on the pending list, we don't need to request it again
+ if (eval_pending_list.has(p_eval)) {
+ return false;
+ }
+
+ EditorDebuggerNode::get_singleton()->get_default_debugger()->request_remote_evaluate(p_eval, p_stack_frame);
+ eval_pending_list.insert(p_eval);
+
+ return true;
+}
+
bool DebugAdapterProtocol::process_message(const String &p_text) {
JSON json;
ERR_FAIL_COND_V_MSG(json.parse(p_text) != OK, true, "Malformed message!");
@@ -1148,6 +1176,12 @@ void DebugAdapterProtocol::on_debug_data(const String &p_msg, const Array &p_dat
remote_obj.deserialize(p_data);
parse_object(remote_obj);
+ } else if (p_msg == "evaluation_return") {
+ // An evaluation was requested from the debuggee; parse it.
+ DebuggerMarshalls::ScriptStackVariable remote_evaluation;
+ remote_evaluation.deserialize(p_data);
+
+ parse_evaluation(remote_evaluation);
}
notify_custom_data(p_msg, p_data);
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h
index 29d7457ee7..81e6205fee 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.h
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h
@@ -31,9 +31,11 @@
#ifndef DEBUG_ADAPTER_PROTOCOL_H
#define DEBUG_ADAPTER_PROTOCOL_H
+#include "core/debugger/debugger_marshalls.h"
#include "core/io/stream_peer_tcp.h"
#include "core/io/tcp_server.h"
+#include "core/object/object_id.h"
#include "debug_adapter_parser.h"
#include "debug_adapter_types.h"
#include "scene/debugger/scene_debugger.h"
@@ -103,9 +105,11 @@ private:
int parse_variant(const Variant &p_var);
void parse_object(SceneDebuggerObject &p_obj);
const Variant parse_object_variable(const SceneDebuggerObject::SceneDebuggerProperty &p_property);
+ void parse_evaluation(DebuggerMarshalls::ScriptStackVariable &p_var);
ObjectID search_object_id(DAPVarID p_var_id);
bool request_remote_object(const ObjectID &p_object_id);
+ bool request_remote_evaluate(const String &p_eval, int p_stack_frame);
bool _initialized = false;
bool _processing_breakpoint = false;
@@ -129,6 +133,9 @@ private:
HashMap<ObjectID, DAPVarID> object_list;
HashSet<ObjectID> object_pending_set;
+ HashMap<String, DAP::Variable> eval_list;
+ HashSet<String> eval_pending_list;
+
public:
friend class DebugAdapterServer;
diff --git a/editor/debugger/editor_expression_evaluator.cpp b/editor/debugger/editor_expression_evaluator.cpp
index e8b1e33d20..25e9c9eac3 100644
--- a/editor/debugger/editor_expression_evaluator.cpp
+++ b/editor/debugger/editor_expression_evaluator.cpp
@@ -64,10 +64,7 @@ void EditorExpressionEvaluator::_evaluate() {
return;
}
- Array expr_data;
- expr_data.push_back(expression);
- expr_data.push_back(editor_debugger->get_stack_script_frame());
- editor_debugger->send_message("evaluate", expr_data);
+ editor_debugger->request_remote_evaluate(expression, editor_debugger->get_stack_script_frame());
expression_input->clear();
}
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 642244ebeb..cbe7910518 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -253,6 +253,13 @@ const SceneDebuggerTree *ScriptEditorDebugger::get_remote_tree() {
return scene_tree;
}
+void ScriptEditorDebugger::request_remote_evaluate(const String &p_expression, int p_stack_frame) {
+ Array msg;
+ msg.push_back(p_expression);
+ msg.push_back(p_stack_frame);
+ _put_msg("evaluate", msg);
+}
+
void ScriptEditorDebugger::update_remote_object(ObjectID p_obj_id, const String &p_prop, const Variant &p_value) {
Array msg;
msg.push_back(p_obj_id);
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index 26106849f9..1908b1e5a7 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -254,6 +254,8 @@ public:
void request_remote_tree();
const SceneDebuggerTree *get_remote_tree();
+ void request_remote_evaluate(const String &p_expression, int p_stack_frame);
+
void start(Ref<RemoteDebuggerPeer> p_peer);
void stop();