[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 19:53:03 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 1/2] [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;
 };
 

>From b0f2dd369ccf04887494aca16d6f2c068b8abcda Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 18 Mar 2025 19:52:45 -0700
Subject: [PATCH 2/2] Remove unnecessary include

---
 lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
index 64002945f94d5..a8fe0d6ffce8b 100644
--- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
@@ -13,7 +13,6 @@
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBListener.h"
 #include "lldb/API/SBStream.h"
-#include "llvm/Support/raw_ostream.h"
 
 using namespace lldb;
 



More information about the lldb-commits mailing list