mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 03:18:11 +00:00
LibJS: Use local variables for function declarations when possible
Previously, the usage of local variables was limited for all function declarations. This change relaxes the restriction and only prohibits locals for hoistable annexB declarations.
This commit is contained in:
parent
167495b87b
commit
8b6450842e
4 changed files with 36 additions and 26 deletions
|
@ -283,18 +283,6 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_functions_to_hoist.size(); i++) {
|
||||
auto const& function_declaration = m_functions_to_hoist[i];
|
||||
if (m_lexical_names.contains(function_declaration->name()) || m_forbidden_var_names.contains(function_declaration->name()))
|
||||
continue;
|
||||
if (is_top_level()) {
|
||||
m_node->add_hoisted_function(move(m_functions_to_hoist[i]));
|
||||
} else {
|
||||
if (!m_parent_scope->m_lexical_names.contains(function_declaration->name()) && !m_parent_scope->m_function_names.contains(function_declaration->name()))
|
||||
m_parent_scope->m_functions_to_hoist.append(move(m_functions_to_hoist[i]));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& it : m_identifier_groups) {
|
||||
auto const& identifier_group_name = it.key;
|
||||
auto& identifier_group = it.value;
|
||||
|
@ -316,20 +304,21 @@ public:
|
|||
scope_has_declaration = true;
|
||||
}));
|
||||
|
||||
bool function_declaration = false;
|
||||
MUST(m_node->for_each_var_function_declaration_in_reverse_order([&](auto const& declaration) {
|
||||
if (declaration.name() == identifier_group_name)
|
||||
function_declaration = true;
|
||||
scope_has_declaration = true;
|
||||
}));
|
||||
MUST(m_node->for_each_lexical_function_declaration_in_reverse_order([&](auto const& declaration) {
|
||||
if (declaration.name() == identifier_group_name)
|
||||
function_declaration = true;
|
||||
}));
|
||||
MUST(m_node->for_each_function_hoistable_with_annexB_extension([&](auto const& declaration) {
|
||||
if (declaration.name() == identifier_group_name)
|
||||
function_declaration = true;
|
||||
scope_has_declaration = true;
|
||||
}));
|
||||
|
||||
bool hoistable_function_declaration = false;
|
||||
for (auto const& function_declaration : m_functions_to_hoist) {
|
||||
if (function_declaration->name() == identifier_group_name)
|
||||
hoistable_function_declaration = true;
|
||||
}
|
||||
|
||||
if ((m_type == ScopeType::ClassDeclaration || m_type == ScopeType::Catch) && m_bound_names.contains(identifier_group_name)) {
|
||||
// NOTE: Currently class names and catch section parameters are not considered to become local variables
|
||||
// but this might be fixed in the future
|
||||
|
@ -346,7 +335,7 @@ public:
|
|||
}
|
||||
|
||||
if (scope_has_declaration) {
|
||||
if (function_declaration)
|
||||
if (hoistable_function_declaration)
|
||||
continue;
|
||||
|
||||
if (!identifier_group.captured_by_nested_function) {
|
||||
|
@ -377,6 +366,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_functions_to_hoist.size(); i++) {
|
||||
auto const& function_declaration = m_functions_to_hoist[i];
|
||||
if (m_lexical_names.contains(function_declaration->name()) || m_forbidden_var_names.contains(function_declaration->name()))
|
||||
continue;
|
||||
if (is_top_level()) {
|
||||
m_node->add_hoisted_function(move(m_functions_to_hoist[i]));
|
||||
} else {
|
||||
if (!m_parent_scope->m_lexical_names.contains(function_declaration->name()) && !m_parent_scope->m_function_names.contains(function_declaration->name()))
|
||||
m_parent_scope->m_functions_to_hoist.append(move(m_functions_to_hoist[i]));
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY(m_parser.m_state.current_scope_pusher == this);
|
||||
m_parser.m_state.current_scope_pusher = m_parent_scope;
|
||||
}
|
||||
|
@ -2799,15 +2800,15 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(u16 parse_options, O
|
|||
}
|
||||
|
||||
if (parse_options & FunctionNodeParseOptions::HasDefaultExportName) {
|
||||
name = create_ast_node<Identifier const>(
|
||||
name = create_identifier_and_register_in_current_scope(
|
||||
{ m_source_code, rule_start.position(), position() },
|
||||
ExportStatement::local_name_for_default);
|
||||
} else if (FunctionNodeType::must_have_name() || match_identifier()) {
|
||||
name = create_ast_node<Identifier const>(
|
||||
name = create_identifier_and_register_in_current_scope(
|
||||
{ m_source_code, rule_start.position(), position() },
|
||||
consume_identifier().DeprecatedFlyString_value());
|
||||
} else if (is_function_expression && (match(TokenType::Yield) || match(TokenType::Await))) {
|
||||
name = create_ast_node<Identifier const>(
|
||||
name = create_identifier_and_register_in_current_scope(
|
||||
{ m_source_code, rule_start.position(), position() },
|
||||
consume().DeprecatedFlyString_value());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue