Skip to content

[lldb-dap] Move request capabilities into request handlers (NFC) #131943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines +1152 to +1160
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure some of these could be associated with a specific request handler. Let me know if anyone feels strongly about moving any of these.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a lot of those are general enough (like LogPoints that spans all the breakpoint types) that it makes sense to leave them as top level capabilities.


// 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
3 changes: 3 additions & 0 deletions lldb/tools/lldb-dap/DAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }

Expand Down
80 changes: 5 additions & 75 deletions lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,49 +377,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(".");
Expand All @@ -428,42 +394,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());
Expand Down
42 changes: 42 additions & 0 deletions lldb/tools/lldb-dap/Handler/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -153,13 +155,19 @@ 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;
};

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;
};

Expand All @@ -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;
};

Expand All @@ -198,13 +209,19 @@ 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;
};

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;
};

Expand All @@ -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;
};

Expand All @@ -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;
};

Expand All @@ -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;
};

Expand All @@ -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;
};

Expand Down Expand Up @@ -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;
};

Expand All @@ -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;
};

Expand Down Expand Up @@ -371,13 +407,19 @@ 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;
};

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;
};

Expand Down
Loading