diff --git a/Userland/Libraries/LibJS/Lexer.cpp b/Userland/Libraries/LibJS/Lexer.cpp index cf9b787a76..8a9a3d27f3 100644 --- a/Userland/Libraries/LibJS/Lexer.cpp +++ b/Userland/Libraries/LibJS/Lexer.cpp @@ -38,9 +38,12 @@ HashMap Lexer::s_three_char_tokens; HashMap Lexer::s_two_char_tokens; HashMap Lexer::s_single_char_tokens; -Lexer::Lexer(StringView source) +Lexer::Lexer(StringView source, StringView filename, size_t line_number, size_t line_column) : m_source(source) - , m_current_token(TokenType::Eof, {}, StringView(nullptr), StringView(nullptr), 0, 0) + , m_current_token(TokenType::Eof, {}, StringView(nullptr), StringView(nullptr), filename, 0, 0) + , m_filename(filename) + , m_line_number(line_number) + , m_line_column(line_column) { if (s_keywords.is_empty()) { s_keywords.set("await", TokenType::Await); @@ -635,6 +638,7 @@ Token Lexer::next() token_message, m_source.substring_view(trivia_start - 1, value_start - trivia_start), m_source.substring_view(value_start - 1, m_position - value_start), + m_filename, value_start_line_number, value_start_column_number); diff --git a/Userland/Libraries/LibJS/Lexer.h b/Userland/Libraries/LibJS/Lexer.h index 3efe290aa8..3d769ada50 100644 --- a/Userland/Libraries/LibJS/Lexer.h +++ b/Userland/Libraries/LibJS/Lexer.h @@ -36,11 +36,12 @@ namespace JS { class Lexer { public: - explicit Lexer(StringView source); + explicit Lexer(StringView source, StringView filename = "(unknown)", size_t line_number = 1, size_t line_column = 0); Token next(); const StringView& source() const { return m_source; }; + const StringView& filename() const { return m_filename; }; private: void consume(); @@ -65,6 +66,8 @@ private: size_t m_position { 0 }; Token m_current_token; char m_current_char { 0 }; + + StringView m_filename; size_t m_line_number { 1 }; size_t m_line_column { 0 }; diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 56483b9866..918a7f4a5d 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -248,7 +248,7 @@ NonnullRefPtr Parser::parse_program() { auto rule_start = push_start(); ScopePusher scope(*this, ScopePusher::Var | ScopePusher::Let | ScopePusher::Function); - auto program = adopt(*new Program({ rule_start.position(), position() })); + auto program = adopt(*new Program({ m_filename, rule_start.position(), position() })); bool first = true; while (!done()) { @@ -299,7 +299,7 @@ NonnullRefPtr Parser::parse_declaration() default: expected("declaration"); consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } } @@ -339,7 +339,7 @@ NonnullRefPtr Parser::parse_statement() return parse_debugger_statement(); case TokenType::Semicolon: consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); default: if (match(TokenType::Identifier)) { auto result = try_parse_labelled_statement(); @@ -351,11 +351,11 @@ NonnullRefPtr Parser::parse_statement() syntax_error("Function declaration not allowed in single-statement context"); auto expr = parse_expression(0); consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }, move(expr)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expr)); } expected("statement"); consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } } @@ -423,8 +423,8 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe // Esprima generates a single "ArrowFunctionExpression" // with a "body" property. auto return_expression = parse_expression(2); - auto return_block = create_ast_node({ rule_start.position(), position() }); - return_block->append({ rule_start.position(), position() }, move(return_expression)); + auto return_block = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); + return_block->append({ m_filename, rule_start.position(), position() }, move(return_expression)); return return_block; } // Invalid arrow function body @@ -435,7 +435,7 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe state_rollback_guard.disarm(); discard_saved_state(); auto body = function_body_result.release_nonnull(); - return create_ast_node({ rule_start.position(), position() }, "", move(body), move(parameters), function_length, m_parser_state.m_var_scopes.take_last(), is_strict, true); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, "", move(body), move(parameters), function_length, m_parser_state.m_var_scopes.take_last(), is_strict, true); } return nullptr; @@ -485,13 +485,13 @@ RefPtr Parser::try_parse_new_target_expression() state_rollback_guard.disarm(); discard_saved_state(); - return create_ast_node({ rule_start.position(), position() }, MetaProperty::Type::NewTarget); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, MetaProperty::Type::NewTarget); } NonnullRefPtr Parser::parse_class_declaration() { auto rule_start = push_start(); - return create_ast_node({ rule_start.position(), position() }, parse_class_expression(true)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, parse_class_expression(true)); } NonnullRefPtr Parser::parse_class_expression(bool expect_class_name) @@ -549,7 +549,7 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ switch (m_parser_state.m_current_token.type()) { case TokenType::Identifier: name = consume().value(); - property_key = create_ast_node({ rule_start.position(), position() }, name); + property_key = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, name); break; case TokenType::StringLiteral: { auto string_literal = parse_string_literal(consume()); @@ -589,7 +589,7 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ if (is_constructor) { constructor = move(function); } else if (!property_key.is_null()) { - methods.append(create_ast_node({ rule_start.position(), position() }, property_key.release_nonnull(), move(function), method_kind, is_static)); + methods.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, property_key.release_nonnull(), move(function), method_kind, is_static)); } else { syntax_error("No key for class method"); } @@ -602,21 +602,21 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ consume(TokenType::CurlyClose); if (constructor.is_null()) { - auto constructor_body = create_ast_node({ rule_start.position(), position() }); + auto constructor_body = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); if (!super_class.is_null()) { // Set constructor to the result of parsing the source text // constructor(... args){ super (...args);} - auto super_call = create_ast_node({ rule_start.position(), position() }, create_ast_node({ rule_start.position(), position() }), Vector { CallExpression::Argument { create_ast_node({ rule_start.position(), position() }, "args"), true } }); - constructor_body->append(create_ast_node({ rule_start.position(), position() }, move(super_call))); + auto super_call = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }), Vector { CallExpression::Argument { create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, "args"), true } }); + constructor_body->append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(super_call))); constructor_body->add_variables(m_parser_state.m_var_scopes.last()); - constructor = create_ast_node({ rule_start.position(), position() }, class_name, move(constructor_body), Vector { FunctionNode::Parameter { "args", nullptr, true } }, 0, NonnullRefPtrVector(), true); + constructor = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, class_name, move(constructor_body), Vector { FunctionNode::Parameter { "args", nullptr, true } }, 0, NonnullRefPtrVector(), true); } else { - constructor = create_ast_node({ rule_start.position(), position() }, class_name, move(constructor_body), Vector {}, 0, NonnullRefPtrVector(), true); + constructor = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, class_name, move(constructor_body), Vector {}, 0, NonnullRefPtrVector(), true); } } - return create_ast_node({ rule_start.position(), position() }, move(class_name), move(constructor), move(super_class), move(methods)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(class_name), move(constructor), move(super_class), move(methods)); } NonnullRefPtr Parser::parse_primary_expression() @@ -639,31 +639,31 @@ NonnullRefPtr Parser::parse_primary_expression() } case TokenType::This: consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); case TokenType::Class: return parse_class_expression(false); case TokenType::Super: consume(); if (!m_parser_state.m_allow_super_property_lookup) syntax_error("'super' keyword unexpected here"); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); case TokenType::Identifier: { auto arrow_function_result = try_parse_arrow_function_expression(false); if (!arrow_function_result.is_null()) return arrow_function_result.release_nonnull(); - return create_ast_node({ rule_start.position(), position() }, consume().value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value()); } case TokenType::NumericLiteral: - return create_ast_node({ rule_start.position(), position() }, consume_and_validate_numeric_literal().double_value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume_and_validate_numeric_literal().double_value()); case TokenType::BigIntLiteral: - return create_ast_node({ rule_start.position(), position() }, consume().value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value()); case TokenType::BoolLiteral: - return create_ast_node({ rule_start.position(), position() }, consume().bool_value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().bool_value()); case TokenType::StringLiteral: return parse_string_literal(consume()); case TokenType::NullLiteral: consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); case TokenType::CurlyOpen: return parse_object_expression(); case TokenType::Function: @@ -687,7 +687,7 @@ NonnullRefPtr Parser::parse_primary_expression() default: expected("primary expression"); consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } } @@ -696,7 +696,7 @@ NonnullRefPtr Parser::parse_regexp_literal() auto rule_start = push_start(); auto content = consume().value(); auto flags = match(TokenType::RegexFlags) ? consume().value() : ""; - return create_ast_node({ rule_start.position(), position() }, content.substring_view(1, content.length() - 2), flags); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, content.substring_view(1, content.length() - 2), flags); } NonnullRefPtr Parser::parse_unary_prefixed_expression() @@ -713,7 +713,7 @@ NonnullRefPtr Parser::parse_unary_prefixed_expression() // other engines throw ReferenceError for ++foo() if (!is(*rhs) && !is(*rhs)) syntax_error(String::formatted("Right-hand side of prefix increment operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); - return create_ast_node({ rule_start.position(), position() }, UpdateOp::Increment, move(rhs), true); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UpdateOp::Increment, move(rhs), true); } case TokenType::MinusMinus: { consume(); @@ -723,33 +723,33 @@ NonnullRefPtr Parser::parse_unary_prefixed_expression() // other engines throw ReferenceError for --foo() if (!is(*rhs) && !is(*rhs)) syntax_error(String::formatted("Right-hand side of prefix decrement operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); - return create_ast_node({ rule_start.position(), position() }, UpdateOp::Decrement, move(rhs), true); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UpdateOp::Decrement, move(rhs), true); } case TokenType::ExclamationMark: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Not, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Not, parse_expression(precedence, associativity)); case TokenType::Tilde: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::BitwiseNot, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::BitwiseNot, parse_expression(precedence, associativity)); case TokenType::Plus: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Plus, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Plus, parse_expression(precedence, associativity)); case TokenType::Minus: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Minus, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Minus, parse_expression(precedence, associativity)); case TokenType::Typeof: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Typeof, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Typeof, parse_expression(precedence, associativity)); case TokenType::Void: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Void, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Void, parse_expression(precedence, associativity)); case TokenType::Delete: consume(); - return create_ast_node({ rule_start.position(), position() }, UnaryOp::Delete, parse_expression(precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UnaryOp::Delete, parse_expression(precedence, associativity)); default: expected("primary expression"); consume(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } } @@ -759,9 +759,9 @@ NonnullRefPtr Parser::parse_property_key() if (match(TokenType::StringLiteral)) { return parse_string_literal(consume()); } else if (match(TokenType::NumericLiteral)) { - return create_ast_node({ rule_start.position(), position() }, consume().double_value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().double_value()); } else if (match(TokenType::BigIntLiteral)) { - return create_ast_node({ rule_start.position(), position() }, consume().value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value()); } else if (match(TokenType::BracketOpen)) { consume(TokenType::BracketOpen); auto result = parse_expression(0); @@ -770,7 +770,7 @@ NonnullRefPtr Parser::parse_property_key() } else { if (!match_identifier_name()) expected("IdentifierName"); - return create_ast_node({ rule_start.position(), position() }, consume().value()); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value()); } } @@ -795,7 +795,7 @@ NonnullRefPtr Parser::parse_object_expression() if (match(TokenType::TripleDot)) { consume(); property_name = parse_expression(4); - properties.append(create_ast_node({ rule_start.position(), position() }, *property_name, nullptr, ObjectProperty::Type::Spread, false)); + properties.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, *property_name, nullptr, ObjectProperty::Type::Spread, false)); if (!match(TokenType::Comma)) break; consume(TokenType::Comma); @@ -811,8 +811,8 @@ NonnullRefPtr Parser::parse_object_expression() property_type = ObjectProperty::Type::Setter; property_name = parse_property_key(); } else { - property_name = create_ast_node({ rule_start.position(), position() }, identifier); - property_value = create_ast_node({ rule_start.position(), position() }, identifier); + property_name = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, identifier); + property_value = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, identifier); } } else { property_name = parse_property_key(); @@ -834,7 +834,7 @@ NonnullRefPtr Parser::parse_object_expression() if (property_type == ObjectProperty::Type::Setter) parse_options |= FunctionNodeParseOptions::IsSetterFunction; auto function = parse_function_node(parse_options); - properties.append(create_ast_node({ rule_start.position(), position() }, *property_name, function, property_type, true)); + properties.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, *property_name, function, property_type, true)); } else if (match(TokenType::Colon)) { if (!property_name) { syntax_error("Expected a property name"); @@ -842,9 +842,9 @@ NonnullRefPtr Parser::parse_object_expression() continue; } consume(); - properties.append(create_ast_node({ rule_start.position(), position() }, *property_name, parse_expression(2), property_type, false)); + properties.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, *property_name, parse_expression(2), property_type, false)); } else if (property_name && property_value) { - properties.append(create_ast_node({ rule_start.position(), position() }, *property_name, *property_value, property_type, false)); + properties.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, *property_name, *property_value, property_type, false)); } else { syntax_error("Expected a property"); skip_to_next_property(); @@ -857,7 +857,7 @@ NonnullRefPtr Parser::parse_object_expression() } consume(TokenType::CurlyClose); - return create_ast_node({ rule_start.position(), position() }, properties); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, properties); } NonnullRefPtr Parser::parse_array_expression() @@ -871,7 +871,7 @@ NonnullRefPtr Parser::parse_array_expression() if (match(TokenType::TripleDot)) { consume(TokenType::TripleDot); - expression = create_ast_node({ rule_start.position(), position() }, parse_expression(2)); + expression = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, parse_expression(2)); } else if (match_expression()) { expression = parse_expression(2); } @@ -883,7 +883,7 @@ NonnullRefPtr Parser::parse_array_expression() } consume(TokenType::BracketClose); - return create_ast_node({ rule_start.position(), position() }, move(elements)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(elements)); } NonnullRefPtr Parser::parse_string_literal(const Token& token, bool in_template_literal) @@ -914,7 +914,7 @@ NonnullRefPtr Parser::parse_string_literal(const Token& token, bo auto is_use_strict_directive = !in_template_literal && (token.value() == "'use strict'" || token.value() == "\"use strict\""); - return create_ast_node({ rule_start.position(), position() }, string, is_use_strict_directive); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, string, is_use_strict_directive); } NonnullRefPtr Parser::parse_template_literal(bool is_tagged) @@ -926,7 +926,7 @@ NonnullRefPtr Parser::parse_template_literal(bool is_tagged) NonnullRefPtrVector raw_strings; auto append_empty_string = [this, &rule_start, &expressions, &raw_strings, is_tagged]() { - auto string_literal = create_ast_node({ rule_start.position(), position() }, ""); + auto string_literal = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, ""); expressions.append(string_literal); if (is_tagged) raw_strings.append(string_literal); @@ -940,18 +940,18 @@ NonnullRefPtr Parser::parse_template_literal(bool is_tagged) auto token = consume(); expressions.append(parse_string_literal(token, true)); if (is_tagged) - raw_strings.append(create_ast_node({ rule_start.position(), position() }, token.value())); + raw_strings.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, token.value())); } else if (match(TokenType::TemplateLiteralExprStart)) { consume(TokenType::TemplateLiteralExprStart); if (match(TokenType::TemplateLiteralExprEnd)) { syntax_error("Empty template literal expression block"); - return create_ast_node({ rule_start.position(), position() }, expressions); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, expressions); } expressions.append(parse_expression(0)); if (match(TokenType::UnterminatedTemplateLiteral)) { syntax_error("Unterminated template literal"); - return create_ast_node({ rule_start.position(), position() }, expressions); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, expressions); } consume(TokenType::TemplateLiteralExprEnd); @@ -970,8 +970,8 @@ NonnullRefPtr Parser::parse_template_literal(bool is_tagged) } if (is_tagged) - return create_ast_node({ rule_start.position(), position() }, expressions, raw_strings); - return create_ast_node({ rule_start.position(), position() }, expressions); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, expressions, raw_strings); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, expressions); } NonnullRefPtr Parser::parse_expression(int min_precedence, Associativity associativity, const Vector& forbidden) @@ -980,7 +980,7 @@ NonnullRefPtr Parser::parse_expression(int min_precedence, Associati auto expression = parse_primary_expression(); while (match(TokenType::TemplateLiteralStart)) { auto template_literal = parse_template_literal(true); - expression = create_ast_node({ rule_start.position(), position() }, move(expression), move(template_literal)); + expression = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expression), move(template_literal)); } while (match_secondary_expression(forbidden)) { int new_precedence = g_operator_precedence.get(m_parser_state.m_current_token.type()); @@ -993,7 +993,7 @@ NonnullRefPtr Parser::parse_expression(int min_precedence, Associati expression = parse_secondary_expression(move(expression), new_precedence, new_associativity); while (match(TokenType::TemplateLiteralStart)) { auto template_literal = parse_template_literal(true); - expression = create_ast_node({ rule_start.position(), position() }, move(expression), move(template_literal)); + expression = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expression), move(template_literal)); } } if (match(TokenType::Comma) && min_precedence <= 1) { @@ -1003,7 +1003,7 @@ NonnullRefPtr Parser::parse_expression(int min_precedence, Associati consume(); expressions.append(parse_expression(2)); } - expression = create_ast_node({ rule_start.position(), position() }, move(expressions)); + expression = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expressions)); } return expression; } @@ -1014,92 +1014,92 @@ NonnullRefPtr Parser::parse_secondary_expression(NonnullRefPtr({ rule_start.position(), position() }, BinaryOp::Addition, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Addition, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::PlusEquals: return parse_assignment_expression(AssignmentOp::AdditionAssignment, move(lhs), min_precedence, associativity); case TokenType::Minus: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::Subtraction, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Subtraction, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::MinusEquals: return parse_assignment_expression(AssignmentOp::SubtractionAssignment, move(lhs), min_precedence, associativity); case TokenType::Asterisk: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::Multiplication, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Multiplication, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::AsteriskEquals: return parse_assignment_expression(AssignmentOp::MultiplicationAssignment, move(lhs), min_precedence, associativity); case TokenType::Slash: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::Division, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Division, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::SlashEquals: return parse_assignment_expression(AssignmentOp::DivisionAssignment, move(lhs), min_precedence, associativity); case TokenType::Percent: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::PercentEquals: return parse_assignment_expression(AssignmentOp::ModuloAssignment, move(lhs), min_precedence, associativity); case TokenType::DoubleAsterisk: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::DoubleAsteriskEquals: return parse_assignment_expression(AssignmentOp::ExponentiationAssignment, move(lhs), min_precedence, associativity); case TokenType::GreaterThan: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::GreaterThanEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::LessThan: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::LessThanEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::EqualsEqualsEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::TypedEquals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::TypedEquals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::ExclamationMarkEqualsEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::EqualsEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::ExclamationMarkEquals: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::In: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::In, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::In, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::Instanceof: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::InstanceOf, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::InstanceOf, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::Ampersand: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::BitwiseAnd, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::BitwiseAnd, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::AmpersandEquals: return parse_assignment_expression(AssignmentOp::BitwiseAndAssignment, move(lhs), min_precedence, associativity); case TokenType::Pipe: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::BitwiseOr, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::BitwiseOr, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::PipeEquals: return parse_assignment_expression(AssignmentOp::BitwiseOrAssignment, move(lhs), min_precedence, associativity); case TokenType::Caret: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::BitwiseXor, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::BitwiseXor, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::CaretEquals: return parse_assignment_expression(AssignmentOp::BitwiseXorAssignment, move(lhs), min_precedence, associativity); case TokenType::ShiftLeft: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::LeftShift, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::LeftShift, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::ShiftLeftEquals: return parse_assignment_expression(AssignmentOp::LeftShiftAssignment, move(lhs), min_precedence, associativity); case TokenType::ShiftRight: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::RightShift, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::RightShift, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::ShiftRightEquals: return parse_assignment_expression(AssignmentOp::RightShiftAssignment, move(lhs), min_precedence, associativity); case TokenType::UnsignedShiftRight: consume(); - return create_ast_node({ rule_start.position(), position() }, BinaryOp::UnsignedRightShift, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, BinaryOp::UnsignedRightShift, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::UnsignedShiftRightEquals: return parse_assignment_expression(AssignmentOp::UnsignedRightShiftAssignment, move(lhs), min_precedence, associativity); case TokenType::ParenOpen: @@ -1110,10 +1110,10 @@ NonnullRefPtr Parser::parse_secondary_expression(NonnullRefPtr({ rule_start.position(), position() }, move(lhs), create_ast_node({ rule_start.position(), position() }, consume().value())); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(lhs), create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value())); case TokenType::BracketOpen: { consume(TokenType::BracketOpen); - auto expression = create_ast_node({ rule_start.position(), position() }, move(lhs), parse_expression(0), true); + auto expression = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(lhs), parse_expression(0), true); consume(TokenType::BracketClose); return expression; } @@ -1123,27 +1123,27 @@ NonnullRefPtr Parser::parse_secondary_expression(NonnullRefPtr(*lhs) && !is(*lhs)) syntax_error(String::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); consume(); - return create_ast_node({ rule_start.position(), position() }, UpdateOp::Increment, move(lhs)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UpdateOp::Increment, move(lhs)); case TokenType::MinusMinus: // FIXME: Apparently for functions this should also not be enforced on a parser level, // other engines throw ReferenceError for foo()-- if (!is(*lhs) && !is(*lhs)) syntax_error(String::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); consume(); - return create_ast_node({ rule_start.position(), position() }, UpdateOp::Decrement, move(lhs)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, UpdateOp::Decrement, move(lhs)); case TokenType::DoubleAmpersand: consume(); - return create_ast_node({ rule_start.position(), position() }, LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::DoubleAmpersandEquals: return parse_assignment_expression(AssignmentOp::AndAssignment, move(lhs), min_precedence, associativity); case TokenType::DoublePipe: consume(); - return create_ast_node({ rule_start.position(), position() }, LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::DoublePipeEquals: return parse_assignment_expression(AssignmentOp::OrAssignment, move(lhs), min_precedence, associativity); case TokenType::DoubleQuestionMark: consume(); - return create_ast_node({ rule_start.position(), position() }, LogicalOp::NullishCoalescing, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, LogicalOp::NullishCoalescing, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::DoubleQuestionMarkEquals: return parse_assignment_expression(AssignmentOp::NullishAssignment, move(lhs), min_precedence, associativity); case TokenType::QuestionMark: @@ -1151,7 +1151,7 @@ NonnullRefPtr Parser::parse_secondary_expression(NonnullRefPtr({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } } @@ -1184,7 +1184,7 @@ NonnullRefPtr Parser::parse_assignment_expression(Assignme } else if (m_parser_state.m_strict_mode && is(*lhs)) { syntax_error("Cannot assign to function call"); } - return create_ast_node({ rule_start.position(), position() }, assignment_op, move(lhs), parse_expression(min_precedence, associativity)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, assignment_op, move(lhs), parse_expression(min_precedence, associativity)); } NonnullRefPtr Parser::parse_call_expression(NonnullRefPtr lhs) @@ -1211,7 +1211,7 @@ NonnullRefPtr Parser::parse_call_expression(NonnullRefPtr({ rule_start.position(), position() }, move(lhs), move(arguments)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(lhs), move(arguments)); } NonnullRefPtr Parser::parse_new_expression() @@ -1239,7 +1239,7 @@ NonnullRefPtr Parser::parse_new_expression() consume(TokenType::ParenClose); } - return create_ast_node({ rule_start.position(), position() }, move(callee), move(arguments)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(callee), move(arguments)); } NonnullRefPtr Parser::parse_return_statement() @@ -1252,16 +1252,16 @@ NonnullRefPtr Parser::parse_return_statement() // Automatic semicolon insertion: terminate statement when return is followed by newline if (m_parser_state.m_current_token.trivia_contains_line_terminator()) - return create_ast_node({ rule_start.position(), position() }, nullptr); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, nullptr); if (match_expression()) { auto expression = parse_expression(0); consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }, move(expression)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expression)); } consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }, nullptr); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, nullptr); } NonnullRefPtr Parser::parse_block_statement() @@ -1275,7 +1275,7 @@ NonnullRefPtr Parser::parse_block_statement(bool& is_strict) { auto rule_start = push_start(); ScopePusher scope(*this, ScopePusher::Let); - auto block = create_ast_node({ rule_start.position(), position() }); + auto block = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); consume(TokenType::CurlyOpen); bool first = true; @@ -1346,7 +1346,7 @@ NonnullRefPtr Parser::parse_function_node(u8 parse_options) auto body = parse_block_statement(is_strict); body->add_variables(m_parser_state.m_var_scopes.last()); body->add_functions(m_parser_state.m_function_scopes.last()); - return create_ast_node({ rule_start.position(), position() }, name, move(body), move(parameters), function_length, NonnullRefPtrVector(), is_strict); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, name, move(body), move(parameters), function_length, NonnullRefPtrVector(), is_strict); } Vector Parser::parse_function_parameters(int& function_length, u8 parse_options) @@ -1441,7 +1441,7 @@ NonnullRefPtr Parser::parse_variable_declaration(bool for_l } else if (!for_loop_variable_declaration && declaration_kind == DeclarationKind::Const) { syntax_error("Missing initializer in 'const' variable declaration"); } - declarations.append(create_ast_node({ rule_start.position(), position() }, create_ast_node({ rule_start.position(), position() }, move(id)), move(init))); + declarations.append(create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(id)), move(init))); if (match(TokenType::Comma)) { consume(); continue; @@ -1451,7 +1451,7 @@ NonnullRefPtr Parser::parse_variable_declaration(bool for_l if (!for_loop_variable_declaration) consume_or_insert_semicolon(); - auto declaration = create_ast_node({ rule_start.position(), position() }, declaration_kind, move(declarations)); + auto declaration = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, declaration_kind, move(declarations)); if (declaration_kind == DeclarationKind::Var) m_parser_state.m_var_scopes.last().append(declaration); else @@ -1467,12 +1467,12 @@ NonnullRefPtr Parser::parse_throw_statement() // Automatic semicolon insertion: terminate statement when throw is followed by newline if (m_parser_state.m_current_token.trivia_contains_line_terminator()) { syntax_error("No line break is allowed between 'throw' and its expression"); - return create_ast_node({ rule_start.position(), position() }, create_ast_node({ rule_start.position(), position() })); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() })); } auto expression = parse_expression(0); consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }, move(expression)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(expression)); } NonnullRefPtr Parser::parse_break_statement() @@ -1494,7 +1494,7 @@ NonnullRefPtr Parser::parse_break_statement() if (target_label.is_null() && !m_parser_state.m_in_break_context) syntax_error("Unlabeled 'break' not allowed outside of a loop or switch statement"); - return create_ast_node({ rule_start.position(), position() }, target_label); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, target_label); } NonnullRefPtr Parser::parse_continue_statement() @@ -1507,7 +1507,7 @@ NonnullRefPtr Parser::parse_continue_statement() FlyString target_label; if (match(TokenType::Semicolon)) { consume(); - return create_ast_node({ rule_start.position(), position() }, target_label); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, target_label); } if (match(TokenType::Identifier) && !m_parser_state.m_current_token.trivia_contains_line_terminator()) { target_label = consume().value(); @@ -1515,7 +1515,7 @@ NonnullRefPtr Parser::parse_continue_statement() syntax_error(String::formatted("Label '{}' not found", target_label)); } consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }, target_label); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, target_label); } NonnullRefPtr Parser::parse_conditional_expression(NonnullRefPtr test) @@ -1525,7 +1525,7 @@ NonnullRefPtr Parser::parse_conditional_expression(Nonnul auto consequent = parse_expression(2); consume(TokenType::Colon); auto alternate = parse_expression(2); - return create_ast_node({ rule_start.position(), position() }, move(test), move(consequent), move(alternate)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(test), move(consequent), move(alternate)); } NonnullRefPtr Parser::parse_try_statement() @@ -1548,7 +1548,7 @@ NonnullRefPtr Parser::parse_try_statement() if (!handler && !finalizer) syntax_error("try statement must have a 'catch' or 'finally' clause"); - return create_ast_node({ rule_start.position(), position() }, move(block), move(handler), move(finalizer)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(block), move(handler), move(finalizer)); } NonnullRefPtr Parser::parse_do_while_statement() @@ -1573,7 +1573,7 @@ NonnullRefPtr Parser::parse_do_while_statement() if (match(TokenType::Semicolon)) consume(); - return create_ast_node({ rule_start.position(), position() }, move(test), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(test), move(body)); } NonnullRefPtr Parser::parse_while_statement() @@ -1590,7 +1590,7 @@ NonnullRefPtr Parser::parse_while_statement() TemporaryChange continue_change(m_parser_state.m_in_continue_context, true); auto body = parse_statement(); - return create_ast_node({ rule_start.position(), position() }, move(test), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(test), move(body)); } NonnullRefPtr Parser::parse_switch_statement() @@ -1618,7 +1618,7 @@ NonnullRefPtr Parser::parse_switch_statement() consume(TokenType::CurlyClose); - return create_ast_node({ rule_start.position(), position() }, move(determinant), move(cases)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(determinant), move(cases)); } NonnullRefPtr Parser::parse_with_statement() @@ -1632,7 +1632,7 @@ NonnullRefPtr Parser::parse_with_statement() consume(TokenType::ParenClose); auto body = parse_statement(); - return create_ast_node({ rule_start.position(), position() }, move(object), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(object), move(body)); } NonnullRefPtr Parser::parse_switch_case() @@ -1657,7 +1657,7 @@ NonnullRefPtr Parser::parse_switch_case() break; } - return create_ast_node({ rule_start.position(), position() }, move(test), move(consequent)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(test), move(consequent)); } NonnullRefPtr Parser::parse_catch_clause() @@ -1673,7 +1673,7 @@ NonnullRefPtr Parser::parse_catch_clause() } auto body = parse_block_statement(); - return create_ast_node({ rule_start.position(), position() }, parameter, move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, parameter, move(body)); } NonnullRefPtr Parser::parse_if_statement() @@ -1685,7 +1685,7 @@ NonnullRefPtr Parser::parse_if_statement() // FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem // of a BlockStatement occupying that position in the source code. ScopePusher scope(*this, ScopePusher::Let); - auto block = create_ast_node({ rule_start.position(), position() }); + auto block = create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); block->append(parse_declaration()); block->add_functions(m_parser_state.m_function_scopes.last()); return block; @@ -1710,7 +1710,7 @@ NonnullRefPtr Parser::parse_if_statement() else alternate = parse_statement(); } - return create_ast_node({ rule_start.position(), position() }, move(predicate), move(*consequent), move(alternate)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(predicate), move(*consequent), move(alternate)); } NonnullRefPtr Parser::parse_for_statement() @@ -1771,7 +1771,7 @@ NonnullRefPtr Parser::parse_for_statement() m_parser_state.m_let_scopes.take_last(); } - return create_ast_node({ rule_start.position(), position() }, move(init), move(test), move(update), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(init), move(test), move(update), move(body)); } NonnullRefPtr Parser::parse_for_in_of_statement(NonnullRefPtr lhs) @@ -1792,8 +1792,8 @@ NonnullRefPtr Parser::parse_for_in_of_statement(NonnullRefPtr({ rule_start.position(), position() }, move(lhs), move(rhs), move(body)); - return create_ast_node({ rule_start.position(), position() }, move(lhs), move(rhs), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(lhs), move(rhs), move(body)); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, move(lhs), move(rhs), move(body)); } NonnullRefPtr Parser::parse_debugger_statement() @@ -1801,7 +1801,7 @@ NonnullRefPtr Parser::parse_debugger_statement() auto rule_start = push_start(); consume(TokenType::Debugger); consume_or_insert_semicolon(); - return create_ast_node({ rule_start.position(), position() }); + return create_ast_node({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }); } bool Parser::match(TokenType type) const diff --git a/Userland/Libraries/LibJS/Parser.h b/Userland/Libraries/LibJS/Parser.h index 6743e1cb75..cf066f65ee 100644 --- a/Userland/Libraries/LibJS/Parser.h +++ b/Userland/Libraries/LibJS/Parser.h @@ -222,6 +222,7 @@ private: Vector m_rule_starts; ParserState m_parser_state; + FlyString m_filename; Vector m_saved_state; }; } diff --git a/Userland/Libraries/LibJS/SourceRange.h b/Userland/Libraries/LibJS/SourceRange.h index f0359ab84c..a281dd90dd 100644 --- a/Userland/Libraries/LibJS/SourceRange.h +++ b/Userland/Libraries/LibJS/SourceRange.h @@ -36,6 +36,7 @@ struct Position { }; struct SourceRange { + StringView filename; Position start; Position end; }; diff --git a/Userland/Libraries/LibJS/Token.h b/Userland/Libraries/LibJS/Token.h index a266cd32ce..0a698bb163 100644 --- a/Userland/Libraries/LibJS/Token.h +++ b/Userland/Libraries/LibJS/Token.h @@ -181,11 +181,12 @@ enum class TokenCategory { class Token { public: - Token(TokenType type, String message, StringView trivia, StringView value, size_t line_number, size_t line_column) + Token(TokenType type, String message, StringView trivia, StringView value, StringView filename, size_t line_number, size_t line_column) : m_type(type) , m_message(message) , m_trivia(trivia) , m_value(value) + , m_filename(filename) , m_line_number(line_number) , m_line_column(line_column) { @@ -200,6 +201,7 @@ public: const String& message() const { return m_message; } const StringView& trivia() const { return m_trivia; } const StringView& value() const { return m_value; } + const StringView& filename() const { return m_filename; } size_t line_number() const { return m_line_number; } size_t line_column() const { return m_line_column; } double double_value() const; @@ -222,6 +224,7 @@ private: String m_message; StringView m_trivia; StringView m_value; + StringView m_filename; size_t m_line_number; size_t m_line_column; };