mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-06 16:19:23 +00:00
LibJS: Use Identifier to represent CatchClause parameter names
By doing that we consistently use Identifier node for identifiers and also enable mechanism that registers identifiers in a corresponding ScopePusher for catch parameters, which is necessary for work in the upcoming changes.
This commit is contained in:
parent
42f72bbdce
commit
0f14c70252
Notes:
github-actions[bot]
2025-04-22 19:58:36 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 0f14c70252
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4421
Reviewed-by: https://github.com/gmta
4 changed files with 43 additions and 30 deletions
|
@ -1378,19 +1378,17 @@ void TryStatement::dump(int indent) const
|
||||||
void CatchClause::dump(int indent) const
|
void CatchClause::dump(int indent) const
|
||||||
{
|
{
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
m_parameter.visit(
|
|
||||||
[&](FlyString const& parameter) {
|
|
||||||
if (parameter.is_empty())
|
|
||||||
outln("CatchClause");
|
outln("CatchClause");
|
||||||
else
|
m_parameter.visit(
|
||||||
outln("CatchClause ({})", parameter);
|
[&](NonnullRefPtr<Identifier const> const& parameter) {
|
||||||
|
parameter->dump(indent + 1);
|
||||||
},
|
},
|
||||||
[&](NonnullRefPtr<BindingPattern const> const& pattern) {
|
[&](NonnullRefPtr<BindingPattern const> const& pattern) {
|
||||||
outln("CatchClause");
|
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
outln("(Parameter)");
|
outln("(Parameter)");
|
||||||
pattern->dump(indent + 2);
|
pattern->dump(indent + 2);
|
||||||
});
|
},
|
||||||
|
[&](Empty) {});
|
||||||
|
|
||||||
body().dump(indent + 1);
|
body().dump(indent + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2075,7 +2075,7 @@ private:
|
||||||
|
|
||||||
class CatchClause final : public ASTNode {
|
class CatchClause final : public ASTNode {
|
||||||
public:
|
public:
|
||||||
CatchClause(SourceRange source_range, FlyString parameter, NonnullRefPtr<BlockStatement const> body)
|
CatchClause(SourceRange source_range, NonnullRefPtr<Identifier const> parameter, NonnullRefPtr<BlockStatement const> body)
|
||||||
: ASTNode(move(source_range))
|
: ASTNode(move(source_range))
|
||||||
, m_parameter(move(parameter))
|
, m_parameter(move(parameter))
|
||||||
, m_body(move(body))
|
, m_body(move(body))
|
||||||
|
@ -2089,13 +2089,20 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CatchClause(SourceRange source_range, NonnullRefPtr<BlockStatement const> body)
|
||||||
|
: ASTNode(move(source_range))
|
||||||
|
, m_parameter(Empty {})
|
||||||
|
, m_body(move(body))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
auto& parameter() const { return m_parameter; }
|
auto& parameter() const { return m_parameter; }
|
||||||
BlockStatement const& body() const { return m_body; }
|
BlockStatement const& body() const { return m_body; }
|
||||||
|
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Variant<FlyString, NonnullRefPtr<BindingPattern const>> m_parameter;
|
Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>, Empty> m_parameter;
|
||||||
NonnullRefPtr<BlockStatement const> m_body;
|
NonnullRefPtr<BlockStatement const> m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2660,14 +2660,12 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> TryStatement::generate_
|
||||||
bool did_create_variable_scope_for_catch_clause = false;
|
bool did_create_variable_scope_for_catch_clause = false;
|
||||||
|
|
||||||
TRY(m_handler->parameter().visit(
|
TRY(m_handler->parameter().visit(
|
||||||
[&](FlyString const& parameter) -> Bytecode::CodeGenerationErrorOr<void> {
|
[&](NonnullRefPtr<Identifier const> const& parameter) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||||
if (!parameter.is_empty()) {
|
|
||||||
generator.begin_variable_scope();
|
generator.begin_variable_scope();
|
||||||
did_create_variable_scope_for_catch_clause = true;
|
did_create_variable_scope_for_catch_clause = true;
|
||||||
auto parameter_identifier = generator.intern_identifier(parameter);
|
auto parameter_identifier = generator.intern_identifier(parameter->string());
|
||||||
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
|
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
|
||||||
generator.emit<Bytecode::Op::InitializeLexicalBinding>(parameter_identifier, caught_value);
|
generator.emit<Bytecode::Op::InitializeLexicalBinding>(parameter_identifier, caught_value);
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
[&](NonnullRefPtr<BindingPattern const> const& binding_pattern) -> Bytecode::CodeGenerationErrorOr<void> {
|
[&](NonnullRefPtr<BindingPattern const> const& binding_pattern) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||||
|
@ -2675,6 +2673,9 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> TryStatement::generate_
|
||||||
did_create_variable_scope_for_catch_clause = true;
|
did_create_variable_scope_for_catch_clause = true;
|
||||||
TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::BindingInitializationMode::Initialize, caught_value, true));
|
TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::BindingInitializationMode::Initialize, caught_value, true));
|
||||||
return {};
|
return {};
|
||||||
|
},
|
||||||
|
[](Empty) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||||
|
return {};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
auto handler_result = TRY(m_handler->body().generate_bytecode(generator));
|
auto handler_result = TRY(m_handler->body().generate_bytecode(generator));
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
return scope_pusher;
|
return scope_pusher;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScopePusher catch_scope(Parser& parser, RefPtr<BindingPattern const> const& pattern, FlyString const& parameter)
|
static ScopePusher catch_scope(Parser& parser, RefPtr<BindingPattern const> const& pattern, RefPtr<Identifier const> const& parameter)
|
||||||
{
|
{
|
||||||
ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel, ScopeType::Catch);
|
ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel, ScopeType::Catch);
|
||||||
if (pattern) {
|
if (pattern) {
|
||||||
|
@ -114,9 +114,9 @@ public:
|
||||||
scope_pusher.m_forbidden_var_names.set(identifier.string());
|
scope_pusher.m_forbidden_var_names.set(identifier.string());
|
||||||
scope_pusher.m_bound_names.set(identifier.string());
|
scope_pusher.m_bound_names.set(identifier.string());
|
||||||
}));
|
}));
|
||||||
} else if (!parameter.is_empty()) {
|
} else if (parameter) {
|
||||||
scope_pusher.m_var_names.set(parameter);
|
scope_pusher.m_var_names.set(parameter->string());
|
||||||
scope_pusher.m_bound_names.set(parameter);
|
scope_pusher.m_bound_names.set(parameter->string());
|
||||||
}
|
}
|
||||||
|
|
||||||
return scope_pusher;
|
return scope_pusher;
|
||||||
|
@ -3777,7 +3777,7 @@ NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
|
||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
consume(TokenType::Catch);
|
consume(TokenType::Catch);
|
||||||
|
|
||||||
FlyString parameter;
|
RefPtr<Identifier const> parameter;
|
||||||
RefPtr<BindingPattern const> pattern_parameter;
|
RefPtr<BindingPattern const> pattern_parameter;
|
||||||
auto should_expect_parameter = false;
|
auto should_expect_parameter = false;
|
||||||
if (match(TokenType::ParenOpen)) {
|
if (match(TokenType::ParenOpen)) {
|
||||||
|
@ -3787,14 +3787,15 @@ NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
|
||||||
if (match_identifier_name()
|
if (match_identifier_name()
|
||||||
&& (!match(TokenType::Yield) || !m_state.in_generator_function_context)
|
&& (!match(TokenType::Yield) || !m_state.in_generator_function_context)
|
||||||
&& (!match(TokenType::Async) || !m_state.await_expression_is_valid)
|
&& (!match(TokenType::Async) || !m_state.await_expression_is_valid)
|
||||||
&& (!match(TokenType::Await) || !m_state.in_class_static_init_block))
|
&& (!match(TokenType::Await) || !m_state.in_class_static_init_block)) {
|
||||||
parameter = consume().fly_string_value();
|
parameter = parse_identifier();
|
||||||
else
|
} else {
|
||||||
pattern_parameter = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No);
|
pattern_parameter = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No);
|
||||||
|
}
|
||||||
consume(TokenType::ParenClose);
|
consume(TokenType::ParenClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_expect_parameter && parameter.is_empty() && !pattern_parameter)
|
if (should_expect_parameter && !parameter && !pattern_parameter)
|
||||||
expected("an identifier or a binding pattern");
|
expected("an identifier or a binding pattern");
|
||||||
|
|
||||||
HashTable<FlyString> bound_names;
|
HashTable<FlyString> bound_names;
|
||||||
|
@ -3808,9 +3809,9 @@ NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parameter.is_empty()) {
|
if (parameter) {
|
||||||
check_identifier_name_for_assignment_validity(parameter);
|
check_identifier_name_for_assignment_validity(parameter->string());
|
||||||
bound_names.set(parameter);
|
bound_names.set(parameter->string());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopePusher catch_scope = ScopePusher::catch_scope(*this, pattern_parameter, parameter);
|
ScopePusher catch_scope = ScopePusher::catch_scope(*this, pattern_parameter, parameter);
|
||||||
|
@ -3829,9 +3830,15 @@ NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
|
||||||
move(body));
|
move(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameter) {
|
||||||
|
return create_ast_node<CatchClause>(
|
||||||
|
{ m_source_code, rule_start.position(), position() },
|
||||||
|
parameter.release_nonnull(),
|
||||||
|
move(body));
|
||||||
|
}
|
||||||
|
|
||||||
return create_ast_node<CatchClause>(
|
return create_ast_node<CatchClause>(
|
||||||
{ m_source_code, rule_start.position(), position() },
|
{ m_source_code, rule_start.position(), position() },
|
||||||
move(parameter),
|
|
||||||
move(body));
|
move(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue