Skip to content
Closed
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
3 changes: 3 additions & 0 deletions API/hermes/cdp/CDPAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ void CDPAgentImpl::DomainAgentsImpl::handleCommand(
} else if (method == "setBreakpointByUrl") {
debuggerAgent_->setBreakpointByUrl(
static_cast<m::debugger::SetBreakpointByUrlRequest &>(*command));
} else if (method == "getPossibleBreakpoints") {
debuggerAgent_->getPossibleBreakpoints(
static_cast<m::debugger::GetPossibleBreakpointsRequest &>(*command));
} else if (method == "removeBreakpoint") {
debuggerAgent_->removeBreakpoint(
static_cast<m::debugger::RemoveBreakpointRequest &>(*command));
Expand Down
10 changes: 10 additions & 0 deletions API/hermes/cdp/DebuggerDomainAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,16 @@ void DebuggerDomainAgent::setBreakpointByUrl(
sendResponseToClient(resp);
}

void DebuggerDomainAgent::getPossibleBreakpoints(
const m::debugger::GetPossibleBreakpointsRequest &req) {
// Compatibility stub: unconditionally return an empty set of locations. This
// patches spec-conformance so clients (e.g. VS Code) stop treating it as
// "method not found". Real breakpoint enumeration is TODO.
m::debugger::GetPossibleBreakpointsResponse resp;
resp.id = req.id;
sendResponseToClient(resp);
}

void DebuggerDomainAgent::removeBreakpoint(
const m::debugger::RemoveBreakpointRequest &req) {
if (!checkDebuggerEnabled(req)) {
Expand Down
6 changes: 6 additions & 0 deletions API/hermes/cdp/DebuggerDomainAgent.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ class DebuggerDomainAgent : public DomainAgent {
/// even in the same CDP session. For comparison, V8 allows it from different
/// sessions but disallows it within a single session.
void setBreakpointByUrl(const m::debugger::SetBreakpointByUrlRequest &req);
/// @cdp Debugger.getPossibleBreakpoints returns the valid breakpoint
/// locations within a source range. The `start` and (if provided) `end`
/// locations must refer to the same script. `restrictToFunction` is not yet
/// supported and is ignored.
void getPossibleBreakpoints(
const m::debugger::GetPossibleBreakpointsRequest &req);
/// Handles Debugger.removeBreakpoint
void removeBreakpoint(const m::debugger::RemoveBreakpointRequest &req);
/// Handles Debugger.setBreakpointsActive
Expand Down
105 changes: 104 additions & 1 deletion API/hermes/cdp/MessageTypes.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
// @generated SignedSource<<b6f23d499b731c057a44576d724cde32>>
// @generated SignedSource<<330a0049c8eb8453a49b0b402e63aa47>>

#include "MessageTypes.h"

Expand Down Expand Up @@ -94,6 +94,8 @@ std::unique_ptr<Request> Request::fromJson(const std::string &str) {
{"Debugger.enable", tryMake<debugger::EnableRequest>},
{"Debugger.evaluateOnCallFrame",
tryMake<debugger::EvaluateOnCallFrameRequest>},
{"Debugger.getPossibleBreakpoints",
tryMake<debugger::GetPossibleBreakpointsRequest>},
{"Debugger.pause", tryMake<debugger::PauseRequest>},
{"Debugger.removeBreakpoint", tryMake<debugger::RemoveBreakpointRequest>},
{"Debugger.resume", tryMake<debugger::ResumeRequest>},
Expand Down Expand Up @@ -375,6 +377,27 @@ JSONValue *runtime::ExceptionDetails::toJsonVal(JSONFactory &factory) const {
return factory.newObject(props.begin(), props.end());
}

std::unique_ptr<debugger::BreakLocation> debugger::BreakLocation::tryMake(
const JSONObject *obj) {
std::unique_ptr<debugger::BreakLocation> type =
std::make_unique<debugger::BreakLocation>();
TRY_ASSIGN(type->scriptId, obj, "scriptId");
TRY_ASSIGN(type->lineNumber, obj, "lineNumber");
TRY_ASSIGN(type->columnNumber, obj, "columnNumber");
TRY_ASSIGN(type->type, obj, "type");
return type;
}

JSONValue *debugger::BreakLocation::toJsonVal(JSONFactory &factory) const {
llvh::SmallVector<JSONFactory::Prop, 4> props;

put(props, "scriptId", scriptId, factory);
put(props, "lineNumber", lineNumber, factory);
put(props, "columnNumber", columnNumber, factory);
put(props, "type", type, factory);
return factory.newObject(props.begin(), props.end());
}

std::unique_ptr<debugger::Scope> debugger::Scope::tryMake(
const JSONObject *obj) {
std::unique_ptr<debugger::Scope> type = std::make_unique<debugger::Scope>();
Expand Down Expand Up @@ -786,6 +809,53 @@ void debugger::EvaluateOnCallFrameRequest::accept(
handler.handle(*this);
}

debugger::GetPossibleBreakpointsRequest::GetPossibleBreakpointsRequest()
: Request("Debugger.getPossibleBreakpoints") {}

std::unique_ptr<debugger::GetPossibleBreakpointsRequest>
debugger::GetPossibleBreakpointsRequest::tryMake(const JSONObject *obj) {
std::unique_ptr<debugger::GetPossibleBreakpointsRequest> req =
std::make_unique<debugger::GetPossibleBreakpointsRequest>();
TRY_ASSIGN(req->id, obj, "id");
TRY_ASSIGN(req->method, obj, "method");

JSONValue *v = obj->get("params");
if (v == nullptr) {
return nullptr;
}
auto convertResult = valueFromJson<JSONObject *>(v);
if (!convertResult) {
return nullptr;
}
auto *params = *convertResult;
TRY_ASSIGN(req->start, params, "start");
TRY_ASSIGN(req->end, params, "end");
TRY_ASSIGN(req->restrictToFunction, params, "restrictToFunction");
return req;
}

JSONValue *debugger::GetPossibleBreakpointsRequest::toJsonVal(
JSONFactory &factory) const {
llvh::SmallVector<JSONFactory::Prop, 3> paramsProps;
put(paramsProps, "start", start, factory);
put(paramsProps, "end", end, factory);
put(paramsProps, "restrictToFunction", restrictToFunction, factory);

llvh::SmallVector<JSONFactory::Prop, 1> props;
put(props, "id", id, factory);
put(props, "method", method, factory);
put(props,
"params",
factory.newObject(paramsProps.begin(), paramsProps.end()),
factory);
return factory.newObject(props.begin(), props.end());
}

void debugger::GetPossibleBreakpointsRequest::accept(
RequestHandler &handler) const {
handler.handle(*this);
}

debugger::PauseRequest::PauseRequest() : Request("Debugger.pause") {}

std::unique_ptr<debugger::PauseRequest> debugger::PauseRequest::tryMake(
Expand Down Expand Up @@ -2210,6 +2280,39 @@ JSONValue *debugger::EvaluateOnCallFrameResponse::toJsonVal(
return factory.newObject(props.begin(), props.end());
}

std::unique_ptr<debugger::GetPossibleBreakpointsResponse>
debugger::GetPossibleBreakpointsResponse::tryMake(const JSONObject *obj) {
std::unique_ptr<debugger::GetPossibleBreakpointsResponse> resp =
std::make_unique<debugger::GetPossibleBreakpointsResponse>();
TRY_ASSIGN(resp->id, obj, "id");

JSONValue *v = obj->get("result");
if (v == nullptr) {
return nullptr;
}
auto convertResult = valueFromJson<JSONObject *>(v);
if (!convertResult) {
return nullptr;
}
auto *res = *convertResult;
TRY_ASSIGN(resp->locations, res, "locations");
return resp;
}

JSONValue *debugger::GetPossibleBreakpointsResponse::toJsonVal(
JSONFactory &factory) const {
llvh::SmallVector<JSONFactory::Prop, 1> resProps;
put(resProps, "locations", locations, factory);

llvh::SmallVector<JSONFactory::Prop, 2> props;
put(props, "id", id, factory);
put(props,
"result",
factory.newObject(resProps.begin(), resProps.end()),
factory);
return factory.newObject(props.begin(), props.end());
}

std::unique_ptr<debugger::SetBreakpointResponse>
debugger::SetBreakpointResponse::tryMake(const JSONObject *obj) {
std::unique_ptr<debugger::SetBreakpointResponse> resp =
Expand Down
44 changes: 43 additions & 1 deletion API/hermes/cdp/MessageTypes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
// @generated SignedSource<<1284c402aedd087ebdf70e9e76596f1c>>
// @generated SignedSource<<727dcfe67419625e56b2acb525424108>>

#pragma once

Expand All @@ -20,6 +20,7 @@ using JSONBlob = std::string;
struct UnknownRequest;

namespace debugger {
struct BreakLocation;
using BreakpointId = std::string;
struct BreakpointResolvedNotification;
struct CallFrame;
Expand All @@ -28,6 +29,8 @@ struct DisableRequest;
struct EnableRequest;
struct EvaluateOnCallFrameRequest;
struct EvaluateOnCallFrameResponse;
struct GetPossibleBreakpointsRequest;
struct GetPossibleBreakpointsResponse;
struct Location;
struct PauseRequest;
struct PausedNotification;
Expand Down Expand Up @@ -133,6 +136,7 @@ struct RequestHandler {
virtual void handle(const debugger::DisableRequest &req) = 0;
virtual void handle(const debugger::EnableRequest &req) = 0;
virtual void handle(const debugger::EvaluateOnCallFrameRequest &req) = 0;
virtual void handle(const debugger::GetPossibleBreakpointsRequest &req) = 0;
virtual void handle(const debugger::PauseRequest &req) = 0;
virtual void handle(const debugger::RemoveBreakpointRequest &req) = 0;
virtual void handle(const debugger::ResumeRequest &req) = 0;
Expand Down Expand Up @@ -180,6 +184,7 @@ struct NoopRequestHandler : public RequestHandler {
void handle(const debugger::DisableRequest &req) override {}
void handle(const debugger::EnableRequest &req) override {}
void handle(const debugger::EvaluateOnCallFrameRequest &req) override {}
void handle(const debugger::GetPossibleBreakpointsRequest &req) override {}
void handle(const debugger::PauseRequest &req) override {}
void handle(const debugger::RemoveBreakpointRequest &req) override {}
void handle(const debugger::ResumeRequest &req) override {}
Expand Down Expand Up @@ -374,6 +379,21 @@ struct runtime::ExceptionDetails : public Serializable {
std::optional<runtime::ExecutionContextId> executionContextId;
};

struct debugger::BreakLocation : public Serializable {
BreakLocation() = default;
BreakLocation(BreakLocation &&) = default;
BreakLocation(const BreakLocation &) = delete;
static std::unique_ptr<BreakLocation> tryMake(const JSONObject *obj);
JSONValue *toJsonVal(JSONFactory &factory) const override;
BreakLocation &operator=(const BreakLocation &) = delete;
BreakLocation &operator=(BreakLocation &&) = default;

runtime::ScriptId scriptId{};
long long lineNumber{};
std::optional<long long> columnNumber;
std::optional<std::string> type;
};

struct debugger::Scope : public Serializable {
Scope() = default;
Scope(Scope &&) = default;
Expand Down Expand Up @@ -627,6 +647,19 @@ struct debugger::EvaluateOnCallFrameRequest : public Request {
std::optional<bool> throwOnSideEffect;
};

struct debugger::GetPossibleBreakpointsRequest : public Request {
GetPossibleBreakpointsRequest();
static std::unique_ptr<GetPossibleBreakpointsRequest> tryMake(
const JSONObject *obj);

JSONValue *toJsonVal(JSONFactory &factory) const override;
void accept(RequestHandler &handler) const override;

debugger::Location start{};
std::optional<debugger::Location> end;
std::optional<bool> restrictToFunction;
};

struct debugger::PauseRequest : public Request {
PauseRequest();
static std::unique_ptr<PauseRequest> tryMake(const JSONObject *obj);
Expand Down Expand Up @@ -1031,6 +1064,15 @@ struct debugger::EvaluateOnCallFrameResponse : public Response {
std::optional<runtime::ExceptionDetails> exceptionDetails;
};

struct debugger::GetPossibleBreakpointsResponse : public Response {
GetPossibleBreakpointsResponse() = default;
static std::unique_ptr<GetPossibleBreakpointsResponse> tryMake(
const JSONObject *obj);
JSONValue *toJsonVal(JSONFactory &factory) const override;

std::vector<debugger::BreakLocation> locations;
};

struct debugger::SetBreakpointResponse : public Response {
SetBreakpointResponse() = default;
static std::unique_ptr<SetBreakpointResponse> tryMake(const JSONObject *obj);
Expand Down
1 change: 1 addition & 0 deletions API/hermes/cdp/tools/message_types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Debugger.breakpointResolved
Debugger.disable
Debugger.enable
Debugger.evaluateOnCallFrame
Debugger.getPossibleBreakpoints
Debugger.pause
Debugger.paused
Debugger.removeBreakpoint
Expand Down
Loading