Implement GlobalLexicalScopeNamesRequest
Summary: Implement the `GlobalLexicalScopeNames` request and response: > Returns all let, const and class variables from global scope. The returned elements are filtered to remove internal entries that are prefixed with `?`: https://www.internalfb.com/code/fbsource/[4398b6a77500984e8536c06d58c691cd7c591477][history]/xplat/hermes/lib/IRGen/ESTreeIRGen-func.cpp?lines=49&base=da0d9de8a0d2 Changelog: [Internal] Reviewed By: jpporto Differential Revision: D38119568 fbshipit-source-id: 5c74dc7fa58d8dbc784bf39ac5baf85788a3df7a
This commit is contained in:
Родитель
e24ce708ab
Коммит
b7164278cf
|
@ -107,6 +107,7 @@ class Connection::Impl : public inspector::InspectorObserver,
|
|||
void handle(const m::runtime::EvaluateRequest &req) override;
|
||||
void handle(const m::runtime::GetHeapUsageRequest &req) override;
|
||||
void handle(const m::runtime::GetPropertiesRequest &req) override;
|
||||
void handle(const m::runtime::GlobalLexicalScopeNamesRequest &req) override;
|
||||
void handle(const m::runtime::RunIfWaitingForDebuggerRequest &req) override;
|
||||
|
||||
private:
|
||||
|
@ -1451,6 +1452,45 @@ void Connection::Impl::handle(const m::runtime::GetPropertiesRequest &req) {
|
|||
.thenError<std::exception>(sendErrorToClient(req.id));
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(
|
||||
const m::runtime::GlobalLexicalScopeNamesRequest &req) {
|
||||
auto resp = std::make_shared<m::runtime::GlobalLexicalScopeNamesResponse>();
|
||||
resp->id = req.id;
|
||||
|
||||
inspector_
|
||||
->executeIfEnabled(
|
||||
"Runtime.globalLexicalScopeNames",
|
||||
[req, resp](const debugger::ProgramState &state) {
|
||||
if (req.executionContextId.hasValue() &&
|
||||
req.executionContextId.value() != kHermesExecutionContextId) {
|
||||
throw std::invalid_argument("Invalid execution context");
|
||||
}
|
||||
|
||||
const debugger::LexicalInfo &lexicalInfo = state.getLexicalInfo(0);
|
||||
debugger::ScopeDepth scopeCount = lexicalInfo.getScopesCount();
|
||||
if (scopeCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const debugger::ScopeDepth globalScopeIndex = scopeCount - 1;
|
||||
uint32_t variableCount =
|
||||
lexicalInfo.getVariablesCountInScope(globalScopeIndex);
|
||||
resp->names.reserve(variableCount);
|
||||
for (uint32_t i = 0; i < variableCount; i++) {
|
||||
debugger::String name =
|
||||
state.getVariableInfo(0, globalScopeIndex, i).name;
|
||||
// The global scope has some entries prefixed with '?', which are
|
||||
// not valid identifiers.
|
||||
if (!name.empty() && name.front() != '?') {
|
||||
resp->names.push_back(name);
|
||||
}
|
||||
}
|
||||
})
|
||||
.via(executor_.get())
|
||||
.thenValue([this, resp](auto &&) { sendResponseToClient(*resp); })
|
||||
.thenError<std::exception>(sendErrorToClient(req.id));
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(
|
||||
const m::runtime::RunIfWaitingForDebuggerRequest &req) {
|
||||
if (inspector_->isAwaitingDebuggerOnStart()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
|
||||
// @generated SignedSource<<f6f9a72f332587809b4e50ab054e0a74>>
|
||||
// @generated SignedSource<<d10e11c5f88b40149af7ace19008d0fc>>
|
||||
|
||||
#include "MessageTypes.h"
|
||||
|
||||
|
@ -66,6 +66,8 @@ std::unique_ptr<Request> Request::fromJsonThrowOnError(const std::string &str) {
|
|||
{"Runtime.evaluate", makeUnique<runtime::EvaluateRequest>},
|
||||
{"Runtime.getHeapUsage", makeUnique<runtime::GetHeapUsageRequest>},
|
||||
{"Runtime.getProperties", makeUnique<runtime::GetPropertiesRequest>},
|
||||
{"Runtime.globalLexicalScopeNames",
|
||||
makeUnique<runtime::GlobalLexicalScopeNamesRequest>},
|
||||
{"Runtime.runIfWaitingForDebugger",
|
||||
makeUnique<runtime::RunIfWaitingForDebuggerRequest>},
|
||||
};
|
||||
|
@ -1199,6 +1201,38 @@ void runtime::GetPropertiesRequest::accept(RequestHandler &handler) const {
|
|||
handler.handle(*this);
|
||||
}
|
||||
|
||||
runtime::GlobalLexicalScopeNamesRequest::GlobalLexicalScopeNamesRequest()
|
||||
: Request("Runtime.globalLexicalScopeNames") {}
|
||||
|
||||
runtime::GlobalLexicalScopeNamesRequest::GlobalLexicalScopeNamesRequest(
|
||||
const dynamic &obj)
|
||||
: Request("Runtime.globalLexicalScopeNames") {
|
||||
assign(id, obj, "id");
|
||||
assign(method, obj, "method");
|
||||
|
||||
auto it = obj.find("params");
|
||||
if (it != obj.items().end()) {
|
||||
dynamic params = it->second;
|
||||
assign(executionContextId, params, "executionContextId");
|
||||
}
|
||||
}
|
||||
|
||||
dynamic runtime::GlobalLexicalScopeNamesRequest::toDynamic() const {
|
||||
dynamic params = dynamic::object;
|
||||
put(params, "executionContextId", executionContextId);
|
||||
|
||||
dynamic obj = dynamic::object;
|
||||
put(obj, "id", id);
|
||||
put(obj, "method", method);
|
||||
put(obj, "params", std::move(params));
|
||||
return obj;
|
||||
}
|
||||
|
||||
void runtime::GlobalLexicalScopeNamesRequest::accept(
|
||||
RequestHandler &handler) const {
|
||||
handler.handle(*this);
|
||||
}
|
||||
|
||||
runtime::RunIfWaitingForDebuggerRequest::RunIfWaitingForDebuggerRequest()
|
||||
: Request("Runtime.runIfWaitingForDebugger") {}
|
||||
|
||||
|
@ -1481,6 +1515,24 @@ dynamic runtime::GetPropertiesResponse::toDynamic() const {
|
|||
return obj;
|
||||
}
|
||||
|
||||
runtime::GlobalLexicalScopeNamesResponse::GlobalLexicalScopeNamesResponse(
|
||||
const dynamic &obj) {
|
||||
assign(id, obj, "id");
|
||||
|
||||
dynamic res = obj.at("result");
|
||||
assign(names, res, "names");
|
||||
}
|
||||
|
||||
dynamic runtime::GlobalLexicalScopeNamesResponse::toDynamic() const {
|
||||
dynamic res = dynamic::object;
|
||||
put(res, "names", names);
|
||||
|
||||
dynamic obj = dynamic::object;
|
||||
put(obj, "id", id);
|
||||
put(obj, "result", std::move(res));
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// Notifications
|
||||
debugger::BreakpointResolvedNotification::BreakpointResolvedNotification()
|
||||
: Notification("Debugger.breakpointResolved") {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
|
||||
// @generated SignedSource<<fcbcfeecbc72ca30c8ed005ad47839bb>>
|
||||
// @generated SignedSource<<dafd583635231e17c0264beb38610499>>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -63,6 +63,8 @@ struct GetHeapUsageRequest;
|
|||
struct GetHeapUsageResponse;
|
||||
struct GetPropertiesRequest;
|
||||
struct GetPropertiesResponse;
|
||||
struct GlobalLexicalScopeNamesRequest;
|
||||
struct GlobalLexicalScopeNamesResponse;
|
||||
struct InternalPropertyDescriptor;
|
||||
struct PropertyDescriptor;
|
||||
struct RemoteObject;
|
||||
|
@ -142,6 +144,7 @@ struct RequestHandler {
|
|||
virtual void handle(const runtime::EvaluateRequest &req) = 0;
|
||||
virtual void handle(const runtime::GetHeapUsageRequest &req) = 0;
|
||||
virtual void handle(const runtime::GetPropertiesRequest &req) = 0;
|
||||
virtual void handle(const runtime::GlobalLexicalScopeNamesRequest &req) = 0;
|
||||
virtual void handle(const runtime::RunIfWaitingForDebuggerRequest &req) = 0;
|
||||
};
|
||||
|
||||
|
@ -180,6 +183,7 @@ struct NoopRequestHandler : public RequestHandler {
|
|||
void handle(const runtime::EvaluateRequest &req) override {}
|
||||
void handle(const runtime::GetHeapUsageRequest &req) override {}
|
||||
void handle(const runtime::GetPropertiesRequest &req) override {}
|
||||
void handle(const runtime::GlobalLexicalScopeNamesRequest &req) override {}
|
||||
void handle(const runtime::RunIfWaitingForDebuggerRequest &req) override {}
|
||||
};
|
||||
|
||||
|
@ -686,6 +690,16 @@ struct runtime::GetPropertiesRequest : public Request {
|
|||
folly::Optional<bool> ownProperties;
|
||||
};
|
||||
|
||||
struct runtime::GlobalLexicalScopeNamesRequest : public Request {
|
||||
GlobalLexicalScopeNamesRequest();
|
||||
explicit GlobalLexicalScopeNamesRequest(const folly::dynamic &obj);
|
||||
|
||||
folly::dynamic toDynamic() const override;
|
||||
void accept(RequestHandler &handler) const override;
|
||||
|
||||
folly::Optional<runtime::ExecutionContextId> executionContextId;
|
||||
};
|
||||
|
||||
struct runtime::RunIfWaitingForDebuggerRequest : public Request {
|
||||
RunIfWaitingForDebuggerRequest();
|
||||
explicit RunIfWaitingForDebuggerRequest(const folly::dynamic &obj);
|
||||
|
@ -816,6 +830,14 @@ struct runtime::GetPropertiesResponse : public Response {
|
|||
folly::Optional<runtime::ExceptionDetails> exceptionDetails;
|
||||
};
|
||||
|
||||
struct runtime::GlobalLexicalScopeNamesResponse : public Response {
|
||||
GlobalLexicalScopeNamesResponse() = default;
|
||||
explicit GlobalLexicalScopeNamesResponse(const folly::dynamic &obj);
|
||||
folly::dynamic toDynamic() const override;
|
||||
|
||||
std::vector<std::string> names;
|
||||
};
|
||||
|
||||
/// Notifications
|
||||
struct debugger::BreakpointResolvedNotification : public Notification {
|
||||
BreakpointResolvedNotification();
|
||||
|
|
|
@ -2884,6 +2884,54 @@ TEST(ConnectionTests, testBasicProfilerOperation) {
|
|||
asyncRuntime.stop();
|
||||
}
|
||||
|
||||
TEST(ConnectionTests, testGlobalLexicalScopeNames) {
|
||||
TestContext context;
|
||||
AsyncHermesRuntime &asyncRuntime = context.runtime();
|
||||
SyncConnection &conn = context.conn();
|
||||
int msgId = 1;
|
||||
asyncRuntime.executeScriptAsync(R"(
|
||||
let globalLet = "let";
|
||||
const globalConst = "const";
|
||||
var globalVar = "var";
|
||||
|
||||
let func1 = () => {
|
||||
let local1 = 111;
|
||||
func2();
|
||||
}
|
||||
|
||||
function func2() {
|
||||
let func3 = () => {
|
||||
let local3 = 333;
|
||||
debugger;
|
||||
}
|
||||
|
||||
let local2 = 222;
|
||||
func3();
|
||||
}
|
||||
|
||||
func1();
|
||||
)");
|
||||
send<m::debugger::EnableRequest>(conn, msgId++);
|
||||
expectExecutionContextCreated(conn);
|
||||
expectNotification<m::debugger::ScriptParsedNotification>(conn);
|
||||
expectNotification<m::debugger::PausedNotification>(conn);
|
||||
|
||||
m::runtime::GlobalLexicalScopeNamesRequest req;
|
||||
req.id = msgId;
|
||||
req.executionContextId = 1;
|
||||
conn.send(req.toJson());
|
||||
|
||||
auto resp =
|
||||
expectResponse<m::runtime::GlobalLexicalScopeNamesResponse>(conn, msgId);
|
||||
EXPECT_EQ(resp.id, msgId++);
|
||||
std::sort(resp.names.begin(), resp.names.end());
|
||||
std::vector<std::string> expectedNames{"func1", "globalConst", "globalLet"};
|
||||
EXPECT_EQ(resp.names, expectedNames);
|
||||
|
||||
send<m::debugger::ResumeRequest>(conn, msgId++);
|
||||
expectNotification<m::debugger::ResumedNotification>(conn);
|
||||
}
|
||||
|
||||
} // namespace chrome
|
||||
} // namespace inspector
|
||||
} // namespace hermes
|
||||
|
|
|
@ -37,3 +37,4 @@ Runtime.executionContextCreated
|
|||
Runtime.getHeapUsage
|
||||
Runtime.getProperties
|
||||
Runtime.runIfWaitingForDebugger
|
||||
Runtime.globalLexicalScopeNames
|
||||
|
|
Загрузка…
Ссылка в новой задаче