77// ===----------------------------------------------------------------------===//
88
99#include " DAP.h"
10- #include " EventHelper.h"
11- #include " JSONUtils.h"
1210#include " RequestHandler.h"
1311
12+ using namespace lldb_dap ::protocol;
1413namespace lldb_dap {
1514
16- // "ScopesRequest": {
17- // "allOf": [ { "$ref": "#/definitions/Request" }, {
18- // "type": "object",
19- // "description": "Scopes request; value of command field is 'scopes'. The
20- // request returns the variable scopes for a given stackframe ID.",
21- // "properties": {
22- // "command": {
23- // "type": "string",
24- // "enum": [ "scopes" ]
25- // },
26- // "arguments": {
27- // "$ref": "#/definitions/ScopesArguments"
28- // }
29- // },
30- // "required": [ "command", "arguments" ]
31- // }]
32- // },
33- // "ScopesArguments": {
34- // "type": "object",
35- // "description": "Arguments for 'scopes' request.",
36- // "properties": {
37- // "frameId": {
38- // "type": "integer",
39- // "description": "Retrieve the scopes for this stackframe."
40- // }
41- // },
42- // "required": [ "frameId" ]
43- // },
44- // "ScopesResponse": {
45- // "allOf": [ { "$ref": "#/definitions/Response" }, {
46- // "type": "object",
47- // "description": "Response to 'scopes' request.",
48- // "properties": {
49- // "body": {
50- // "type": "object",
51- // "properties": {
52- // "scopes": {
53- // "type": "array",
54- // "items": {
55- // "$ref": "#/definitions/Scope"
56- // },
57- // "description": "The scopes of the stackframe. If the array has
58- // length zero, there are no scopes available."
59- // }
60- // },
61- // "required": [ "scopes" ]
62- // }
63- // },
64- // "required": [ "body" ]
65- // }]
66- // }
67- void ScopesRequestHandler::operator ()(const llvm::json::Object &request) const {
68- llvm::json::Object response;
69- FillResponse (request, response);
70- llvm::json::Object body;
71- const auto *arguments = request.getObject (" arguments" );
72- lldb::SBFrame frame = dap.GetLLDBFrame (*arguments);
15+ // / Creates a `protocol::Scope` struct.
16+ // /
17+ // /
18+ // / \param[in] name
19+ // / The value to place into the "name" key
20+ // /
21+ // / \param[in] variablesReference
22+ // / The value to place into the "variablesReference" key
23+ // /
24+ // / \param[in] namedVariables
25+ // / The value to place into the "namedVariables" key
26+ // /
27+ // / \param[in] expensive
28+ // / The value to place into the "expensive" key
29+ // /
30+ // / \return
31+ // / A `protocol::Scope`
32+ static Scope CreateScope (const llvm::StringRef name, int64_t variablesReference,
33+ int64_t namedVariables, bool expensive) {
34+ Scope scope;
35+ scope.name = name;
36+
37+ // TODO: Support "arguments" and "return value" scope.
38+ // At the moment lldb-dap includes the arguments and return_value into the
39+ // "locals" scope.
40+ // vscode only expands the first non-expensive scope, this causes friction
41+ // if we add the arguments above the local scope as the locals scope will not
42+ // be expanded if we enter a function with arguments. It becomes more
43+ // annoying when the scope has arguments, return_value and locals.
44+ if (variablesReference == VARREF_LOCALS)
45+ scope.presentationHint = Scope::eScopePresentationHintLocals;
46+ else if (variablesReference == VARREF_REGS)
47+ scope.presentationHint = Scope::eScopePresentationHintRegisters;
48+
49+ scope.variablesReference = variablesReference;
50+ scope.namedVariables = namedVariables;
51+ scope.expensive = expensive;
52+
53+ return scope;
54+ }
55+
56+ llvm::Expected<ScopesResponseBody>
57+ ScopesRequestHandler::Run (const ScopesArguments &args) const {
58+ lldb::SBFrame frame = dap.GetLLDBFrame (args.frameId );
59+
7360 // As the user selects different stack frames in the GUI, a "scopes" request
7461 // will be sent to the DAP. This is the only way we know that the user has
7562 // selected a frame in a thread. There are no other notifications that are
@@ -78,17 +65,16 @@ void ScopesRequestHandler::operator()(const llvm::json::Object &request) const {
7865 // are sent, this allows users to type commands in the debugger console
7966 // with a backtick character to run lldb commands and these lldb commands
8067 // will now have the right context selected as they are run. If the user
81- // types "`bt" into the debugger console and we had another thread selected
68+ // types "`bt" into the debugger console, and we had another thread selected
8269 // in the LLDB library, we would show the wrong thing to the user. If the
83- // users switches threads with a lldb command like "`thread select 14", the
70+ // users switch threads with a lldb command like "`thread select 14", the
8471 // GUI will not update as there are no "event" notification packets that
8572 // allow us to change the currently selected thread or frame in the GUI that
8673 // I am aware of.
8774 if (frame.IsValid ()) {
8875 frame.GetThread ().GetProcess ().SetSelectedThread (frame.GetThread ());
8976 frame.GetThread ().SetSelectedFrame (frame.GetFrameID ());
9077 }
91-
9278 dap.variables .locals = frame.GetVariables (/* arguments=*/ true ,
9379 /* locals=*/ true ,
9480 /* statics=*/ false ,
@@ -98,9 +84,15 @@ void ScopesRequestHandler::operator()(const llvm::json::Object &request) const {
9884 /* statics=*/ true ,
9985 /* in_scope_only=*/ true );
10086 dap.variables .registers = frame.GetRegisters ();
101- body.try_emplace (" scopes" , dap.CreateTopLevelScopes ());
102- response.try_emplace (" body" , std::move (body));
103- dap.SendJSON (llvm::json::Value (std::move (response)));
87+
88+ std::vector scopes = {CreateScope (" Locals" , VARREF_LOCALS,
89+ dap.variables .locals .GetSize (), false ),
90+ CreateScope (" Globals" , VARREF_GLOBALS,
91+ dap.variables .globals .GetSize (), false ),
92+ CreateScope (" Registers" , VARREF_REGS,
93+ dap.variables .registers .GetSize (), false )};
94+
95+ return ScopesResponseBody{std::move (scopes)};
10496}
10597
10698} // namespace lldb_dap
0 commit comments