Skip to content

Commit b716427

Browse files
mattbfbfacebook-github-bot
authored andcommitted
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
1 parent e24ce70 commit b716427

File tree

5 files changed

+165
-2
lines changed

5 files changed

+165
-2
lines changed

ReactCommon/hermes/inspector/chrome/Connection.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class Connection::Impl : public inspector::InspectorObserver,
107107
void handle(const m::runtime::EvaluateRequest &req) override;
108108
void handle(const m::runtime::GetHeapUsageRequest &req) override;
109109
void handle(const m::runtime::GetPropertiesRequest &req) override;
110+
void handle(const m::runtime::GlobalLexicalScopeNamesRequest &req) override;
110111
void handle(const m::runtime::RunIfWaitingForDebuggerRequest &req) override;
111112

112113
private:
@@ -1451,6 +1452,45 @@ void Connection::Impl::handle(const m::runtime::GetPropertiesRequest &req) {
14511452
.thenError<std::exception>(sendErrorToClient(req.id));
14521453
}
14531454

1455+
void Connection::Impl::handle(
1456+
const m::runtime::GlobalLexicalScopeNamesRequest &req) {
1457+
auto resp = std::make_shared<m::runtime::GlobalLexicalScopeNamesResponse>();
1458+
resp->id = req.id;
1459+
1460+
inspector_
1461+
->executeIfEnabled(
1462+
"Runtime.globalLexicalScopeNames",
1463+
[req, resp](const debugger::ProgramState &state) {
1464+
if (req.executionContextId.hasValue() &&
1465+
req.executionContextId.value() != kHermesExecutionContextId) {
1466+
throw std::invalid_argument("Invalid execution context");
1467+
}
1468+
1469+
const debugger::LexicalInfo &lexicalInfo = state.getLexicalInfo(0);
1470+
debugger::ScopeDepth scopeCount = lexicalInfo.getScopesCount();
1471+
if (scopeCount == 0) {
1472+
return;
1473+
}
1474+
1475+
const debugger::ScopeDepth globalScopeIndex = scopeCount - 1;
1476+
uint32_t variableCount =
1477+
lexicalInfo.getVariablesCountInScope(globalScopeIndex);
1478+
resp->names.reserve(variableCount);
1479+
for (uint32_t i = 0; i < variableCount; i++) {
1480+
debugger::String name =
1481+
state.getVariableInfo(0, globalScopeIndex, i).name;
1482+
// The global scope has some entries prefixed with '?', which are
1483+
// not valid identifiers.
1484+
if (!name.empty() && name.front() != '?') {
1485+
resp->names.push_back(name);
1486+
}
1487+
}
1488+
})
1489+
.via(executor_.get())
1490+
.thenValue([this, resp](auto &&) { sendResponseToClient(*resp); })
1491+
.thenError<std::exception>(sendErrorToClient(req.id));
1492+
}
1493+
14541494
void Connection::Impl::handle(
14551495
const m::runtime::RunIfWaitingForDebuggerRequest &req) {
14561496
if (inspector_->isAwaitingDebuggerOnStart()) {

ReactCommon/hermes/inspector/chrome/MessageTypes.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
2-
// @generated SignedSource<<f6f9a72f332587809b4e50ab054e0a74>>
2+
// @generated SignedSource<<d10e11c5f88b40149af7ace19008d0fc>>
33

44
#include "MessageTypes.h"
55

@@ -66,6 +66,8 @@ std::unique_ptr<Request> Request::fromJsonThrowOnError(const std::string &str) {
6666
{"Runtime.evaluate", makeUnique<runtime::EvaluateRequest>},
6767
{"Runtime.getHeapUsage", makeUnique<runtime::GetHeapUsageRequest>},
6868
{"Runtime.getProperties", makeUnique<runtime::GetPropertiesRequest>},
69+
{"Runtime.globalLexicalScopeNames",
70+
makeUnique<runtime::GlobalLexicalScopeNamesRequest>},
6971
{"Runtime.runIfWaitingForDebugger",
7072
makeUnique<runtime::RunIfWaitingForDebuggerRequest>},
7173
};
@@ -1199,6 +1201,38 @@ void runtime::GetPropertiesRequest::accept(RequestHandler &handler) const {
11991201
handler.handle(*this);
12001202
}
12011203

1204+
runtime::GlobalLexicalScopeNamesRequest::GlobalLexicalScopeNamesRequest()
1205+
: Request("Runtime.globalLexicalScopeNames") {}
1206+
1207+
runtime::GlobalLexicalScopeNamesRequest::GlobalLexicalScopeNamesRequest(
1208+
const dynamic &obj)
1209+
: Request("Runtime.globalLexicalScopeNames") {
1210+
assign(id, obj, "id");
1211+
assign(method, obj, "method");
1212+
1213+
auto it = obj.find("params");
1214+
if (it != obj.items().end()) {
1215+
dynamic params = it->second;
1216+
assign(executionContextId, params, "executionContextId");
1217+
}
1218+
}
1219+
1220+
dynamic runtime::GlobalLexicalScopeNamesRequest::toDynamic() const {
1221+
dynamic params = dynamic::object;
1222+
put(params, "executionContextId", executionContextId);
1223+
1224+
dynamic obj = dynamic::object;
1225+
put(obj, "id", id);
1226+
put(obj, "method", method);
1227+
put(obj, "params", std::move(params));
1228+
return obj;
1229+
}
1230+
1231+
void runtime::GlobalLexicalScopeNamesRequest::accept(
1232+
RequestHandler &handler) const {
1233+
handler.handle(*this);
1234+
}
1235+
12021236
runtime::RunIfWaitingForDebuggerRequest::RunIfWaitingForDebuggerRequest()
12031237
: Request("Runtime.runIfWaitingForDebugger") {}
12041238

@@ -1481,6 +1515,24 @@ dynamic runtime::GetPropertiesResponse::toDynamic() const {
14811515
return obj;
14821516
}
14831517

1518+
runtime::GlobalLexicalScopeNamesResponse::GlobalLexicalScopeNamesResponse(
1519+
const dynamic &obj) {
1520+
assign(id, obj, "id");
1521+
1522+
dynamic res = obj.at("result");
1523+
assign(names, res, "names");
1524+
}
1525+
1526+
dynamic runtime::GlobalLexicalScopeNamesResponse::toDynamic() const {
1527+
dynamic res = dynamic::object;
1528+
put(res, "names", names);
1529+
1530+
dynamic obj = dynamic::object;
1531+
put(obj, "id", id);
1532+
put(obj, "result", std::move(res));
1533+
return obj;
1534+
}
1535+
14841536
/// Notifications
14851537
debugger::BreakpointResolvedNotification::BreakpointResolvedNotification()
14861538
: Notification("Debugger.breakpointResolved") {}

ReactCommon/hermes/inspector/chrome/MessageTypes.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
2-
// @generated SignedSource<<fcbcfeecbc72ca30c8ed005ad47839bb>>
2+
// @generated SignedSource<<dafd583635231e17c0264beb38610499>>
33

44
#pragma once
55

@@ -63,6 +63,8 @@ struct GetHeapUsageRequest;
6363
struct GetHeapUsageResponse;
6464
struct GetPropertiesRequest;
6565
struct GetPropertiesResponse;
66+
struct GlobalLexicalScopeNamesRequest;
67+
struct GlobalLexicalScopeNamesResponse;
6668
struct InternalPropertyDescriptor;
6769
struct PropertyDescriptor;
6870
struct RemoteObject;
@@ -142,6 +144,7 @@ struct RequestHandler {
142144
virtual void handle(const runtime::EvaluateRequest &req) = 0;
143145
virtual void handle(const runtime::GetHeapUsageRequest &req) = 0;
144146
virtual void handle(const runtime::GetPropertiesRequest &req) = 0;
147+
virtual void handle(const runtime::GlobalLexicalScopeNamesRequest &req) = 0;
145148
virtual void handle(const runtime::RunIfWaitingForDebuggerRequest &req) = 0;
146149
};
147150

@@ -180,6 +183,7 @@ struct NoopRequestHandler : public RequestHandler {
180183
void handle(const runtime::EvaluateRequest &req) override {}
181184
void handle(const runtime::GetHeapUsageRequest &req) override {}
182185
void handle(const runtime::GetPropertiesRequest &req) override {}
186+
void handle(const runtime::GlobalLexicalScopeNamesRequest &req) override {}
183187
void handle(const runtime::RunIfWaitingForDebuggerRequest &req) override {}
184188
};
185189

@@ -686,6 +690,16 @@ struct runtime::GetPropertiesRequest : public Request {
686690
folly::Optional<bool> ownProperties;
687691
};
688692

693+
struct runtime::GlobalLexicalScopeNamesRequest : public Request {
694+
GlobalLexicalScopeNamesRequest();
695+
explicit GlobalLexicalScopeNamesRequest(const folly::dynamic &obj);
696+
697+
folly::dynamic toDynamic() const override;
698+
void accept(RequestHandler &handler) const override;
699+
700+
folly::Optional<runtime::ExecutionContextId> executionContextId;
701+
};
702+
689703
struct runtime::RunIfWaitingForDebuggerRequest : public Request {
690704
RunIfWaitingForDebuggerRequest();
691705
explicit RunIfWaitingForDebuggerRequest(const folly::dynamic &obj);
@@ -816,6 +830,14 @@ struct runtime::GetPropertiesResponse : public Response {
816830
folly::Optional<runtime::ExceptionDetails> exceptionDetails;
817831
};
818832

833+
struct runtime::GlobalLexicalScopeNamesResponse : public Response {
834+
GlobalLexicalScopeNamesResponse() = default;
835+
explicit GlobalLexicalScopeNamesResponse(const folly::dynamic &obj);
836+
folly::dynamic toDynamic() const override;
837+
838+
std::vector<std::string> names;
839+
};
840+
819841
/// Notifications
820842
struct debugger::BreakpointResolvedNotification : public Notification {
821843
BreakpointResolvedNotification();

ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2884,6 +2884,54 @@ TEST(ConnectionTests, testBasicProfilerOperation) {
28842884
asyncRuntime.stop();
28852885
}
28862886

2887+
TEST(ConnectionTests, testGlobalLexicalScopeNames) {
2888+
TestContext context;
2889+
AsyncHermesRuntime &asyncRuntime = context.runtime();
2890+
SyncConnection &conn = context.conn();
2891+
int msgId = 1;
2892+
asyncRuntime.executeScriptAsync(R"(
2893+
let globalLet = "let";
2894+
const globalConst = "const";
2895+
var globalVar = "var";
2896+
2897+
let func1 = () => {
2898+
let local1 = 111;
2899+
func2();
2900+
}
2901+
2902+
function func2() {
2903+
let func3 = () => {
2904+
let local3 = 333;
2905+
debugger;
2906+
}
2907+
2908+
let local2 = 222;
2909+
func3();
2910+
}
2911+
2912+
func1();
2913+
)");
2914+
send<m::debugger::EnableRequest>(conn, msgId++);
2915+
expectExecutionContextCreated(conn);
2916+
expectNotification<m::debugger::ScriptParsedNotification>(conn);
2917+
expectNotification<m::debugger::PausedNotification>(conn);
2918+
2919+
m::runtime::GlobalLexicalScopeNamesRequest req;
2920+
req.id = msgId;
2921+
req.executionContextId = 1;
2922+
conn.send(req.toJson());
2923+
2924+
auto resp =
2925+
expectResponse<m::runtime::GlobalLexicalScopeNamesResponse>(conn, msgId);
2926+
EXPECT_EQ(resp.id, msgId++);
2927+
std::sort(resp.names.begin(), resp.names.end());
2928+
std::vector<std::string> expectedNames{"func1", "globalConst", "globalLet"};
2929+
EXPECT_EQ(resp.names, expectedNames);
2930+
2931+
send<m::debugger::ResumeRequest>(conn, msgId++);
2932+
expectNotification<m::debugger::ResumedNotification>(conn);
2933+
}
2934+
28872935
} // namespace chrome
28882936
} // namespace inspector
28892937
} // namespace hermes

ReactCommon/hermes/inspector/tools/message_types.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ Runtime.executionContextCreated
3737
Runtime.getHeapUsage
3838
Runtime.getProperties
3939
Runtime.runIfWaitingForDebugger
40+
Runtime.globalLexicalScopeNames

0 commit comments

Comments
 (0)