diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 737a248bf4..f3aff618b8 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -1313,7 +1313,10 @@ Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object) void Identifier::dump(int indent) const { print_indent(indent); - outln("Identifier \"{}\"", m_string); + if (m_argument_index.has_value()) + outln("Identifier \"{}\" (argument #{})", m_string, m_argument_index.value()); + else + outln("Identifier \"{}\"", m_string); } void SpreadExpression::dump(int indent) const diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 62ae3d13de..d36b639251 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -768,13 +768,15 @@ private: class Identifier final : public Expression { public: - explicit Identifier(SourceRange source_range, FlyString const& string) - : Expression(move(source_range)) - , m_string(string) + explicit Identifier(SourceRange source_range, FlyString string, Optional argument_index = {}) + : Expression(source_range) + , m_string(move(string)) + , m_argument_index(move(argument_index)) { } FlyString const& string() const { return m_string; } + Optional const& argument_index() const { return m_argument_index; } virtual Value execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; @@ -785,6 +787,7 @@ private: virtual bool is_identifier() const override { return true; } FlyString m_string; + Optional m_argument_index; }; class ClassMethod final : public ASTNode { diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 95ab39c29f..4f9d0de2b6 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -382,6 +382,8 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe if (function_length == -1) function_length = parameters.size(); + m_parser_state.function_parameters.append(parameters); + auto old_labels_in_scope = move(m_parser_state.m_labels_in_scope); ScopeGuard guard([&]() { m_parser_state.m_labels_in_scope = move(old_labels_in_scope); @@ -411,6 +413,8 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe return nullptr; }(); + m_parser_state.function_parameters.take_last(); + if (!function_body_result.is_null()) { state_rollback_guard.disarm(); discard_saved_state(); @@ -651,7 +655,23 @@ NonnullRefPtr Parser::parse_primary_expression() set_try_parse_arrow_function_expression_failed_at_position(position(), true); } - return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value()); + auto string = consume().value(); + Optional argument_index; + if (!m_parser_state.function_parameters.is_empty()) { + size_t i = 0; + for (auto& parameter : m_parser_state.function_parameters.last()) { + parameter.binding.visit( + [&](FlyString const& name) { + if (name == string) { + argument_index = i; + } + }, + [&](BindingPattern const&) { + }); + ++i; + } + } + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, string, argument_index); } case TokenType::NumericLiteral: return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume_and_validate_numeric_literal().double_value()); @@ -1386,8 +1406,13 @@ NonnullRefPtr Parser::parse_function_node(u8 parse_options) m_parser_state.m_labels_in_scope = move(old_labels_in_scope); }); + m_parser_state.function_parameters.append(parameters); + bool is_strict = false; auto body = parse_block_statement(is_strict); + + m_parser_state.function_parameters.take_last(); + body->add_variables(m_parser_state.m_var_scopes.last()); body->add_functions(m_parser_state.m_function_scopes.last()); return create_ast_node( diff --git a/Userland/Libraries/LibJS/Parser.h b/Userland/Libraries/LibJS/Parser.h index 83a6a01e5e..49e2d9904f 100644 --- a/Userland/Libraries/LibJS/Parser.h +++ b/Userland/Libraries/LibJS/Parser.h @@ -196,6 +196,9 @@ private: Vector> m_var_scopes; Vector> m_let_scopes; Vector> m_function_scopes; + + Vector&> function_parameters; + HashTable m_labels_in_scope; bool m_strict_mode { false }; bool m_allow_super_property_lookup { false };