From 7f0074ac2359b505eceba7096e3b96db085cfc30 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sun, 2 Jul 2023 01:04:07 +0300 Subject: [PATCH] LibJS: Add for_each_bound_identifier for AST::Declaration The same as for_each_bound_name but for identifiers. --- Userland/Libraries/LibJS/AST.cpp | 59 ++++++++++++++++++++++++++++++++ Userland/Libraries/LibJS/AST.h | 20 ++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 866721b093..a85a277d1e 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -2308,6 +2308,14 @@ ThrowCompletionOr ClassDeclaration::for_each_bound_name(ThrowCompletionOrV return callback(m_class_expression->name()); } +ThrowCompletionOr ClassDeclaration::for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const +{ + if (!m_class_expression->m_name) + return {}; + + return callback(*m_class_expression->m_name); +} + void ClassExpression::dump(int indent) const { print_indent(indent); @@ -2447,6 +2455,23 @@ ThrowCompletionOr BindingPattern::for_each_bound_name(ThrowCompletionOrVoi return {}; } +ThrowCompletionOr BindingPattern::for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const +{ + for (auto const& entry : entries) { + auto const& alias = entry.alias; + if (alias.has>()) { + TRY(callback(alias.get>())); + } else if (alias.has>()) { + TRY(alias.get>()->for_each_bound_identifier(forward(callback))); + } else { + auto const& name = entry.name; + if (name.has>()) + TRY(callback(name.get>())); + } + } + return {}; +} + void BindingPattern::dump(int indent) const { print_indent(indent); @@ -2541,6 +2566,13 @@ ThrowCompletionOr FunctionDeclaration::for_each_bound_name(ThrowCompletion return callback(name()); } +ThrowCompletionOr FunctionDeclaration::for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const +{ + if (!m_name) + return {}; + return callback(*m_name); +} + void FunctionExpression::dump(int indent) const { FunctionNode::dump(indent, class_name()); @@ -3099,6 +3131,23 @@ ThrowCompletionOr VariableDeclaration::for_each_bound_name(ThrowCompletion return {}; } +ThrowCompletionOr VariableDeclaration::for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const +{ + for (auto const& entry : declarations()) { + TRY(entry->target().visit( + [&](NonnullRefPtr const& id) { + return callback(id); + }, + [&](NonnullRefPtr const& binding) { + return binding->for_each_bound_identifier([&](auto const& id) { + return callback(id); + }); + })); + } + + return {}; +} + void VariableDeclaration::dump(int indent) const { char const* declaration_kind_string = nullptr; @@ -3156,6 +3205,16 @@ ThrowCompletionOr UsingDeclaration::for_each_bound_name(ThrowCompletionOrV return {}; } +ThrowCompletionOr UsingDeclaration::for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const +{ + for (auto const& entry : m_declarations) { + VERIFY(entry->target().has>()); + TRY(callback(entry->target().get>())); + } + + return {}; +} + void UsingDeclaration::dump(int indent) const { ASTNode::dump(indent); diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index ae8fcebc9e..70fd796cec 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -609,6 +609,7 @@ public: } virtual ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const = 0; + virtual ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const = 0; // 8.1.3 Static Semantics: IsConstantDeclaration, https://tc39.es/ecma262/#sec-static-semantics-isconstantdeclaration virtual bool is_constant_declaration() const { return false; } @@ -628,6 +629,11 @@ public: { VERIFY_NOT_REACHED(); } + + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&&) const override + { + VERIFY_NOT_REACHED(); + } }; struct BindingPattern : RefCounted { @@ -650,6 +656,7 @@ struct BindingPattern : RefCounted { void dump(int indent) const; ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const; + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&& callback) const; bool contains_expression() const; @@ -729,8 +736,9 @@ protected: void dump(int indent, DeprecatedString const& class_name) const; -private: RefPtr m_name { nullptr }; + +private: DeprecatedString m_source_text; NonnullRefPtr m_body; Vector const m_parameters; @@ -762,6 +770,8 @@ public: virtual ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const override; + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&&) const override; + virtual bool is_function_declaration() const override { return true; } void set_should_do_additional_annexB_steps() { m_is_hoisted = true; } @@ -1458,6 +1468,8 @@ public: private: virtual bool is_class_expression() const override { return true; } + friend ClassDeclaration; + RefPtr m_name; DeprecatedString m_source_text; RefPtr m_constructor; @@ -1479,6 +1491,8 @@ public: virtual ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const override; + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&&) const override; + virtual bool is_lexical_declaration() const override { return true; } StringView name() const { return m_class_expression->name(); } @@ -1785,6 +1799,8 @@ public: virtual ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const override; + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&&) const override; + virtual bool is_constant_declaration() const override { return m_declaration_kind == DeclarationKind::Const; }; virtual bool is_lexical_declaration() const override { return m_declaration_kind != DeclarationKind::Var; } @@ -1809,6 +1825,8 @@ public: virtual ThrowCompletionOr for_each_bound_name(ThrowCompletionOrVoidCallback&& callback) const override; + ThrowCompletionOr for_each_bound_identifier(ThrowCompletionOrVoidCallback&&) const override; + virtual bool is_constant_declaration() const override { return true; }; virtual bool is_lexical_declaration() const override { return true; }