[Lldb-commits] [lldb] [lldb-dap] Move request capabilities into request handlers (NFC) (PR #131943)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Tue Mar 18 17:49:53 PDT 2025
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/131943
>From c9770d124155beabcb133e47a5d798d22bcb7de2 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 18 Mar 2025 17:47:26 -0700
Subject: [PATCH] [lldb-dap] Move request capabilities into request handlers
(NFC)
This distributes the registration of request related capabilities to the
corresponding request handler. Global and unsupported capabilities are
registered at the DAP level.
---
lldb/tools/lldb-dap/DAP.cpp | 29 +++++++
lldb/tools/lldb-dap/DAP.h | 3 +
.../Handler/InitializeRequestHandler.cpp | 81 ++-----------------
lldb/tools/lldb-dap/Handler/RequestHandler.h | 42 ++++++++++
4 files changed, 80 insertions(+), 75 deletions(-)
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index a1e2187288768..cab33c640b684 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1145,4 +1145,33 @@ lldb::SBValue Variables::FindVariable(uint64_t variablesReference,
return variable;
}
+llvm::StringMap<bool> DAP::GetCapabilities() {
+ llvm::StringMap<bool> capabilities;
+
+ // Supported capabilities.
+ capabilities["supportTerminateDebuggee"] = true;
+ capabilities["supportsDataBreakpoints"] = true;
+ capabilities["supportsDelayedStackTraceLoading"] = true;
+ capabilities["supportsEvaluateForHovers"] = true;
+ capabilities["supportsExceptionOptions"] = true;
+ capabilities["supportsLogPoints"] = true;
+ capabilities["supportsProgressReporting"] = true;
+ capabilities["supportsSteppingGranularity"] = true;
+ capabilities["supportsValueFormattingOptions"] = true;
+
+ // Unsupported capabilities.
+ capabilities["supportsGotoTargetsRequest"] = false;
+ capabilities["supportsLoadedSourcesRequest"] = false;
+ capabilities["supportsRestartFrame"] = false;
+ capabilities["supportsStepBack"] = false;
+
+ // Capabilities associated with specific requests.
+ for (auto &kv : request_handlers) {
+ for (auto &request_kv : kv.second->GetCapabilities())
+ capabilities[request_kv.getKey()] = request_kv.getValue();
+ }
+
+ return capabilities;
+}
+
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 4c57f9fef3d89..9a823c2d04fe7 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -364,6 +364,9 @@ struct DAP {
request_handlers[Handler::getCommand()] = std::make_unique<Handler>(*this);
}
+ /// Return a key-value list of capabilities.
+ llvm::StringMap<bool> GetCapabilities();
+
/// Debuggee will continue from stopped state.
void WillContinue() { variables.Clear(); }
diff --git a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
index 3262b70042a0e..64002945f94d5 100644
--- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
@@ -13,6 +13,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb;
@@ -377,49 +378,15 @@ void InitializeRequestHandler::operator()(
// process and more.
dap.event_thread = std::thread(EventThreadFunction, std::ref(dap));
- // The debug adapter supports the configurationDoneRequest.
- body.try_emplace("supportsConfigurationDoneRequest", true);
- // The debug adapter supports function breakpoints.
- body.try_emplace("supportsFunctionBreakpoints", true);
- // The debug adapter supports conditional breakpoints.
- body.try_emplace("supportsConditionalBreakpoints", true);
- // The debug adapter supports breakpoints that break execution after a
- // specified number of hits.
- body.try_emplace("supportsHitConditionalBreakpoints", true);
- // The debug adapter supports a (side effect free) evaluate request for
- // data hovers.
- body.try_emplace("supportsEvaluateForHovers", true);
+ llvm::StringMap<bool> capabilities = dap.GetCapabilities();
+ for (auto &kv : capabilities)
+ body.try_emplace(kv.getKey(), kv.getValue());
+
// Available filters or options for the setExceptionBreakpoints request.
llvm::json::Array filters;
- for (const auto &exc_bp : *dap.exception_breakpoints) {
+ for (const auto &exc_bp : *dap.exception_breakpoints)
filters.emplace_back(CreateExceptionBreakpointFilter(exc_bp));
- }
body.try_emplace("exceptionBreakpointFilters", std::move(filters));
- // The debug adapter supports launching a debugee in intergrated VSCode
- // terminal.
- body.try_emplace("supportsRunInTerminalRequest", true);
- // The debug adapter supports stepping back via the stepBack and
- // reverseContinue requests.
- body.try_emplace("supportsStepBack", false);
- // The debug adapter supports setting a variable to a value.
- body.try_emplace("supportsSetVariable", true);
- // The debug adapter supports restarting a frame.
- body.try_emplace("supportsRestartFrame", false);
- // The debug adapter supports the gotoTargetsRequest.
- body.try_emplace("supportsGotoTargetsRequest", false);
- // The debug adapter supports the stepInTargetsRequest.
- body.try_emplace("supportsStepInTargetsRequest", true);
- // The debug adapter supports the completions request.
- body.try_emplace("supportsCompletionsRequest", true);
- // The debug adapter supports the disassembly request.
- body.try_emplace("supportsDisassembleRequest", true);
- // The debug adapter supports the `breakpointLocations` request.
- body.try_emplace("supportsBreakpointLocationsRequest", true);
- // The debug adapter supports stepping granularities (argument `granularity`)
- // for the stepping requests.
- body.try_emplace("supportsSteppingGranularity", true);
- // The debug adapter support for instruction breakpoint.
- body.try_emplace("supportsInstructionBreakpoints", true);
llvm::json::Array completion_characters;
completion_characters.emplace_back(".");
@@ -428,42 +395,6 @@ void InitializeRequestHandler::operator()(
body.try_emplace("completionTriggerCharacters",
std::move(completion_characters));
- // The debug adapter supports the modules request.
- body.try_emplace("supportsModulesRequest", true);
- // The set of additional module information exposed by the debug adapter.
- // body.try_emplace("additionalModuleColumns"] = ColumnDescriptor
- // Checksum algorithms supported by the debug adapter.
- // body.try_emplace("supportedChecksumAlgorithms"] = ChecksumAlgorithm
- // The debug adapter supports the RestartRequest. In this case a client
- // should not implement 'restart' by terminating and relaunching the adapter
- // but by calling the RestartRequest.
- body.try_emplace("supportsRestartRequest", true);
- // The debug adapter supports 'exceptionOptions' on the
- // setExceptionBreakpoints request.
- body.try_emplace("supportsExceptionOptions", true);
- // The debug adapter supports a 'format' attribute on the stackTraceRequest,
- // variablesRequest, and evaluateRequest.
- body.try_emplace("supportsValueFormattingOptions", true);
- // The debug adapter supports the exceptionInfo request.
- body.try_emplace("supportsExceptionInfoRequest", true);
- // The debug adapter supports the 'terminateDebuggee' attribute on the
- // 'disconnect' request.
- body.try_emplace("supportTerminateDebuggee", true);
- // The debug adapter supports the delayed loading of parts of the stack,
- // which requires that both the 'startFrame' and 'levels' arguments and the
- // 'totalFrames' result of the 'StackTrace' request are supported.
- body.try_emplace("supportsDelayedStackTraceLoading", true);
- // The debug adapter supports the 'loadedSources' request.
- body.try_emplace("supportsLoadedSourcesRequest", false);
- // The debug adapter supports sending progress reporting events.
- body.try_emplace("supportsProgressReporting", true);
- // The debug adapter supports 'logMessage' in breakpoint.
- body.try_emplace("supportsLogPoints", true);
- // The debug adapter supports data watchpoints.
- body.try_emplace("supportsDataBreakpoints", true);
- // The debug adapter supports the `readMemory` request.
- body.try_emplace("supportsReadMemoryRequest", true);
-
// Put in non-DAP specification lldb specific information.
llvm::json::Object lldb_json;
lldb_json.try_emplace("version", dap.debugger.GetVersionString());
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index c9bcf15933c33..4856e199ea6b8 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -45,6 +45,8 @@ class BaseRequestHandler {
virtual void operator()(const protocol::Request &request) const = 0;
+ virtual llvm::StringMap<bool> GetCapabilities() const { return {}; }
+
protected:
/// Helpers used by multiple request handlers.
/// FIXME: Move these into the DAP class?
@@ -153,6 +155,9 @@ class BreakpointLocationsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "breakpointLocations"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsBreakpointLocationsRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -160,6 +165,9 @@ class CompletionsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "completions"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsCompletionsRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -174,6 +182,9 @@ class ConfigurationDoneRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "configurationDone"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsConfigurationDoneRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -198,6 +209,9 @@ class ExceptionInfoRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "exceptionInfo"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsExceptionInfoRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -205,6 +219,9 @@ class InitializeRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "initialize"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsRunInTerminalRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -219,6 +236,9 @@ class RestartRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "restart"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsRestartRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -240,6 +260,9 @@ class StepInTargetsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "stepInTargets"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsStepInTargetsRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -254,6 +277,10 @@ class SetBreakpointsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "setBreakpoints"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsConditionalBreakpoints", true},
+ {"supportsHitConditionalBreakpoints", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -268,6 +295,9 @@ class SetFunctionBreakpointsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "setFunctionBreakpoints"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsFunctionBreakpoints", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -305,6 +335,9 @@ class ModulesRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "modules"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsModulesRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -326,6 +359,9 @@ class SetVariableRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "setVariable"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsSetVariable", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -371,6 +407,9 @@ class DisassembleRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "disassemble"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsDisassembleRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
@@ -378,6 +417,9 @@ class ReadMemoryRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral getCommand() { return "readMemory"; }
+ llvm::StringMap<bool> GetCapabilities() const override {
+ return {{"supportsReadMemoryRequest", true}};
+ }
void operator()(const llvm::json::Object &request) const override;
};
More information about the lldb-commits
mailing list