Serenity Operating System
at master 4837 lines 214 kB view raw
1/* 2 * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org> 3 * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> 4 * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org> 5 * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> 6 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> 7 * Copyright (c) 2023, Andreas Kling <kling@serenityos.org> 8 * 9 * SPDX-License-Identifier: BSD-2-Clause 10 */ 11 12#include "Parser.h" 13#include <AK/Array.h> 14#include <AK/CharacterTypes.h> 15#include <AK/HashTable.h> 16#include <AK/ScopeGuard.h> 17#include <AK/StdLibExtras.h> 18#include <AK/TemporaryChange.h> 19#include <LibJS/Runtime/RegExpObject.h> 20#include <LibRegex/Regex.h> 21 22namespace JS { 23 24class ScopePusher { 25 26 // NOTE: We really only need ModuleTopLevel and NotModuleTopLevel as the only 27 // difference seems to be in https://tc39.es/ecma262/#sec-static-semantics-varscopeddeclarations 28 // where ModuleItemList only does the VarScopedDeclaration and not the 29 // TopLevelVarScopedDeclarations. 30 enum class ScopeLevel { 31 NotTopLevel, 32 ScriptTopLevel, 33 ModuleTopLevel, 34 FunctionTopLevel, 35 StaticInitTopLevel 36 }; 37 38private: 39 ScopePusher(Parser& parser, ScopeNode* node, ScopeLevel scope_level) 40 : m_parser(parser) 41 , m_scope_level(scope_level) 42 { 43 m_parent_scope = exchange(m_parser.m_state.current_scope_pusher, this); 44 VERIFY(node || (m_parent_scope && scope_level == ScopeLevel::NotTopLevel)); 45 if (!node) 46 m_node = m_parent_scope->m_node; 47 else 48 m_node = node; 49 VERIFY(m_node); 50 51 if (!is_top_level()) 52 m_top_level_scope = m_parent_scope->m_top_level_scope; 53 else 54 m_top_level_scope = this; 55 } 56 57 bool is_top_level() 58 { 59 return m_scope_level != ScopeLevel::NotTopLevel; 60 } 61 62public: 63 static ScopePusher function_scope(Parser& parser, FunctionBody& function_body, Vector<FunctionParameter> const& parameters) 64 { 65 ScopePusher scope_pusher(parser, &function_body, ScopeLevel::FunctionTopLevel); 66 scope_pusher.m_function_parameters = parameters; 67 for (auto& parameter : parameters) { 68 parameter.binding.visit( 69 [&](DeprecatedFlyString const& name) { 70 scope_pusher.m_forbidden_lexical_names.set(name); 71 }, 72 [&](NonnullRefPtr<BindingPattern const> const& binding_pattern) { 73 // NOTE: Nothing in the callback throws an exception. 74 MUST(binding_pattern->for_each_bound_name([&](auto const& name) { 75 scope_pusher.m_forbidden_lexical_names.set(name); 76 })); 77 }); 78 } 79 return scope_pusher; 80 } 81 82 static ScopePusher program_scope(Parser& parser, Program& program) 83 { 84 return ScopePusher(parser, &program, program.type() == Program::Type::Script ? ScopeLevel::ScriptTopLevel : ScopeLevel::ModuleTopLevel); 85 } 86 87 static ScopePusher block_scope(Parser& parser, ScopeNode& node) 88 { 89 return ScopePusher(parser, &node, ScopeLevel::NotTopLevel); 90 } 91 92 static ScopePusher for_loop_scope(Parser& parser, RefPtr<ASTNode const> const& init) 93 { 94 ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel); 95 if (init && is<VariableDeclaration>(*init)) { 96 auto& variable_declaration = static_cast<VariableDeclaration const&>(*init); 97 if (variable_declaration.declaration_kind() != DeclarationKind::Var) { 98 // NOTE: Nothing in the callback throws an exception. 99 MUST(variable_declaration.for_each_bound_name([&](auto const& name) { 100 scope_pusher.m_forbidden_var_names.set(name); 101 })); 102 } 103 } 104 105 return scope_pusher; 106 } 107 108 static ScopePusher catch_scope(Parser& parser, RefPtr<BindingPattern const> const& pattern, DeprecatedFlyString const& parameter) 109 { 110 ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel); 111 if (pattern) { 112 // NOTE: Nothing in the callback throws an exception. 113 MUST(pattern->for_each_bound_name([&](auto const& name) { 114 scope_pusher.m_forbidden_var_names.set(name); 115 })); 116 } else if (!parameter.is_empty()) { 117 scope_pusher.m_var_names.set(parameter); 118 } 119 return scope_pusher; 120 } 121 122 static ScopePusher static_init_block_scope(Parser& parser, ScopeNode& node) 123 { 124 return ScopePusher(parser, &node, ScopeLevel::StaticInitTopLevel); 125 } 126 127 static ScopePusher class_field_scope(Parser& parser) 128 { 129 return ScopePusher(parser, nullptr, ScopeLevel::NotTopLevel); 130 } 131 132 void add_declaration(NonnullRefPtr<Declaration const> declaration) 133 { 134 if (declaration->is_lexical_declaration()) { 135 // NOTE: Nothing in the callback throws an exception. 136 MUST(declaration->for_each_bound_name([&](auto const& name) { 137 if (m_var_names.contains(name) || m_forbidden_lexical_names.contains(name) || m_function_names.contains(name)) 138 throw_identifier_declared(name, declaration); 139 140 if (m_lexical_names.set(name) != AK::HashSetResult::InsertedNewEntry) 141 throw_identifier_declared(name, declaration); 142 })); 143 144 m_node->add_lexical_declaration(move(declaration)); 145 } else if (!declaration->is_function_declaration()) { 146 // NOTE: Nothing in the callback throws an exception. 147 MUST(declaration->for_each_bound_name([&](auto const& name) { 148 ScopePusher* pusher = this; 149 while (true) { 150 if (pusher->m_lexical_names.contains(name) 151 || pusher->m_function_names.contains(name) 152 || pusher->m_forbidden_var_names.contains(name)) 153 throw_identifier_declared(name, declaration); 154 155 pusher->m_var_names.set(name); 156 if (pusher->is_top_level()) 157 break; 158 159 VERIFY(pusher->m_parent_scope != nullptr); 160 pusher = pusher->m_parent_scope; 161 } 162 VERIFY(pusher->is_top_level() && pusher->m_node); 163 pusher->m_node->add_var_scoped_declaration(declaration); 164 })); 165 166 VERIFY(m_top_level_scope); 167 m_top_level_scope->m_node->add_var_scoped_declaration(move(declaration)); 168 } else { 169 if (m_scope_level != ScopeLevel::NotTopLevel && m_scope_level != ScopeLevel::ModuleTopLevel) { 170 // Only non-top levels and Module don't var declare the top functions 171 // NOTE: Nothing in the callback throws an exception. 172 MUST(declaration->for_each_bound_name([&](auto const& name) { 173 m_var_names.set(name); 174 })); 175 m_node->add_var_scoped_declaration(move(declaration)); 176 } else { 177 VERIFY(is<FunctionDeclaration>(*declaration)); 178 auto& function_declaration = static_cast<FunctionDeclaration const&>(*declaration); 179 auto& function_name = function_declaration.name(); 180 if (m_var_names.contains(function_name) || m_lexical_names.contains(function_name)) 181 throw_identifier_declared(function_name, declaration); 182 183 if (function_declaration.kind() != FunctionKind::Normal || m_parser.m_state.strict_mode) { 184 if (m_function_names.contains(function_name)) 185 throw_identifier_declared(function_name, declaration); 186 187 m_lexical_names.set(function_name); 188 m_node->add_lexical_declaration(move(declaration)); 189 return; 190 } 191 192 m_function_names.set(function_name); 193 if (!m_lexical_names.contains(function_name)) 194 m_functions_to_hoist.append(static_ptr_cast<FunctionDeclaration const>(declaration)); 195 196 m_node->add_lexical_declaration(move(declaration)); 197 } 198 } 199 } 200 201 ScopePusher const* last_function_scope() const 202 { 203 for (auto scope_ptr = this; scope_ptr; scope_ptr = scope_ptr->m_parent_scope) { 204 if (scope_ptr->m_function_parameters.has_value()) 205 return scope_ptr; 206 } 207 return nullptr; 208 } 209 210 Vector<FunctionParameter> const& function_parameters() const 211 { 212 return *m_function_parameters; 213 } 214 215 ScopePusher* parent_scope() { return m_parent_scope; } 216 ScopePusher const* parent_scope() const { return m_parent_scope; } 217 218 [[nodiscard]] bool has_declaration(DeprecatedFlyString const& name) const 219 { 220 return m_lexical_names.contains(name) || m_var_names.contains(name) || !m_functions_to_hoist.find_if([&name](auto& function) { return function->name() == name; }).is_end(); 221 } 222 223 bool contains_direct_call_to_eval() const { return m_contains_direct_call_to_eval; } 224 bool contains_access_to_arguments_object() const { return m_contains_access_to_arguments_object; } 225 void set_contains_direct_call_to_eval() { m_contains_direct_call_to_eval = true; } 226 void set_contains_access_to_arguments_object() { m_contains_access_to_arguments_object = true; } 227 228 ~ScopePusher() 229 { 230 VERIFY(is_top_level() || m_parent_scope); 231 232 for (size_t i = 0; i < m_functions_to_hoist.size(); i++) { 233 auto const& function_declaration = m_functions_to_hoist[i]; 234 if (m_lexical_names.contains(function_declaration->name()) || m_forbidden_var_names.contains(function_declaration->name())) 235 continue; 236 if (is_top_level()) { 237 m_node->add_hoisted_function(move(m_functions_to_hoist[i])); 238 } else { 239 if (!m_parent_scope->m_lexical_names.contains(function_declaration->name()) && !m_parent_scope->m_function_names.contains(function_declaration->name())) 240 m_parent_scope->m_functions_to_hoist.append(move(m_functions_to_hoist[i])); 241 } 242 } 243 244 if (m_parent_scope && !m_function_parameters.has_value()) { 245 m_parent_scope->m_contains_access_to_arguments_object |= m_contains_access_to_arguments_object; 246 m_parent_scope->m_contains_direct_call_to_eval |= m_contains_direct_call_to_eval; 247 } 248 249 VERIFY(m_parser.m_state.current_scope_pusher == this); 250 m_parser.m_state.current_scope_pusher = m_parent_scope; 251 } 252 253 void set_contains_await_expression() 254 { 255 m_contains_await_expression = true; 256 } 257 258 bool contains_await_expression() const 259 { 260 return m_contains_await_expression; 261 } 262 263 bool can_have_using_declaration() const 264 { 265 return m_scope_level != ScopeLevel::ScriptTopLevel; 266 } 267 268private: 269 void throw_identifier_declared(DeprecatedFlyString const& name, NonnullRefPtr<Declaration const> const& declaration) 270 { 271 m_parser.syntax_error(DeprecatedString::formatted("Identifier '{}' already declared", name), declaration->source_range().start); 272 } 273 274 Parser& m_parser; 275 ScopeNode* m_node { nullptr }; 276 ScopeLevel m_scope_level { ScopeLevel::NotTopLevel }; 277 278 ScopePusher* m_parent_scope { nullptr }; 279 ScopePusher* m_top_level_scope { nullptr }; 280 281 HashTable<DeprecatedFlyString> m_lexical_names; 282 HashTable<DeprecatedFlyString> m_var_names; 283 HashTable<DeprecatedFlyString> m_function_names; 284 285 HashTable<DeprecatedFlyString> m_forbidden_lexical_names; 286 HashTable<DeprecatedFlyString> m_forbidden_var_names; 287 Vector<NonnullRefPtr<FunctionDeclaration const>> m_functions_to_hoist; 288 289 Optional<Vector<FunctionParameter>> m_function_parameters; 290 291 bool m_contains_access_to_arguments_object { false }; 292 bool m_contains_direct_call_to_eval { false }; 293 bool m_contains_await_expression { false }; 294}; 295 296class OperatorPrecedenceTable { 297public: 298 constexpr OperatorPrecedenceTable() 299 : m_token_precedence() 300 { 301 for (size_t i = 0; i < array_size(m_operator_precedence); ++i) { 302 auto& op = m_operator_precedence[i]; 303 m_token_precedence[static_cast<size_t>(op.token)] = op.precedence; 304 } 305 } 306 307 constexpr int get(TokenType token) const 308 { 309 int p = m_token_precedence[static_cast<size_t>(token)]; 310 if (p == 0) { 311 warnln("Internal Error: No precedence for operator {}", Token::name(token)); 312 VERIFY_NOT_REACHED(); 313 return -1; 314 } 315 316 return p; 317 } 318 319private: 320 int m_token_precedence[cs_num_of_js_tokens]; 321 322 struct OperatorPrecedence { 323 TokenType token; 324 int precedence; 325 }; 326 327 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence 328 static constexpr const OperatorPrecedence m_operator_precedence[] = { 329 { TokenType::Period, 20 }, 330 { TokenType::BracketOpen, 20 }, 331 { TokenType::ParenOpen, 20 }, 332 { TokenType::QuestionMarkPeriod, 20 }, 333 334 { TokenType::New, 19 }, 335 336 { TokenType::PlusPlus, 18 }, 337 { TokenType::MinusMinus, 18 }, 338 339 { TokenType::ExclamationMark, 17 }, 340 { TokenType::Tilde, 17 }, 341 { TokenType::Typeof, 17 }, 342 { TokenType::Void, 17 }, 343 { TokenType::Delete, 17 }, 344 { TokenType::Await, 17 }, 345 346 { TokenType::DoubleAsterisk, 16 }, 347 348 { TokenType::Asterisk, 15 }, 349 { TokenType::Slash, 15 }, 350 { TokenType::Percent, 15 }, 351 352 { TokenType::Plus, 14 }, 353 { TokenType::Minus, 14 }, 354 355 { TokenType::ShiftLeft, 13 }, 356 { TokenType::ShiftRight, 13 }, 357 { TokenType::UnsignedShiftRight, 13 }, 358 359 { TokenType::LessThan, 12 }, 360 { TokenType::LessThanEquals, 12 }, 361 { TokenType::GreaterThan, 12 }, 362 { TokenType::GreaterThanEquals, 12 }, 363 { TokenType::In, 12 }, 364 { TokenType::Instanceof, 12 }, 365 366 { TokenType::EqualsEquals, 11 }, 367 { TokenType::ExclamationMarkEquals, 11 }, 368 { TokenType::EqualsEqualsEquals, 11 }, 369 { TokenType::ExclamationMarkEqualsEquals, 11 }, 370 371 { TokenType::Ampersand, 10 }, 372 373 { TokenType::Caret, 9 }, 374 375 { TokenType::Pipe, 8 }, 376 377 { TokenType::DoubleQuestionMark, 7 }, 378 379 { TokenType::DoubleAmpersand, 6 }, 380 381 { TokenType::DoublePipe, 5 }, 382 383 { TokenType::QuestionMark, 4 }, 384 385 { TokenType::Equals, 3 }, 386 { TokenType::PlusEquals, 3 }, 387 { TokenType::MinusEquals, 3 }, 388 { TokenType::DoubleAsteriskEquals, 3 }, 389 { TokenType::AsteriskEquals, 3 }, 390 { TokenType::SlashEquals, 3 }, 391 { TokenType::PercentEquals, 3 }, 392 { TokenType::ShiftLeftEquals, 3 }, 393 { TokenType::ShiftRightEquals, 3 }, 394 { TokenType::UnsignedShiftRightEquals, 3 }, 395 { TokenType::AmpersandEquals, 3 }, 396 { TokenType::CaretEquals, 3 }, 397 { TokenType::PipeEquals, 3 }, 398 { TokenType::DoubleAmpersandEquals, 3 }, 399 { TokenType::DoublePipeEquals, 3 }, 400 { TokenType::DoubleQuestionMarkEquals, 3 }, 401 402 { TokenType::Yield, 2 }, 403 404 { TokenType::Comma, 1 }, 405 }; 406}; 407 408constexpr OperatorPrecedenceTable g_operator_precedence; 409 410Parser::ParserState::ParserState(Lexer l, Program::Type program_type) 411 : lexer(move(l)) 412{ 413 if (program_type == Program::Type::Module) 414 lexer.disallow_html_comments(); 415 current_token = lexer.next(); 416} 417 418Parser::Parser(Lexer lexer, Program::Type program_type, Optional<EvalInitialState> initial_state_for_eval) 419 : m_source_code(SourceCode::create(lexer.filename(), String::from_deprecated_string(lexer.source()).release_value_but_fixme_should_propagate_errors())) 420 , m_state(move(lexer), program_type) 421 , m_program_type(program_type) 422{ 423 if (initial_state_for_eval.has_value()) { 424 m_state.in_eval_function_context = initial_state_for_eval->in_eval_function_context; 425 m_state.allow_super_property_lookup = initial_state_for_eval->allow_super_property_lookup; 426 m_state.allow_super_constructor_call = initial_state_for_eval->allow_super_constructor_call; 427 m_state.in_class_field_initializer = initial_state_for_eval->in_class_field_initializer; 428 } 429} 430 431Associativity Parser::operator_associativity(TokenType type) const 432{ 433 switch (type) { 434 case TokenType::Period: 435 case TokenType::BracketOpen: 436 case TokenType::ParenOpen: 437 case TokenType::QuestionMarkPeriod: 438 case TokenType::Asterisk: 439 case TokenType::Slash: 440 case TokenType::Percent: 441 case TokenType::Plus: 442 case TokenType::Minus: 443 case TokenType::ShiftLeft: 444 case TokenType::ShiftRight: 445 case TokenType::UnsignedShiftRight: 446 case TokenType::LessThan: 447 case TokenType::LessThanEquals: 448 case TokenType::GreaterThan: 449 case TokenType::GreaterThanEquals: 450 case TokenType::In: 451 case TokenType::Instanceof: 452 case TokenType::EqualsEquals: 453 case TokenType::ExclamationMarkEquals: 454 case TokenType::EqualsEqualsEquals: 455 case TokenType::ExclamationMarkEqualsEquals: 456 case TokenType::Typeof: 457 case TokenType::Void: 458 case TokenType::Delete: 459 case TokenType::Await: 460 case TokenType::Ampersand: 461 case TokenType::Caret: 462 case TokenType::Pipe: 463 case TokenType::DoubleQuestionMark: 464 case TokenType::DoubleAmpersand: 465 case TokenType::DoublePipe: 466 case TokenType::Comma: 467 return Associativity::Left; 468 default: 469 return Associativity::Right; 470 } 471} 472 473bool Parser::parse_directive(ScopeNode& body) 474{ 475 bool found_use_strict = false; 476 while (!done() && match(TokenType::StringLiteral)) { 477 auto raw_value = m_state.current_token.original_value(); 478 // It cannot be a labelled function since we hit a string literal. 479 auto statement = parse_statement(AllowLabelledFunction::No); 480 body.append(statement); 481 482 VERIFY(is<ExpressionStatement>(*statement)); 483 auto& expression = static_cast<ExpressionStatement const&>(*statement).expression(); 484 485 if (!is<StringLiteral>(expression)) 486 break; 487 488 if (raw_value.is_one_of("'use strict'"sv, "\"use strict\"")) { 489 found_use_strict = true; 490 491 if (m_state.string_legacy_octal_escape_sequence_in_scope) 492 syntax_error("Octal escape sequence in string literal not allowed in strict mode"); 493 break; 494 } 495 } 496 497 m_state.string_legacy_octal_escape_sequence_in_scope = false; 498 return found_use_strict; 499} 500 501NonnullRefPtr<Program> Parser::parse_program(bool starts_in_strict_mode) 502{ 503 auto rule_start = push_start(); 504 auto program = adopt_ref(*new Program({ m_source_code, rule_start.position(), position() }, m_program_type)); 505 ScopePusher program_scope = ScopePusher::program_scope(*this, *program); 506 507 if (m_program_type == Program::Type::Script) 508 parse_script(program, starts_in_strict_mode); 509 else 510 parse_module(program); 511 512 program->set_end_offset({}, position().offset); 513 return program; 514} 515 516void Parser::parse_script(Program& program, bool starts_in_strict_mode) 517{ 518 bool strict_before = m_state.strict_mode; 519 if (starts_in_strict_mode) 520 m_state.strict_mode = true; 521 522 bool has_use_strict = parse_directive(program); 523 524 if (m_state.strict_mode || has_use_strict) { 525 program.set_strict_mode(); 526 m_state.strict_mode = true; 527 } 528 529 parse_statement_list(program, AllowLabelledFunction::Yes); 530 if (!done()) { 531 expected("statement or declaration"); 532 consume(); 533 } 534 535 m_state.strict_mode = strict_before; 536} 537 538void Parser::parse_module(Program& program) 539{ 540 TemporaryChange strict_mode_rollback(m_state.strict_mode, true); 541 TemporaryChange await_expression_valid_rollback(m_state.await_expression_is_valid, true); 542 543 // Since strict mode is already enabled we skip any directive parsing. 544 while (!done()) { 545 parse_statement_list(program, AllowLabelledFunction::Yes); 546 547 if (done()) 548 break; 549 550 if (match_export_or_import()) { 551 VERIFY(m_state.current_token.type() == TokenType::Export || m_state.current_token.type() == TokenType::Import); 552 if (m_state.current_token.type() == TokenType::Export) 553 program.append_export(parse_export_statement(program)); 554 else 555 program.append_import(parse_import_statement(program)); 556 557 } else { 558 expected("statement or declaration"); 559 consume(); 560 } 561 } 562 563 VERIFY(m_state.current_scope_pusher); 564 if (m_state.current_scope_pusher->contains_await_expression()) 565 program.set_has_top_level_await(); 566 567 for (auto& export_statement : program.exports()) { 568 if (export_statement->has_statement()) 569 continue; 570 for (auto& entry : export_statement->entries()) { 571 if (entry.is_module_request() || entry.kind == ExportEntry::Kind::EmptyNamedExport) 572 return; 573 574 auto const& exported_name = entry.local_or_import_name; 575 bool found = false; 576 // NOTE: Nothing in the callback throws an exception. 577 MUST(program.for_each_lexically_declared_name([&](auto const& name) { 578 if (name == exported_name) 579 found = true; 580 })); 581 if (found) 582 continue; 583 // NOTE: Nothing in the callback throws an exception. 584 MUST(program.for_each_var_declared_name([&](auto const& name) { 585 if (name == exported_name) 586 found = true; 587 })); 588 for (auto& import : program.imports()) { 589 if (import->has_bound_name(exported_name)) { 590 found = true; 591 break; 592 } 593 } 594 595 if (!found) 596 syntax_error(DeprecatedString::formatted("'{}' in export is not declared", exported_name), export_statement->source_range().start); 597 } 598 } 599} 600 601NonnullRefPtr<Declaration const> Parser::parse_declaration() 602{ 603 auto rule_start = push_start(); 604 if (m_state.current_token.type() == TokenType::Async && next_token().type() == TokenType::Function) 605 return parse_function_node<FunctionDeclaration>(); 606 switch (m_state.current_token.type()) { 607 case TokenType::Class: 608 return parse_class_declaration(); 609 case TokenType::Function: 610 return parse_function_node<FunctionDeclaration>(); 611 case TokenType::Let: 612 case TokenType::Const: 613 return parse_variable_declaration(); 614 case TokenType::Identifier: 615 if (m_state.current_token.original_value() == "using"sv) { 616 if (!m_state.current_scope_pusher->can_have_using_declaration()) 617 syntax_error("'using' not allowed outside of block, for loop or function"); 618 619 return parse_using_declaration(); 620 } 621 [[fallthrough]]; 622 default: 623 expected("declaration"); 624 consume(); 625 return create_ast_node<ErrorDeclaration>({ m_source_code, rule_start.position(), position() }); 626 } 627} 628 629NonnullRefPtr<Statement const> Parser::parse_statement(AllowLabelledFunction allow_labelled_function) 630{ 631 auto rule_start = push_start(); 632 auto type = m_state.current_token.type(); 633 switch (type) { 634 case TokenType::CurlyOpen: 635 return parse_block_statement(); 636 case TokenType::Return: 637 return parse_return_statement(); 638 case TokenType::Var: { 639 auto declaration = parse_variable_declaration(); 640 m_state.current_scope_pusher->add_declaration(declaration); 641 return declaration; 642 } 643 case TokenType::For: 644 return parse_for_statement(); 645 case TokenType::If: 646 return parse_if_statement(); 647 case TokenType::Throw: 648 return parse_throw_statement(); 649 case TokenType::Try: 650 return parse_try_statement(); 651 case TokenType::Break: 652 return parse_break_statement(); 653 case TokenType::Continue: 654 return parse_continue_statement(); 655 case TokenType::Switch: 656 return parse_switch_statement(); 657 case TokenType::Do: 658 return parse_do_while_statement(); 659 case TokenType::While: 660 return parse_while_statement(); 661 case TokenType::With: 662 if (m_state.strict_mode) 663 syntax_error("'with' statement not allowed in strict mode"); 664 return parse_with_statement(); 665 case TokenType::Debugger: 666 return parse_debugger_statement(); 667 case TokenType::Semicolon: 668 consume(); 669 return create_ast_node<EmptyStatement>({ m_source_code, rule_start.position(), position() }); 670 case TokenType::Slash: 671 case TokenType::SlashEquals: 672 m_state.current_token = m_state.lexer.force_slash_as_regex(); 673 [[fallthrough]]; 674 default: 675 if (match_invalid_escaped_keyword()) 676 syntax_error("Keyword must not contain escaped characters"); 677 678 if (match_identifier_name()) { 679 auto result = try_parse_labelled_statement(allow_labelled_function); 680 if (!result.is_null()) 681 return result.release_nonnull(); 682 } 683 if (match_expression()) { 684 if (match(TokenType::Async)) { 685 auto lookahead_token = next_token(); 686 if (lookahead_token.type() == TokenType::Function && !lookahead_token.trivia_contains_line_terminator()) 687 syntax_error("Async function declaration not allowed in single-statement context"); 688 } else if (match(TokenType::Function) || match(TokenType::Class)) { 689 syntax_error(DeprecatedString::formatted("{} declaration not allowed in single-statement context", m_state.current_token.name())); 690 } else if (match(TokenType::Let) && next_token().type() == TokenType::BracketOpen) { 691 syntax_error(DeprecatedString::formatted("let followed by [ is not allowed in single-statement context")); 692 } 693 694 auto expr = parse_expression(0); 695 consume_or_insert_semicolon(); 696 return create_ast_node<ExpressionStatement>({ m_source_code, rule_start.position(), position() }, move(expr)); 697 } 698 expected("statement"); 699 consume(); 700 return create_ast_node<ErrorStatement>({ m_source_code, rule_start.position(), position() }); 701 } 702} 703 704bool Parser::match_invalid_escaped_keyword() const 705{ 706 if (m_state.current_token.type() != TokenType::EscapedKeyword) 707 return false; 708 auto token_value = m_state.current_token.value(); 709 if (token_value == "await"sv) 710 return m_program_type == Program::Type::Module || m_state.await_expression_is_valid; 711 if (token_value == "async"sv) 712 return false; 713 if (token_value == "yield"sv) 714 return m_state.in_generator_function_context; 715 if (m_state.strict_mode) 716 return true; 717 return token_value != "let"sv; 718} 719 720static constexpr AK::Array<StringView, 9> strict_reserved_words = { "implements"sv, "interface"sv, "let"sv, "package"sv, "private"sv, "protected"sv, "public"sv, "static"sv, "yield"sv }; 721 722static bool is_strict_reserved_word(StringView str) 723{ 724 return any_of(strict_reserved_words, [&str](StringView word) { 725 return word == str; 726 }); 727} 728 729static bool is_simple_parameter_list(Vector<FunctionParameter> const& parameters) 730{ 731 return all_of(parameters, [](FunctionParameter const& parameter) { 732 return !parameter.is_rest && parameter.default_value.is_null() && parameter.binding.has<DeprecatedFlyString>(); 733 }); 734} 735 736RefPtr<FunctionExpression const> Parser::try_parse_arrow_function_expression(bool expect_parens, bool is_async) 737{ 738 if (is_async) 739 VERIFY(match(TokenType::Async)); 740 741 if (!expect_parens && !is_async) { 742 // NOTE: This is a fast path where we try to fail early in case this can't possibly 743 // be a match. The idea is to avoid the expensive parser state save/load mechanism. 744 // The logic is duplicated below in the "real" !expect_parens branch. 745 if (!match_identifier() && !match(TokenType::Yield) && !match(TokenType::Await)) 746 return nullptr; 747 auto token = next_token(); 748 if (token.trivia_contains_line_terminator()) 749 return nullptr; 750 if (token.type() != TokenType::Arrow) 751 return nullptr; 752 } 753 754 save_state(); 755 auto rule_start = (expect_parens && !is_async) 756 // Someone has consumed the opening parenthesis for us! Start there. 757 ? RulePosition { *this, m_rule_starts.last() } 758 // We've not encountered one yet, so the rule start is actually here. 759 : push_start(); 760 761 ArmedScopeGuard state_rollback_guard = [&] { 762 load_state(); 763 }; 764 765 auto function_kind = FunctionKind::Normal; 766 767 if (is_async) { 768 consume(TokenType::Async); 769 function_kind = FunctionKind::Async; 770 if (m_state.current_token.trivia_contains_line_terminator()) 771 return nullptr; 772 773 // Since we have async it can be followed by paren open in the expect_parens case 774 // so we also consume that token. 775 if (expect_parens) { 776 VERIFY(match(TokenType::ParenOpen)); 777 consume(TokenType::ParenOpen); 778 } 779 } 780 781 Vector<FunctionParameter> parameters; 782 i32 function_length = -1; 783 if (expect_parens) { 784 // We have parens around the function parameters and can re-use the same parsing 785 // logic used for regular functions: multiple parameters, default values, rest 786 // parameter, maybe a trailing comma. If we have a new syntax error afterwards we 787 // check if it's about a wrong token (something like duplicate parameter name must 788 // not abort), know parsing failed and rollback the parser state. 789 auto previous_syntax_errors = m_state.errors.size(); 790 TemporaryChange in_async_context(m_state.await_expression_is_valid, is_async || m_state.await_expression_is_valid); 791 792 parameters = parse_formal_parameters(function_length, FunctionNodeParseOptions::IsArrowFunction | (is_async ? FunctionNodeParseOptions::IsAsyncFunction : 0)); 793 if (m_state.errors.size() > previous_syntax_errors && m_state.errors[previous_syntax_errors].message.starts_with("Unexpected token"sv)) 794 return nullptr; 795 if (!match(TokenType::ParenClose)) 796 return nullptr; 797 consume(); 798 } else { 799 // No parens - this must be an identifier followed by arrow. That's it. 800 if (!match_identifier() && !match(TokenType::Yield) && !match(TokenType::Await)) 801 return nullptr; 802 auto token = consume_identifier_reference(); 803 if (m_state.strict_mode && token.value().is_one_of("arguments"sv, "eval"sv)) 804 syntax_error("BindingIdentifier may not be 'arguments' or 'eval' in strict mode"); 805 if (is_async && token.value() == "await"sv) 806 syntax_error("'await' is a reserved identifier in async functions"); 807 parameters.append({ DeprecatedFlyString { token.value() }, {} }); 808 } 809 // If there's a newline between the closing paren and arrow it's not a valid arrow function, 810 // ASI should kick in instead (it'll then fail with "Unexpected token Arrow") 811 if (m_state.current_token.trivia_contains_line_terminator()) 812 return nullptr; 813 if (!match(TokenType::Arrow)) 814 return nullptr; 815 consume(); 816 817 if (function_length == -1) 818 function_length = parameters.size(); 819 820 auto old_labels_in_scope = move(m_state.labels_in_scope); 821 ScopeGuard guard([&]() { 822 m_state.labels_in_scope = move(old_labels_in_scope); 823 }); 824 825 bool contains_direct_call_to_eval = false; 826 827 auto function_body_result = [&]() -> RefPtr<FunctionBody const> { 828 TemporaryChange change(m_state.in_arrow_function_context, true); 829 TemporaryChange async_context_change(m_state.await_expression_is_valid, is_async); 830 TemporaryChange in_class_static_init_block_change(m_state.in_class_static_init_block, false); 831 832 if (match(TokenType::CurlyOpen)) { 833 // Parse a function body with statements 834 consume(TokenType::CurlyOpen); 835 auto body = parse_function_body(parameters, function_kind, contains_direct_call_to_eval); 836 consume(TokenType::CurlyClose); 837 return body; 838 } 839 if (match_expression()) { 840 // Parse a function body which returns a single expression 841 842 // FIXME: We synthesize a block with a return statement 843 // for arrow function bodies which are a single expression. 844 // Esprima generates a single "ArrowFunctionExpression" 845 // with a "body" property. 846 auto return_block = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() }); 847 ScopePusher function_scope = ScopePusher::function_scope(*this, return_block, parameters); 848 auto return_expression = parse_expression(2); 849 return_block->append<ReturnStatement const>({ m_source_code, rule_start.position(), position() }, move(return_expression)); 850 if (m_state.strict_mode) 851 const_cast<FunctionBody&>(*return_block).set_strict_mode(); 852 contains_direct_call_to_eval = function_scope.contains_direct_call_to_eval(); 853 return return_block; 854 } 855 // Invalid arrow function body 856 return nullptr; 857 }(); 858 859 if (function_body_result.is_null()) 860 return nullptr; 861 862 state_rollback_guard.disarm(); 863 discard_saved_state(); 864 auto body = function_body_result.release_nonnull(); 865 866 if (body->in_strict_mode()) { 867 for (auto& parameter : parameters) { 868 parameter.binding.visit( 869 [&](DeprecatedFlyString const& name) { 870 check_identifier_name_for_assignment_validity(name, true); 871 }, 872 [&](auto const&) {}); 873 } 874 } 875 876 auto function_start_offset = rule_start.position().offset; 877 auto function_end_offset = position().offset - m_state.current_token.trivia().length(); 878 auto source_text = DeprecatedString { m_state.lexer.source().substring_view(function_start_offset, function_end_offset - function_start_offset) }; 879 return create_ast_node<FunctionExpression>( 880 { m_source_code, rule_start.position(), position() }, "", move(source_text), 881 move(body), move(parameters), function_length, function_kind, body->in_strict_mode(), 882 /* might_need_arguments_object */ false, contains_direct_call_to_eval, /* is_arrow_function */ true); 883} 884 885RefPtr<LabelledStatement const> Parser::try_parse_labelled_statement(AllowLabelledFunction allow_function) 886{ 887 { 888 // NOTE: This is a fast path where we try to fail early to avoid the expensive save_state+load_state. 889 if (next_token().type() != TokenType::Colon) 890 return {}; 891 } 892 893 save_state(); 894 auto rule_start = push_start(); 895 ArmedScopeGuard state_rollback_guard = [&] { 896 load_state(); 897 }; 898 899 if (m_state.current_token.value() == "yield"sv && (m_state.strict_mode || m_state.in_generator_function_context)) { 900 return {}; 901 } 902 903 if (m_state.current_token.value() == "await"sv && (m_program_type == Program::Type::Module || m_state.await_expression_is_valid || m_state.in_class_static_init_block)) { 904 return {}; 905 } 906 907 auto identifier = [&] { 908 if (m_state.current_token.value() == "await"sv) { 909 return consume().value(); 910 } 911 return consume_identifier_reference().value(); 912 }(); 913 if (!match(TokenType::Colon)) 914 return {}; 915 consume(TokenType::Colon); 916 917 if (!match_statement()) 918 return {}; 919 920 state_rollback_guard.disarm(); 921 discard_saved_state(); 922 923 if (m_state.strict_mode && identifier == "let"sv) { 924 syntax_error("Strict mode reserved word 'let' is not allowed in label", rule_start.position()); 925 return {}; 926 } 927 928 if (match(TokenType::Function) && (allow_function == AllowLabelledFunction::No || m_state.strict_mode)) { 929 syntax_error("Not allowed to declare a function here"); 930 return {}; 931 } 932 933 if (m_state.labels_in_scope.contains(identifier)) 934 syntax_error(DeprecatedString::formatted("Label '{}' has already been declared", identifier)); 935 936 RefPtr<Statement const> labelled_item; 937 938 auto is_iteration_statement = false; 939 940 if (match(TokenType::Function)) { 941 m_state.labels_in_scope.set(identifier, {}); 942 auto function_declaration = parse_function_node<FunctionDeclaration>(); 943 VERIFY(m_state.current_scope_pusher); 944 m_state.current_scope_pusher->add_declaration(function_declaration); 945 if (function_declaration->kind() == FunctionKind::Generator) 946 syntax_error("Generator functions cannot be defined in labelled statements"); 947 if (function_declaration->kind() == FunctionKind::Async) 948 syntax_error("Async functions cannot be defined in labelled statements"); 949 950 labelled_item = move(function_declaration); 951 } else { 952 m_state.labels_in_scope.set(identifier, {}); 953 labelled_item = parse_statement(allow_function); 954 // Extract the innermost statement from a potentially nested chain of LabelledStatements. 955 auto statement = labelled_item; 956 while (is<LabelledStatement>(*statement)) 957 statement = static_cast<LabelledStatement const&>(*statement).labelled_item(); 958 if (is<IterationStatement>(*statement)) 959 is_iteration_statement = true; 960 } 961 962 if (!is_iteration_statement) { 963 if (auto entry = m_state.labels_in_scope.find(identifier); entry != m_state.labels_in_scope.end() && entry->value.has_value()) 964 syntax_error("labelled continue statement cannot use non iterating statement", m_state.labels_in_scope.get(identifier).value()); 965 } 966 967 m_state.labels_in_scope.remove(identifier); 968 969 return create_ast_node<LabelledStatement>({ m_source_code, rule_start.position(), position() }, identifier, labelled_item.release_nonnull()); 970} 971 972RefPtr<MetaProperty const> Parser::try_parse_new_target_expression() 973{ 974 // Optimization which skips the save/load state. 975 if (next_token().type() != TokenType::Period) 976 return {}; 977 978 save_state(); 979 auto rule_start = push_start(); 980 ArmedScopeGuard state_rollback_guard = [&] { 981 load_state(); 982 }; 983 984 consume(TokenType::New); 985 consume(TokenType::Period); 986 if (!match(TokenType::Identifier)) 987 return {}; 988 // The string 'target' cannot have escapes so we check original value. 989 if (consume().original_value() != "target"sv) 990 return {}; 991 992 state_rollback_guard.disarm(); 993 discard_saved_state(); 994 return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::NewTarget); 995} 996 997RefPtr<MetaProperty const> Parser::try_parse_import_meta_expression() 998{ 999 // Optimization which skips the save/load state. 1000 if (next_token().type() != TokenType::Period) 1001 return {}; 1002 1003 save_state(); 1004 auto rule_start = push_start(); 1005 ArmedScopeGuard state_rollback_guard = [&] { 1006 load_state(); 1007 }; 1008 1009 consume(TokenType::Import); 1010 consume(TokenType::Period); 1011 if (!match(TokenType::Identifier)) 1012 return {}; 1013 // The string 'meta' cannot have escapes so we check original value. 1014 if (consume().original_value() != "meta"sv) 1015 return {}; 1016 1017 state_rollback_guard.disarm(); 1018 discard_saved_state(); 1019 return create_ast_node<MetaProperty>({ m_source_code, rule_start.position(), position() }, MetaProperty::Type::ImportMeta); 1020} 1021 1022NonnullRefPtr<ImportCall const> Parser::parse_import_call() 1023{ 1024 auto rule_start = push_start(); 1025 1026 // We use the extended definition: 1027 // ImportCall[Yield, Await]: 1028 // import(AssignmentExpression[+In, ?Yield, ?Await] ,opt) 1029 // import(AssignmentExpression[+In, ?Yield, ?Await] ,AssignmentExpression[+In, ?Yield, ?Await] ,opt) 1030 // From https://tc39.es/proposal-import-assertions/#sec-evaluate-import-call 1031 1032 consume(TokenType::Import); 1033 consume(TokenType::ParenOpen); 1034 auto argument = parse_expression(2); 1035 1036 RefPtr<Expression const> options; 1037 if (match(TokenType::Comma)) { 1038 consume(TokenType::Comma); 1039 1040 if (!match(TokenType::ParenClose)) { 1041 options = parse_expression(2); 1042 1043 // Second optional comma 1044 if (match(TokenType::Comma)) 1045 consume(TokenType::Comma); 1046 } 1047 } 1048 1049 consume(TokenType::ParenClose); 1050 1051 return create_ast_node<ImportCall>({ m_source_code, rule_start.position(), position() }, move(argument), move(options)); 1052} 1053 1054NonnullRefPtr<ClassDeclaration const> Parser::parse_class_declaration() 1055{ 1056 auto rule_start = push_start(); 1057 return create_ast_node<ClassDeclaration>({ m_source_code, rule_start.position(), position() }, parse_class_expression(true)); 1058} 1059 1060NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_class_name) 1061{ 1062 auto rule_start = push_start(); 1063 // Classes are always in strict mode. 1064 TemporaryChange strict_mode_rollback(m_state.strict_mode, true); 1065 1066 consume(TokenType::Class); 1067 1068 Vector<NonnullRefPtr<ClassElement const>> elements; 1069 RefPtr<Expression const> super_class; 1070 RefPtr<FunctionExpression const> constructor; 1071 HashTable<DeprecatedFlyString> found_private_names; 1072 1073 DeprecatedFlyString class_name = expect_class_name || match_identifier() || match(TokenType::Yield) || match(TokenType::Await) 1074 ? consume_identifier_reference().DeprecatedFlyString_value() 1075 : ""; 1076 1077 check_identifier_name_for_assignment_validity(class_name, true); 1078 if (m_state.in_class_static_init_block && class_name == "await"sv) 1079 syntax_error("Identifier must not be a reserved word in modules ('await')"); 1080 1081 if (match(TokenType::Extends)) { 1082 consume(); 1083 auto [expression, should_continue_parsing] = parse_primary_expression(); 1084 1085 // Basically a (much) simplified parse_secondary_expression(). 1086 for (;;) { 1087 if (match(TokenType::TemplateLiteralStart)) { 1088 auto template_literal = parse_template_literal(true); 1089 expression = create_ast_node<TaggedTemplateLiteral>({ m_source_code, rule_start.position(), position() }, move(expression), move(template_literal)); 1090 continue; 1091 } 1092 if (match(TokenType::BracketOpen) || match(TokenType::Period) || match(TokenType::ParenOpen)) { 1093 auto precedence = g_operator_precedence.get(m_state.current_token.type()); 1094 expression = parse_secondary_expression(move(expression), precedence).expression; 1095 continue; 1096 } 1097 break; 1098 } 1099 1100 super_class = move(expression); 1101 (void)should_continue_parsing; 1102 } 1103 1104 consume(TokenType::CurlyOpen); 1105 1106 HashTable<StringView> referenced_private_names; 1107 HashTable<StringView>* outer_referenced_private_names = m_state.referenced_private_names; 1108 m_state.referenced_private_names = &referenced_private_names; 1109 ScopeGuard restore_private_name_table = [&] { 1110 m_state.referenced_private_names = outer_referenced_private_names; 1111 }; 1112 1113 while (!done() && !match(TokenType::CurlyClose)) { 1114 RefPtr<Expression const> property_key; 1115 bool is_static = false; 1116 bool is_constructor = false; 1117 bool is_generator = false; 1118 bool is_async = false; 1119 auto method_kind = ClassMethod::Kind::Method; 1120 1121 if (match(TokenType::Semicolon)) { 1122 consume(); 1123 continue; 1124 } 1125 1126 auto function_start = position(); 1127 1128 if (match(TokenType::Async)) { 1129 auto lookahead_token = next_token(); 1130 // If async is followed by a Semicolon or CurlyClose it is a field (CurlyClose indicates end of class) 1131 // Otherwise if it is followed by a ParenOpen it is a function named async 1132 if (lookahead_token.type() != TokenType::Semicolon && lookahead_token.type() != TokenType::CurlyClose && lookahead_token.type() != TokenType::ParenOpen 1133 && !lookahead_token.trivia_contains_line_terminator()) { 1134 consume(); 1135 is_async = true; 1136 } 1137 } 1138 1139 if (match(TokenType::Asterisk)) { 1140 consume(); 1141 is_generator = true; 1142 } 1143 1144 StringView name; 1145 if (match_property_key() || match(TokenType::PrivateIdentifier)) { 1146 if (!is_generator && !is_async && m_state.current_token.original_value() == "static"sv) { 1147 if (match(TokenType::Identifier)) { 1148 consume(); 1149 is_static = true; 1150 function_start = position(); 1151 if (match(TokenType::Async)) { 1152 consume(); 1153 is_async = true; 1154 } 1155 if (match(TokenType::Asterisk)) { 1156 consume(); 1157 is_generator = true; 1158 } 1159 } 1160 } 1161 1162 if (match(TokenType::Identifier)) { 1163 auto identifier_name = m_state.current_token.original_value(); 1164 1165 if (identifier_name == "get"sv) { 1166 method_kind = ClassMethod::Kind::Getter; 1167 consume(); 1168 } else if (identifier_name == "set"sv) { 1169 method_kind = ClassMethod::Kind::Setter; 1170 consume(); 1171 } 1172 } 1173 1174 if (match_property_key() || match(TokenType::PrivateIdentifier)) { 1175 switch (m_state.current_token.type()) { 1176 case TokenType::Identifier: 1177 name = consume().value(); 1178 property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name); 1179 break; 1180 case TokenType::PrivateIdentifier: 1181 name = consume().value(); 1182 if (name == "#constructor") 1183 syntax_error("Private property with name '#constructor' is not allowed"); 1184 1185 if (method_kind != ClassMethod::Kind::Method) { 1186 // It is a Syntax Error if PrivateBoundIdentifiers of ClassElementList contains any duplicate entries, 1187 // unless the name is used once for a getter and once for a setter and in no other entries, 1188 // and the getter and setter are either both static or both non-static. 1189 1190 for (auto& element : elements) { 1191 auto private_name = element->private_bound_identifier(); 1192 if (!private_name.has_value() || private_name.value() != name) 1193 continue; 1194 1195 if (element->class_element_kind() != ClassElement::ElementKind::Method 1196 || element->is_static() != is_static) { 1197 syntax_error(DeprecatedString::formatted("Duplicate private field or method named '{}'", name)); 1198 break; 1199 } 1200 1201 VERIFY(is<ClassMethod>(*element)); 1202 auto& class_method_element = static_cast<ClassMethod const&>(*element); 1203 1204 if (class_method_element.kind() == ClassMethod::Kind::Method || class_method_element.kind() == method_kind) { 1205 syntax_error(DeprecatedString::formatted("Duplicate private field or method named '{}'", name)); 1206 break; 1207 } 1208 } 1209 1210 found_private_names.set(name); 1211 } else if (found_private_names.set(name) != AK::HashSetResult::InsertedNewEntry) { 1212 syntax_error(DeprecatedString::formatted("Duplicate private field or method named '{}'", name)); 1213 } 1214 1215 property_key = create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, name); 1216 break; 1217 case TokenType::StringLiteral: { 1218 auto string_literal = parse_string_literal(consume()); 1219 name = string_literal->value(); 1220 property_key = move(string_literal); 1221 break; 1222 } 1223 default: 1224 property_key = parse_property_key(); 1225 break; 1226 } 1227 1228 // https://tc39.es/ecma262/#sec-class-definitions-static-semantics-early-errors 1229 // ClassElement : static MethodDefinition 1230 // It is a Syntax Error if PropName of MethodDefinition is "prototype". 1231 if (is_static && name == "prototype"sv) 1232 syntax_error("Classes may not have a static property named 'prototype'"); 1233 } else if ((match(TokenType::ParenOpen) || match(TokenType::Equals) || match(TokenType::Semicolon) || match(TokenType::CurlyClose)) && (is_static || is_async || method_kind != ClassMethod::Kind::Method)) { 1234 switch (method_kind) { 1235 case ClassMethod::Kind::Method: 1236 if (is_async) { 1237 name = "async"sv; 1238 is_async = false; 1239 } else { 1240 VERIFY(is_static); 1241 name = "static"sv; 1242 is_static = false; 1243 } 1244 break; 1245 case ClassMethod::Kind::Getter: 1246 name = "get"sv; 1247 method_kind = ClassMethod::Kind::Method; 1248 break; 1249 case ClassMethod::Kind::Setter: 1250 name = "set"sv; 1251 method_kind = ClassMethod::Kind::Method; 1252 break; 1253 } 1254 property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name); 1255 } else if (match(TokenType::CurlyOpen) && is_static) { 1256 auto static_start = push_start(); 1257 consume(TokenType::CurlyOpen); 1258 1259 auto static_init_block = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() }); 1260 1261 TemporaryChange break_context_rollback(m_state.in_break_context, false); 1262 TemporaryChange continue_context_rollback(m_state.in_continue_context, false); 1263 TemporaryChange function_context_rollback(m_state.in_function_context, false); 1264 TemporaryChange generator_function_context_rollback(m_state.in_generator_function_context, false); 1265 TemporaryChange async_function_context_rollback(m_state.await_expression_is_valid, false); 1266 TemporaryChange class_field_initializer_rollback(m_state.in_class_field_initializer, true); 1267 TemporaryChange class_static_init_block_rollback(m_state.in_class_static_init_block, true); 1268 TemporaryChange super_property_access_rollback(m_state.allow_super_property_lookup, true); 1269 1270 ScopePusher static_init_scope = ScopePusher::static_init_block_scope(*this, *static_init_block); 1271 parse_statement_list(static_init_block); 1272 1273 consume(TokenType::CurlyClose); 1274 elements.append(create_ast_node<StaticInitializer>({ m_source_code, static_start.position(), position() }, move(static_init_block), static_init_scope.contains_direct_call_to_eval())); 1275 continue; 1276 } else { 1277 expected("property key"); 1278 } 1279 1280 // Constructor may be a StringLiteral or an Identifier. 1281 if (!is_static && name == "constructor"sv) { 1282 if (method_kind != ClassMethod::Kind::Method) 1283 syntax_error("Class constructor may not be an accessor"); 1284 if (!constructor.is_null()) 1285 syntax_error("Classes may not have more than one constructor"); 1286 if (is_generator) 1287 syntax_error("Class constructor may not be a generator"); 1288 if (is_async) 1289 syntax_error("Class constructor may not be async"); 1290 1291 is_constructor = true; 1292 } 1293 } 1294 1295 if (match(TokenType::ParenOpen)) { 1296 u8 parse_options = FunctionNodeParseOptions::AllowSuperPropertyLookup; 1297 if (!super_class.is_null() && !is_static && is_constructor) 1298 parse_options |= FunctionNodeParseOptions::AllowSuperConstructorCall; 1299 if (method_kind == ClassMethod::Kind::Getter) 1300 parse_options |= FunctionNodeParseOptions::IsGetterFunction; 1301 if (method_kind == ClassMethod::Kind::Setter) 1302 parse_options |= FunctionNodeParseOptions::IsSetterFunction; 1303 if (is_generator) 1304 parse_options |= FunctionNodeParseOptions::IsGeneratorFunction; 1305 if (is_async) 1306 parse_options |= FunctionNodeParseOptions::IsAsyncFunction; 1307 auto function = parse_function_node<FunctionExpression>(parse_options, function_start); 1308 if (is_constructor) { 1309 constructor = move(function); 1310 } else if (!property_key.is_null()) { 1311 elements.append(create_ast_node<ClassMethod>({ m_source_code, rule_start.position(), position() }, property_key.release_nonnull(), move(function), method_kind, is_static)); 1312 } else { 1313 syntax_error("No key for class method"); 1314 } 1315 } else if (is_generator || is_async) { 1316 expected("ParenOpen"); 1317 consume(); 1318 } else if (property_key.is_null()) { 1319 expected("property key"); 1320 consume(); 1321 } else { 1322 if (name == "constructor"sv) 1323 syntax_error("Class cannot have field named 'constructor'"); 1324 1325 RefPtr<Expression const> initializer; 1326 bool contains_direct_call_to_eval = false; 1327 1328 if (match(TokenType::Equals)) { 1329 consume(); 1330 1331 TemporaryChange super_property_access_rollback(m_state.allow_super_property_lookup, true); 1332 TemporaryChange field_initializer_rollback(m_state.in_class_field_initializer, true); 1333 1334 auto class_field_scope = ScopePusher::class_field_scope(*this); 1335 initializer = parse_expression(2); 1336 contains_direct_call_to_eval = class_field_scope.contains_direct_call_to_eval(); 1337 } 1338 1339 elements.append(create_ast_node<ClassField>({ m_source_code, rule_start.position(), position() }, property_key.release_nonnull(), move(initializer), contains_direct_call_to_eval, is_static)); 1340 consume_or_insert_semicolon(); 1341 } 1342 } 1343 1344 consume(TokenType::CurlyClose); 1345 1346 if (constructor.is_null()) { 1347 auto constructor_body = create_ast_node<BlockStatement>({ m_source_code, rule_start.position(), position() }); 1348 if (!super_class.is_null()) { 1349 // Set constructor to the result of parsing the source text 1350 // constructor(... args){ super (...args);} 1351 // However: The most notable distinction is that while the aforementioned ECMAScript 1352 // source text observably calls the @@iterator method on %Array.prototype%, 1353 // this function does not. 1354 // So we use a custom version of SuperCall which doesn't use the @@iterator 1355 // method on %Array.prototype% visibly. 1356 DeprecatedFlyString argument_name = "args"; 1357 auto super_call = create_ast_node<SuperCall>( 1358 { m_source_code, rule_start.position(), position() }, 1359 SuperCall::IsPartOfSyntheticConstructor::Yes, 1360 CallExpression::Argument { create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, "args"), true }); 1361 // NOTE: While the JS approximation above doesn't do `return super(...args)`, the 1362 // abstract closure is expected to capture and return the result, so we do need a 1363 // return statement here to create the correct completion. 1364 constructor_body->append(create_ast_node<ReturnStatement>({ m_source_code, rule_start.position(), position() }, move(super_call))); 1365 1366 constructor = create_ast_node<FunctionExpression>( 1367 { m_source_code, rule_start.position(), position() }, class_name, "", 1368 move(constructor_body), Vector { FunctionParameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal, 1369 /* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false); 1370 } else { 1371 constructor = create_ast_node<FunctionExpression>( 1372 { m_source_code, rule_start.position(), position() }, class_name, "", 1373 move(constructor_body), Vector<FunctionParameter> {}, 0, FunctionKind::Normal, 1374 /* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false); 1375 } 1376 } 1377 1378 // We could be in a subclass defined within the main class so must move all non declared private names to outer. 1379 for (auto& private_name : referenced_private_names) { 1380 if (found_private_names.contains(private_name)) 1381 continue; 1382 if (outer_referenced_private_names) 1383 outer_referenced_private_names->set(private_name); 1384 else // FIXME: Make these error appear in the appropriate places. 1385 syntax_error(DeprecatedString::formatted("Reference to undeclared private field or method '{}'", private_name)); 1386 } 1387 1388 auto function_start_offset = rule_start.position().offset; 1389 auto function_end_offset = position().offset - m_state.current_token.trivia().length(); 1390 auto source_text = DeprecatedString { m_state.lexer.source().substring_view(function_start_offset, function_end_offset - function_start_offset) }; 1391 1392 return create_ast_node<ClassExpression>({ m_source_code, rule_start.position(), position() }, move(class_name), move(source_text), move(constructor), move(super_class), move(elements)); 1393} 1394 1395Parser::PrimaryExpressionParseResult Parser::parse_primary_expression() 1396{ 1397 auto rule_start = push_start(); 1398 if (match_unary_prefixed_expression()) 1399 return { parse_unary_prefixed_expression() }; 1400 1401 auto try_arrow_function_parse_or_fail = [this](Position const& position, bool expect_paren, bool is_async = false) -> RefPtr<FunctionExpression const> { 1402 if (try_parse_arrow_function_expression_failed_at_position(position)) 1403 return nullptr; 1404 auto arrow_function = try_parse_arrow_function_expression(expect_paren, is_async); 1405 if (arrow_function) 1406 return arrow_function; 1407 1408 set_try_parse_arrow_function_expression_failed_at_position(position, true); 1409 return nullptr; 1410 }; 1411 1412 switch (m_state.current_token.type()) { 1413 case TokenType::ParenOpen: { 1414 auto paren_position = position(); 1415 consume(TokenType::ParenOpen); 1416 if ((match(TokenType::ParenClose) || match_identifier() || match(TokenType::TripleDot) || match(TokenType::CurlyOpen) || match(TokenType::BracketOpen))) { 1417 if (auto arrow_function_result = try_arrow_function_parse_or_fail(paren_position, true)) 1418 return { arrow_function_result.release_nonnull(), false }; 1419 } 1420 auto expression = parse_expression(0); 1421 consume(TokenType::ParenClose); 1422 if (is<FunctionExpression>(*expression)) { 1423 auto& function = static_cast<FunctionExpression const&>(*expression); 1424 if (function.kind() == FunctionKind::Generator && function.name() == "yield"sv) 1425 syntax_error("function is not allowed to be called 'yield' in this context", function.source_range().start); 1426 if (function.kind() == FunctionKind::Async && function.name() == "await"sv) 1427 syntax_error("function is not allowed to be called 'await' in this context", function.source_range().start); 1428 } 1429 return { move(expression) }; 1430 } 1431 case TokenType::This: 1432 consume(); 1433 return { create_ast_node<ThisExpression>({ m_source_code, rule_start.position(), position() }) }; 1434 case TokenType::Class: 1435 return { parse_class_expression(false) }; 1436 case TokenType::Super: 1437 consume(); 1438 if (!m_state.allow_super_property_lookup) 1439 syntax_error("'super' keyword unexpected here"); 1440 return { create_ast_node<SuperExpression>({ m_source_code, rule_start.position(), position() }) }; 1441 case TokenType::EscapedKeyword: 1442 if (match_invalid_escaped_keyword()) 1443 syntax_error("Keyword must not contain escaped characters"); 1444 [[fallthrough]]; 1445 case TokenType::Identifier: { 1446 read_as_identifier:; 1447 if (auto arrow_function_result = try_arrow_function_parse_or_fail(position(), false)) 1448 return { arrow_function_result.release_nonnull(), false }; 1449 1450 auto string = m_state.current_token.value(); 1451 // This could be 'eval' or 'arguments' and thus needs a custom check (`eval[1] = true`) 1452 if (m_state.strict_mode && (string == "let" || is_strict_reserved_word(string))) 1453 syntax_error(DeprecatedString::formatted("Identifier must not be a reserved word in strict mode ('{}')", string)); 1454 return { parse_identifier() }; 1455 } 1456 case TokenType::NumericLiteral: 1457 return { create_ast_node<NumericLiteral>({ m_source_code, rule_start.position(), position() }, consume_and_validate_numeric_literal().double_value()) }; 1458 case TokenType::BigIntLiteral: 1459 return { create_ast_node<BigIntLiteral>({ m_source_code, rule_start.position(), position() }, consume().value()) }; 1460 case TokenType::BoolLiteral: 1461 return { create_ast_node<BooleanLiteral>({ m_source_code, rule_start.position(), position() }, consume().bool_value()) }; 1462 case TokenType::StringLiteral: 1463 return { parse_string_literal(consume()) }; 1464 case TokenType::NullLiteral: 1465 consume(); 1466 return { create_ast_node<NullLiteral>({ m_source_code, rule_start.position(), position() }) }; 1467 case TokenType::CurlyOpen: 1468 return { parse_object_expression() }; 1469 case TokenType::Async: { 1470 auto lookahead_token = next_token(); 1471 // No valid async function (arrow or not) can have a line terminator after the async since asi would kick in. 1472 if (lookahead_token.trivia_contains_line_terminator()) 1473 goto read_as_identifier; 1474 1475 if (lookahead_token.type() == TokenType::Function) 1476 return { parse_function_node<FunctionExpression>() }; 1477 1478 if (lookahead_token.type() == TokenType::ParenOpen) { 1479 if (auto arrow_function_result = try_arrow_function_parse_or_fail(position(), true, true)) 1480 return { arrow_function_result.release_nonnull(), false }; 1481 } else if (lookahead_token.is_identifier_name()) { 1482 if (auto arrow_function_result = try_arrow_function_parse_or_fail(position(), false, true)) 1483 return { arrow_function_result.release_nonnull(), false }; 1484 } 1485 goto read_as_identifier; 1486 } 1487 case TokenType::Function: 1488 return { parse_function_node<FunctionExpression>() }; 1489 case TokenType::BracketOpen: 1490 return { parse_array_expression() }; 1491 case TokenType::RegexLiteral: 1492 return { parse_regexp_literal() }; 1493 case TokenType::TemplateLiteralStart: 1494 return { parse_template_literal(false) }; 1495 case TokenType::New: { 1496 auto new_start = position(); 1497 auto new_target_result = try_parse_new_target_expression(); 1498 if (!new_target_result.is_null()) { 1499 if (!m_state.in_function_context && !m_state.in_eval_function_context && !m_state.in_class_static_init_block) 1500 syntax_error("'new.target' not allowed outside of a function", new_start); 1501 return { new_target_result.release_nonnull() }; 1502 } 1503 return { parse_new_expression() }; 1504 } 1505 case TokenType::Import: { 1506 auto lookahead_token = next_token(); 1507 if (lookahead_token.type() == TokenType::ParenOpen) 1508 return { parse_import_call() }; 1509 1510 if (lookahead_token.type() == TokenType::Period) { 1511 if (auto import_meta = try_parse_import_meta_expression()) { 1512 if (m_program_type != Program::Type::Module) 1513 syntax_error("import.meta is only allowed in modules"); 1514 return { import_meta.release_nonnull() }; 1515 } 1516 } else { 1517 consume(); 1518 expected("import.meta or import call"); 1519 } 1520 break; 1521 } 1522 case TokenType::Yield: 1523 if (!m_state.in_generator_function_context) 1524 goto read_as_identifier; 1525 return { parse_yield_expression(), false }; 1526 case TokenType::Await: 1527 if (!m_state.await_expression_is_valid) 1528 goto read_as_identifier; 1529 return { parse_await_expression() }; 1530 case TokenType::PrivateIdentifier: 1531 if (!is_private_identifier_valid()) 1532 syntax_error(DeprecatedString::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); 1533 if (next_token().type() != TokenType::In) 1534 syntax_error("Cannot have a private identifier in expression if not followed by 'in'"); 1535 return { create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().value()) }; 1536 default: 1537 if (match_identifier_name()) 1538 goto read_as_identifier; 1539 break; 1540 } 1541 expected("primary expression"); 1542 consume(); 1543 return { create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() }) }; 1544} 1545 1546NonnullRefPtr<RegExpLiteral const> Parser::parse_regexp_literal() 1547{ 1548 auto rule_start = push_start(); 1549 auto pattern = consume().value(); 1550 // Remove leading and trailing slash. 1551 pattern = pattern.substring_view(1, pattern.length() - 2); 1552 1553 auto flags = DeprecatedString::empty(); 1554 auto parsed_flags = RegExpObject::default_flags; 1555 1556 if (match(TokenType::RegexFlags)) { 1557 auto flags_start = position(); 1558 flags = consume().value(); 1559 1560 auto parsed_flags_or_error = regex_flags_from_string(flags); 1561 if (parsed_flags_or_error.is_error()) 1562 syntax_error(parsed_flags_or_error.release_error(), flags_start); 1563 else 1564 parsed_flags = parsed_flags_or_error.release_value(); 1565 } 1566 1567 DeprecatedString parsed_pattern; 1568 auto parsed_pattern_result = parse_regex_pattern(pattern, parsed_flags.has_flag_set(ECMAScriptFlags::Unicode), parsed_flags.has_flag_set(ECMAScriptFlags::UnicodeSets)); 1569 if (parsed_pattern_result.is_error()) { 1570 syntax_error(parsed_pattern_result.release_error().error, rule_start.position()); 1571 parsed_pattern = DeprecatedString::empty(); 1572 } else { 1573 parsed_pattern = parsed_pattern_result.release_value(); 1574 } 1575 auto parsed_regex = Regex<ECMA262>::parse_pattern(parsed_pattern, parsed_flags); 1576 1577 if (parsed_regex.error != regex::Error::NoError) 1578 syntax_error(DeprecatedString::formatted("RegExp compile error: {}", Regex<ECMA262>(parsed_regex, parsed_pattern, parsed_flags).error_string()), rule_start.position()); 1579 1580 SourceRange range { m_source_code, rule_start.position(), position() }; 1581 return create_ast_node<RegExpLiteral>(move(range), move(parsed_regex), move(parsed_pattern), move(parsed_flags), pattern.to_deprecated_string(), move(flags)); 1582} 1583 1584static bool is_simple_assignment_target(Expression const& expression, bool allow_web_reality_call_expression = true) 1585{ 1586 return is<Identifier>(expression) || is<MemberExpression>(expression) || (allow_web_reality_call_expression && is<CallExpression>(expression)); 1587} 1588 1589NonnullRefPtr<Expression const> Parser::parse_unary_prefixed_expression() 1590{ 1591 auto rule_start = push_start(); 1592 auto precedence = g_operator_precedence.get(m_state.current_token.type()); 1593 auto associativity = operator_associativity(m_state.current_token.type()); 1594 switch (m_state.current_token.type()) { 1595 case TokenType::PlusPlus: { 1596 consume(); 1597 auto rhs_start = position(); 1598 auto rhs = parse_expression(precedence, associativity); 1599 if (!is_simple_assignment_target(*rhs)) 1600 syntax_error(DeprecatedString::formatted("Right-hand side of prefix increment operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); 1601 1602 if (m_state.strict_mode && is<Identifier>(*rhs)) { 1603 auto& identifier = static_cast<Identifier const&>(*rhs); 1604 auto& name = identifier.string(); 1605 check_identifier_name_for_assignment_validity(name); 1606 } 1607 1608 return create_ast_node<UpdateExpression>({ m_source_code, rule_start.position(), position() }, UpdateOp::Increment, move(rhs), true); 1609 } 1610 case TokenType::MinusMinus: { 1611 consume(); 1612 auto rhs_start = position(); 1613 auto rhs = parse_expression(precedence, associativity); 1614 if (!is_simple_assignment_target(*rhs)) 1615 syntax_error(DeprecatedString::formatted("Right-hand side of prefix decrement operator must be identifier or member expression, got {}", rhs->class_name()), rhs_start); 1616 1617 if (m_state.strict_mode && is<Identifier>(*rhs)) { 1618 auto& identifier = static_cast<Identifier const&>(*rhs); 1619 auto& name = identifier.string(); 1620 check_identifier_name_for_assignment_validity(name); 1621 } 1622 1623 return create_ast_node<UpdateExpression>({ m_source_code, rule_start.position(), position() }, UpdateOp::Decrement, move(rhs), true); 1624 } 1625 case TokenType::ExclamationMark: 1626 consume(); 1627 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Not, parse_expression(precedence, associativity)); 1628 case TokenType::Tilde: 1629 consume(); 1630 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::BitwiseNot, parse_expression(precedence, associativity)); 1631 case TokenType::Plus: 1632 consume(); 1633 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Plus, parse_expression(precedence, associativity)); 1634 case TokenType::Minus: 1635 consume(); 1636 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Minus, parse_expression(precedence, associativity)); 1637 case TokenType::Typeof: 1638 consume(); 1639 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Typeof, parse_expression(precedence, associativity)); 1640 case TokenType::Void: 1641 consume(); 1642 // FIXME: This check is really hiding the fact that we don't deal with different expressions correctly. 1643 if (match(TokenType::Yield) && m_state.in_generator_function_context) 1644 syntax_error("'yield' is not an identifier in generator function context"); 1645 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Void, parse_expression(precedence, associativity)); 1646 case TokenType::Delete: { 1647 consume(); 1648 auto rhs_start = position(); 1649 auto rhs = parse_expression(precedence, associativity); 1650 if (is<Identifier>(*rhs) && m_state.strict_mode) { 1651 syntax_error("Delete of an unqualified identifier in strict mode.", rhs_start); 1652 } 1653 if (is<MemberExpression>(*rhs)) { 1654 auto& member_expression = static_cast<MemberExpression const&>(*rhs); 1655 if (member_expression.ends_in_private_name()) 1656 syntax_error("Private fields cannot be deleted"); 1657 } 1658 return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Delete, move(rhs)); 1659 } 1660 default: 1661 expected("primary expression"); 1662 consume(); 1663 return create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() }); 1664 } 1665} 1666 1667NonnullRefPtr<Expression const> Parser::parse_property_key() 1668{ 1669 auto rule_start = push_start(); 1670 if (match(TokenType::StringLiteral)) { 1671 return parse_string_literal(consume()); 1672 } else if (match(TokenType::NumericLiteral)) { 1673 return create_ast_node<NumericLiteral>({ m_source_code, rule_start.position(), position() }, consume().double_value()); 1674 } else if (match(TokenType::BigIntLiteral)) { 1675 return create_ast_node<BigIntLiteral>({ m_source_code, rule_start.position(), position() }, consume().value()); 1676 } else if (match(TokenType::BracketOpen)) { 1677 consume(TokenType::BracketOpen); 1678 auto result = parse_expression(2); 1679 consume(TokenType::BracketClose); 1680 return result; 1681 } else { 1682 if (!match_identifier_name()) 1683 expected("IdentifierName"); 1684 return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, consume().value()); 1685 } 1686} 1687 1688NonnullRefPtr<ObjectExpression const> Parser::parse_object_expression() 1689{ 1690 auto rule_start = push_start(); 1691 consume(TokenType::CurlyOpen); 1692 1693 Vector<NonnullRefPtr<ObjectProperty>> properties; 1694 ObjectProperty::Type property_type; 1695 Optional<SourceRange> invalid_object_literal_property_range; 1696 1697 auto skip_to_next_property = [&] { 1698 while (!done() && !match(TokenType::Comma) && !match(TokenType::CurlyOpen)) 1699 consume(); 1700 }; 1701 1702 // It is a Syntax Error if PropertyNameList of PropertyDefinitionList contains any duplicate 1703 // entries for "__proto__" and at least two of those entries were obtained from productions of 1704 // the form PropertyDefinition : PropertyKey : AssignmentExpression . 1705 bool has_direct_proto_property = false; 1706 1707 while (!done() && !match(TokenType::CurlyClose)) { 1708 property_type = ObjectProperty::Type::KeyValue; 1709 RefPtr<Expression const> property_key; 1710 RefPtr<Expression const> property_value; 1711 FunctionKind function_kind { FunctionKind::Normal }; 1712 1713 if (match(TokenType::TripleDot)) { 1714 consume(); 1715 property_key = parse_expression(4); 1716 properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, nullptr, ObjectProperty::Type::Spread, false)); 1717 if (!match(TokenType::Comma)) 1718 break; 1719 consume(TokenType::Comma); 1720 continue; 1721 } 1722 1723 auto type = m_state.current_token.type(); 1724 auto function_start = position(); 1725 1726 if (match(TokenType::Async)) { 1727 auto lookahead_token = next_token(); 1728 1729 if (lookahead_token.type() != TokenType::ParenOpen && lookahead_token.type() != TokenType::Colon 1730 && lookahead_token.type() != TokenType::Comma && lookahead_token.type() != TokenType::CurlyClose 1731 && lookahead_token.type() != TokenType::Async 1732 && !lookahead_token.trivia_contains_line_terminator()) { 1733 consume(TokenType::Async); 1734 function_kind = FunctionKind::Async; 1735 } 1736 } 1737 if (match(TokenType::Asterisk)) { 1738 consume(); 1739 property_type = ObjectProperty::Type::KeyValue; 1740 property_key = parse_property_key(); 1741 VERIFY(function_kind == FunctionKind::Normal || function_kind == FunctionKind::Async); 1742 function_kind = function_kind == FunctionKind::Normal ? FunctionKind::Generator : FunctionKind::AsyncGenerator; 1743 } else if (match_identifier()) { 1744 auto identifier = consume(); 1745 if (identifier.original_value() == "get"sv && match_property_key()) { 1746 property_type = ObjectProperty::Type::Getter; 1747 property_key = parse_property_key(); 1748 } else if (identifier.original_value() == "set"sv && match_property_key()) { 1749 property_type = ObjectProperty::Type::Setter; 1750 property_key = parse_property_key(); 1751 } else { 1752 property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, identifier.value()); 1753 property_value = create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, identifier.DeprecatedFlyString_value()); 1754 } 1755 } else { 1756 property_key = parse_property_key(); 1757 } 1758 1759 // 4. Else if propKey is the String value "__proto__" and if IsComputedPropertyKey of PropertyName is false, then 1760 // a. Let isProtoSetter be true. 1761 bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_key) && static_cast<StringLiteral const&>(*property_key).value() == "__proto__"; 1762 1763 if (property_type == ObjectProperty::Type::Getter || property_type == ObjectProperty::Type::Setter) { 1764 if (!match(TokenType::ParenOpen)) { 1765 expected("'(' for object getter or setter property"); 1766 skip_to_next_property(); 1767 continue; 1768 } 1769 } 1770 if (match(TokenType::Equals)) { 1771 // Not a valid object literal, but a valid assignment target 1772 consume(); 1773 // Parse the expression and throw it away 1774 auto expression = parse_expression(2); 1775 if (!invalid_object_literal_property_range.has_value()) 1776 invalid_object_literal_property_range = expression->source_range(); 1777 } else if (match(TokenType::ParenOpen)) { 1778 VERIFY(property_key); 1779 u8 parse_options = FunctionNodeParseOptions::AllowSuperPropertyLookup; 1780 if (property_type == ObjectProperty::Type::Getter) 1781 parse_options |= FunctionNodeParseOptions::IsGetterFunction; 1782 if (property_type == ObjectProperty::Type::Setter) 1783 parse_options |= FunctionNodeParseOptions::IsSetterFunction; 1784 if (function_kind == FunctionKind::Generator || function_kind == FunctionKind::AsyncGenerator) 1785 parse_options |= FunctionNodeParseOptions::IsGeneratorFunction; 1786 if (function_kind == FunctionKind::Async || function_kind == FunctionKind::AsyncGenerator) 1787 parse_options |= FunctionNodeParseOptions::IsAsyncFunction; 1788 auto function = parse_function_node<FunctionExpression>(parse_options, function_start); 1789 properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, function, property_type, true)); 1790 } else if (match(TokenType::Colon)) { 1791 if (!property_key) { 1792 expected("a property name"); 1793 skip_to_next_property(); 1794 continue; 1795 } 1796 consume(); 1797 if (is_proto) { 1798 if (has_direct_proto_property) 1799 syntax_error("Property name '__proto__' must not appear more than once in object literal"); 1800 has_direct_proto_property = true; 1801 } 1802 if (is_proto && property_type == ObjectProperty::Type::KeyValue) 1803 property_type = ObjectProperty::Type::ProtoSetter; 1804 1805 auto rhs_expression = parse_expression(2); 1806 bool is_method = is<FunctionExpression>(*rhs_expression); 1807 properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, move(rhs_expression), property_type, is_method)); 1808 } else if (property_key && property_value) { 1809 if (m_state.strict_mode && is<StringLiteral>(*property_key)) { 1810 auto& string_literal = static_cast<StringLiteral const&>(*property_key); 1811 if (is_strict_reserved_word(string_literal.value())) 1812 syntax_error(DeprecatedString::formatted("'{}' is a reserved keyword", string_literal.value())); 1813 } 1814 1815 properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, *property_value, property_type, false)); 1816 } else { 1817 expected("a property"); 1818 skip_to_next_property(); 1819 continue; 1820 } 1821 1822 if (!match(TokenType::Comma)) 1823 break; 1824 consume(TokenType::Comma); 1825 } 1826 1827 consume(TokenType::CurlyClose); 1828 1829 if (invalid_object_literal_property_range.has_value()) { 1830 size_t object_expression_offset = rule_start.position().offset; 1831 VERIFY(!m_state.invalid_property_range_in_object_expression.contains(object_expression_offset)); 1832 m_state.invalid_property_range_in_object_expression.set(object_expression_offset, invalid_object_literal_property_range->start); 1833 } 1834 1835 properties.shrink_to_fit(); 1836 return create_ast_node<ObjectExpression>( 1837 { m_source_code, rule_start.position(), position() }, 1838 move(properties)); 1839} 1840 1841NonnullRefPtr<ArrayExpression const> Parser::parse_array_expression() 1842{ 1843 auto rule_start = push_start(); 1844 consume(TokenType::BracketOpen); 1845 1846 Vector<RefPtr<Expression const>> elements; 1847 while (match_expression() || match(TokenType::TripleDot) || match(TokenType::Comma)) { 1848 RefPtr<Expression const> expression; 1849 1850 if (match(TokenType::TripleDot)) { 1851 consume(TokenType::TripleDot); 1852 expression = create_ast_node<SpreadExpression>({ m_source_code, rule_start.position(), position() }, parse_expression(2)); 1853 } else if (match_expression()) { 1854 expression = parse_expression(2); 1855 } 1856 1857 elements.append(expression); 1858 if (!match(TokenType::Comma)) 1859 break; 1860 consume(TokenType::Comma); 1861 } 1862 1863 consume(TokenType::BracketClose); 1864 1865 elements.shrink_to_fit(); 1866 return create_ast_node<ArrayExpression>({ m_source_code, rule_start.position(), position() }, move(elements)); 1867} 1868 1869NonnullRefPtr<StringLiteral const> Parser::parse_string_literal(Token const& token, StringLiteralType string_literal_type, bool* contains_invalid_escape) 1870{ 1871 auto rule_start = push_start(); 1872 auto status = Token::StringValueStatus::Ok; 1873 auto string = token.string_value(status); 1874 // NOTE: Tagged templates should not fail on invalid strings as their raw contents can still be accessed. 1875 if (status != Token::StringValueStatus::Ok) { 1876 DeprecatedString message; 1877 if (status == Token::StringValueStatus::LegacyOctalEscapeSequence) { 1878 m_state.string_legacy_octal_escape_sequence_in_scope = true; 1879 // It is a Syntax Error if the [Tagged] parameter was not set and Template{Head, Middle, Tail} Contains NotEscapeSequence. 1880 if (string_literal_type != StringLiteralType::Normal) 1881 message = "Octal escape sequence not allowed in template literal"; 1882 else if (m_state.strict_mode) 1883 message = "Octal escape sequence in string literal not allowed in strict mode"; 1884 } else if (status == Token::StringValueStatus::MalformedHexEscape || status == Token::StringValueStatus::MalformedUnicodeEscape) { 1885 auto type = status == Token::StringValueStatus::MalformedUnicodeEscape ? "unicode" : "hexadecimal"; 1886 message = DeprecatedString::formatted("Malformed {} escape sequence", type); 1887 } else if (status == Token::StringValueStatus::UnicodeEscapeOverflow) { 1888 message = "Unicode code_point must not be greater than 0x10ffff in escape sequence"; 1889 } else { 1890 VERIFY_NOT_REACHED(); 1891 } 1892 1893 if (!message.is_empty()) { 1894 if (contains_invalid_escape != nullptr) { 1895 VERIFY(string_literal_type == StringLiteralType::TaggedTemplate); 1896 *contains_invalid_escape = true; 1897 } else { 1898 syntax_error(message, Position { token.line_number(), token.line_column() }); 1899 } 1900 } 1901 } 1902 1903 return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, string); 1904} 1905 1906NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagged) 1907{ 1908 auto rule_start = push_start(); 1909 consume(TokenType::TemplateLiteralStart); 1910 1911 Vector<NonnullRefPtr<Expression const>> expressions; 1912 Vector<NonnullRefPtr<Expression const>> raw_strings; 1913 1914 auto append_empty_string = [this, &rule_start, &expressions, &raw_strings, is_tagged]() { 1915 auto string_literal = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, ""); 1916 expressions.append(string_literal); 1917 if (is_tagged) 1918 raw_strings.append(string_literal); 1919 }; 1920 1921 if (!match(TokenType::TemplateLiteralString)) 1922 append_empty_string(); 1923 1924 while (!done() && !match(TokenType::TemplateLiteralEnd) && !match(TokenType::UnterminatedTemplateLiteral)) { 1925 if (match(TokenType::TemplateLiteralString)) { 1926 auto token = consume(); 1927 bool contains_invalid_escape = false; 1928 auto parsed_string_value = parse_string_literal(token, 1929 is_tagged ? StringLiteralType::TaggedTemplate : StringLiteralType::NonTaggedTemplate, 1930 is_tagged ? &contains_invalid_escape : nullptr); 1931 // An invalid string leads to a cooked value of `undefined` but still gives the raw string. 1932 if (contains_invalid_escape) 1933 expressions.append(create_ast_node<NullLiteral>({ m_source_code, rule_start.position(), position() })); 1934 else 1935 expressions.append(move(parsed_string_value)); 1936 if (is_tagged) 1937 raw_strings.append(create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, token.raw_template_value())); 1938 } else if (match(TokenType::TemplateLiteralExprStart)) { 1939 consume(TokenType::TemplateLiteralExprStart); 1940 if (match(TokenType::TemplateLiteralExprEnd)) { 1941 syntax_error("Empty template literal expression block"); 1942 return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions); 1943 } 1944 1945 expressions.append(parse_expression(0)); 1946 if (match(TokenType::UnterminatedTemplateLiteral)) { 1947 syntax_error("Unterminated template literal"); 1948 return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions); 1949 } 1950 consume(TokenType::TemplateLiteralExprEnd); 1951 1952 if (!match(TokenType::TemplateLiteralString)) 1953 append_empty_string(); 1954 } else { 1955 expected("Template literal string or expression"); 1956 break; 1957 } 1958 } 1959 1960 if (match(TokenType::UnterminatedTemplateLiteral)) { 1961 syntax_error("Unterminated template literal"); 1962 } else { 1963 consume(TokenType::TemplateLiteralEnd); 1964 } 1965 1966 if (is_tagged) 1967 return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions, raw_strings); 1968 return create_ast_node<TemplateLiteral>({ m_source_code, rule_start.position(), position() }, expressions); 1969} 1970 1971NonnullRefPtr<Expression const> Parser::parse_expression(int min_precedence, Associativity associativity, ForbiddenTokens forbidden) 1972{ 1973 auto rule_start = push_start(); 1974 auto [expression, should_continue_parsing] = parse_primary_expression(); 1975 auto check_for_invalid_object_property = [&](auto& expression) { 1976 if (is<ObjectExpression>(*expression)) { 1977 if (auto start_offset = m_state.invalid_property_range_in_object_expression.get(expression->start_offset()); start_offset.has_value()) 1978 syntax_error("Invalid property in object literal", start_offset.value()); 1979 } 1980 }; 1981 if (is<Identifier>(*expression) && m_state.current_scope_pusher) { 1982 auto identifier_instance = static_ptr_cast<Identifier const>(expression); 1983 auto function_scope = m_state.current_scope_pusher->last_function_scope(); 1984 auto function_parent_scope = function_scope ? function_scope->parent_scope() : nullptr; 1985 bool has_not_been_declared_as_variable = true; 1986 for (auto scope = m_state.current_scope_pusher; scope != function_parent_scope; scope = scope->parent_scope()) { 1987 if (scope->has_declaration(identifier_instance->string())) { 1988 has_not_been_declared_as_variable = false; 1989 break; 1990 } 1991 } 1992 1993 if (has_not_been_declared_as_variable) { 1994 if (identifier_instance->string() == "arguments"sv) 1995 m_state.current_scope_pusher->set_contains_access_to_arguments_object(); 1996 } 1997 } 1998 1999 while (match(TokenType::TemplateLiteralStart)) { 2000 auto template_literal = parse_template_literal(true); 2001 expression = create_ast_node<TaggedTemplateLiteral>({ m_source_code, rule_start.position(), position() }, move(expression), move(template_literal)); 2002 } 2003 if (should_continue_parsing) { 2004 while (match_secondary_expression(forbidden)) { 2005 int new_precedence = g_operator_precedence.get(m_state.current_token.type()); 2006 if (new_precedence < min_precedence) 2007 break; 2008 if (new_precedence == min_precedence && associativity == Associativity::Left) 2009 break; 2010 check_for_invalid_object_property(expression); 2011 2012 Associativity new_associativity = operator_associativity(m_state.current_token.type()); 2013 auto result = parse_secondary_expression(move(expression), new_precedence, new_associativity, forbidden); 2014 expression = result.expression; 2015 forbidden = forbidden.merge(result.forbidden); 2016 while (match(TokenType::TemplateLiteralStart) && !is<UpdateExpression>(*expression)) { 2017 auto template_literal = parse_template_literal(true); 2018 expression = create_ast_node<TaggedTemplateLiteral>({ m_source_code, rule_start.position(), position() }, move(expression), move(template_literal)); 2019 } 2020 } 2021 } 2022 2023 if (is<SuperExpression>(*expression)) 2024 syntax_error("'super' keyword unexpected here"); 2025 2026 check_for_invalid_object_property(expression); 2027 2028 if (is<CallExpression>(*expression) && m_state.current_scope_pusher) { 2029 auto& callee = static_ptr_cast<CallExpression const>(expression)->callee(); 2030 if (is<Identifier>(callee)) { 2031 auto& identifier_instance = static_cast<Identifier const&>(callee); 2032 if (identifier_instance.string() == "eval"sv) { 2033 bool has_not_been_declared_as_variable = true; 2034 for (auto scope = m_state.current_scope_pusher; scope; scope = scope->parent_scope()) { 2035 if (scope->has_declaration(identifier_instance.string())) { 2036 has_not_been_declared_as_variable = false; 2037 break; 2038 } 2039 } 2040 if (has_not_been_declared_as_variable) 2041 m_state.current_scope_pusher->set_contains_direct_call_to_eval(); 2042 } 2043 } 2044 } 2045 2046 if (match(TokenType::Comma) && min_precedence <= 1) { 2047 Vector<NonnullRefPtr<Expression const>> expressions; 2048 expressions.append(expression); 2049 while (match(TokenType::Comma)) { 2050 consume(); 2051 expressions.append(parse_expression(2)); 2052 } 2053 expressions.shrink_to_fit(); 2054 expression = create_ast_node<SequenceExpression>({ m_source_code, rule_start.position(), position() }, move(expressions)); 2055 } 2056 return expression; 2057} 2058 2059Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden) 2060{ 2061 auto rule_start = push_start(); 2062 switch (m_state.current_token.type()) { 2063 case TokenType::Plus: 2064 consume(); 2065 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Addition, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2066 case TokenType::PlusEquals: 2067 return parse_assignment_expression(AssignmentOp::AdditionAssignment, move(lhs), min_precedence, associativity, forbidden); 2068 case TokenType::Minus: 2069 consume(); 2070 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Subtraction, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2071 case TokenType::MinusEquals: 2072 return parse_assignment_expression(AssignmentOp::SubtractionAssignment, move(lhs), min_precedence, associativity, forbidden); 2073 case TokenType::Asterisk: 2074 consume(); 2075 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Multiplication, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2076 case TokenType::AsteriskEquals: 2077 return parse_assignment_expression(AssignmentOp::MultiplicationAssignment, move(lhs), min_precedence, associativity, forbidden); 2078 case TokenType::Slash: 2079 consume(); 2080 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Division, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2081 case TokenType::SlashEquals: 2082 return parse_assignment_expression(AssignmentOp::DivisionAssignment, move(lhs), min_precedence, associativity, forbidden); 2083 case TokenType::Percent: 2084 consume(); 2085 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2086 case TokenType::PercentEquals: 2087 return parse_assignment_expression(AssignmentOp::ModuloAssignment, move(lhs), min_precedence, associativity, forbidden); 2088 case TokenType::DoubleAsterisk: 2089 consume(); 2090 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2091 case TokenType::DoubleAsteriskEquals: 2092 return parse_assignment_expression(AssignmentOp::ExponentiationAssignment, move(lhs), min_precedence, associativity, forbidden); 2093 case TokenType::GreaterThan: 2094 consume(); 2095 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2096 case TokenType::GreaterThanEquals: 2097 consume(); 2098 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2099 case TokenType::LessThan: 2100 consume(); 2101 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2102 case TokenType::LessThanEquals: 2103 consume(); 2104 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2105 case TokenType::EqualsEqualsEquals: 2106 consume(); 2107 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::StrictlyEquals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2108 case TokenType::ExclamationMarkEqualsEquals: 2109 consume(); 2110 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::StrictlyInequals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2111 case TokenType::EqualsEquals: 2112 consume(); 2113 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::LooselyEquals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2114 case TokenType::ExclamationMarkEquals: 2115 consume(); 2116 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::LooselyInequals, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2117 case TokenType::In: 2118 consume(); 2119 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::In, move(lhs), parse_expression(min_precedence, associativity)); 2120 case TokenType::Instanceof: 2121 consume(); 2122 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::InstanceOf, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2123 case TokenType::Ampersand: 2124 consume(); 2125 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::BitwiseAnd, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2126 case TokenType::AmpersandEquals: 2127 return parse_assignment_expression(AssignmentOp::BitwiseAndAssignment, move(lhs), min_precedence, associativity, forbidden); 2128 case TokenType::Pipe: 2129 consume(); 2130 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::BitwiseOr, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2131 case TokenType::PipeEquals: 2132 return parse_assignment_expression(AssignmentOp::BitwiseOrAssignment, move(lhs), min_precedence, associativity, forbidden); 2133 case TokenType::Caret: 2134 consume(); 2135 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::BitwiseXor, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2136 case TokenType::CaretEquals: 2137 return parse_assignment_expression(AssignmentOp::BitwiseXorAssignment, move(lhs), min_precedence, associativity, forbidden); 2138 case TokenType::ShiftLeft: 2139 consume(); 2140 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::LeftShift, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2141 case TokenType::ShiftLeftEquals: 2142 return parse_assignment_expression(AssignmentOp::LeftShiftAssignment, move(lhs), min_precedence, associativity, forbidden); 2143 case TokenType::ShiftRight: 2144 consume(); 2145 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::RightShift, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2146 case TokenType::ShiftRightEquals: 2147 return parse_assignment_expression(AssignmentOp::RightShiftAssignment, move(lhs), min_precedence, associativity, forbidden); 2148 case TokenType::UnsignedShiftRight: 2149 consume(); 2150 return create_ast_node<BinaryExpression>({ m_source_code, rule_start.position(), position() }, BinaryOp::UnsignedRightShift, move(lhs), parse_expression(min_precedence, associativity, forbidden)); 2151 case TokenType::UnsignedShiftRightEquals: 2152 return parse_assignment_expression(AssignmentOp::UnsignedRightShiftAssignment, move(lhs), min_precedence, associativity, forbidden); 2153 case TokenType::ParenOpen: 2154 return parse_call_expression(move(lhs)); 2155 case TokenType::Equals: 2156 return parse_assignment_expression(AssignmentOp::Assignment, move(lhs), min_precedence, associativity, forbidden); 2157 case TokenType::Period: 2158 consume(); 2159 if (match(TokenType::PrivateIdentifier)) { 2160 if (!is_private_identifier_valid()) 2161 syntax_error(DeprecatedString::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); 2162 else if (is<SuperExpression>(*lhs)) 2163 syntax_error(DeprecatedString::formatted("Cannot access private field or method '{}' on super", m_state.current_token.value())); 2164 2165 return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().value())); 2166 } else if (!match_identifier_name()) { 2167 expected("IdentifierName"); 2168 } 2169 2170 return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, consume().DeprecatedFlyString_value())); 2171 case TokenType::BracketOpen: { 2172 consume(TokenType::BracketOpen); 2173 auto expression = create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), parse_expression(0), true); 2174 consume(TokenType::BracketClose); 2175 return expression; 2176 } 2177 case TokenType::PlusPlus: 2178 if (!is_simple_assignment_target(*lhs)) 2179 syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); 2180 2181 if (m_state.strict_mode && is<Identifier>(*lhs)) { 2182 auto& identifier = static_cast<Identifier const&>(*lhs); 2183 auto& name = identifier.string(); 2184 check_identifier_name_for_assignment_validity(name); 2185 } 2186 2187 consume(); 2188 return create_ast_node<UpdateExpression>({ m_source_code, rule_start.position(), position() }, UpdateOp::Increment, move(lhs)); 2189 case TokenType::MinusMinus: 2190 if (!is_simple_assignment_target(*lhs)) 2191 syntax_error(DeprecatedString::formatted("Left-hand side of postfix increment operator must be identifier or member expression, got {}", lhs->class_name())); 2192 2193 if (m_state.strict_mode && is<Identifier>(*lhs)) { 2194 auto& identifier = static_cast<Identifier const&>(*lhs); 2195 auto& name = identifier.string(); 2196 check_identifier_name_for_assignment_validity(name); 2197 } 2198 consume(); 2199 return create_ast_node<UpdateExpression>({ m_source_code, rule_start.position(), position() }, UpdateOp::Decrement, move(lhs)); 2200 case TokenType::DoubleAmpersand: { 2201 consume(); 2202 auto expression = create_ast_node<LogicalExpression>({ m_source_code, rule_start.position(), position() }, LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity, forbidden.forbid({ TokenType::DoubleQuestionMark }))); 2203 return { expression, { TokenType::DoubleQuestionMark } }; 2204 } 2205 case TokenType::DoubleAmpersandEquals: 2206 return parse_assignment_expression(AssignmentOp::AndAssignment, move(lhs), min_precedence, associativity, forbidden); 2207 case TokenType::DoublePipe: { 2208 consume(); 2209 auto expression = create_ast_node<LogicalExpression>({ m_source_code, rule_start.position(), position() }, LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity, forbidden.forbid({ TokenType::DoubleQuestionMark }))); 2210 return { expression, { TokenType::DoubleQuestionMark } }; 2211 } 2212 case TokenType::DoublePipeEquals: 2213 return parse_assignment_expression(AssignmentOp::OrAssignment, move(lhs), min_precedence, associativity, forbidden); 2214 case TokenType::DoubleQuestionMark: { 2215 consume(); 2216 auto expression = create_ast_node<LogicalExpression>({ m_source_code, rule_start.position(), position() }, LogicalOp::NullishCoalescing, move(lhs), parse_expression(min_precedence, associativity, forbidden.forbid({ TokenType::DoubleAmpersand, TokenType::DoublePipe }))); 2217 return { expression, { TokenType::DoubleAmpersand, TokenType::DoublePipe } }; 2218 } 2219 case TokenType::DoubleQuestionMarkEquals: 2220 return parse_assignment_expression(AssignmentOp::NullishAssignment, move(lhs), min_precedence, associativity, forbidden); 2221 case TokenType::QuestionMark: 2222 return parse_conditional_expression(move(lhs), forbidden); 2223 case TokenType::QuestionMarkPeriod: 2224 // FIXME: This should allow `(new Foo)?.bar', but as our parser strips parenthesis, 2225 // we can't really tell if `lhs' was parenthesized at this point. 2226 if (is<NewExpression>(lhs.ptr())) { 2227 syntax_error("'new' cannot be used with optional chaining", position()); 2228 consume(); 2229 return lhs; 2230 } 2231 return parse_optional_chain(move(lhs)); 2232 default: 2233 expected("secondary expression"); 2234 consume(); 2235 return create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() }); 2236 } 2237} 2238 2239bool Parser::is_private_identifier_valid() const 2240{ 2241 VERIFY(match(TokenType::PrivateIdentifier)); 2242 if (!m_state.referenced_private_names) 2243 return false; 2244 2245 // We might not have hit the declaration yet so class will check this in the end 2246 m_state.referenced_private_names->set(m_state.current_token.value()); 2247 return true; 2248} 2249 2250RefPtr<BindingPattern const> Parser::synthesize_binding_pattern(Expression const& expression) 2251{ 2252 VERIFY(is<ArrayExpression>(expression) || is<ObjectExpression>(expression)); 2253 // Clear any syntax error that has occurred in the range that 'expression' spans. 2254 m_state.errors.remove_all_matching([range = expression.source_range()](auto const& error) { 2255 return error.position.has_value() && range.contains(*error.position); 2256 }); 2257 // Make a parser and parse the source for this expression as a binding pattern. 2258 // NOTE: There's currently a fundamental problem that we pass the *next* (a.k.a. `current_token`) 2259 // token's position to most nodes' SourceRange when using `rule_start.position(), position()`. 2260 // This means that `source` will contain the subsequent token's trivia, if any (which is fine). 2261 auto source_start_offset = expression.source_range().start.offset; 2262 auto source_end_offset = expression.source_range().end.offset; 2263 auto source = m_state.lexer.source().substring_view(source_start_offset, source_end_offset - source_start_offset); 2264 Lexer lexer { source, m_state.lexer.filename(), expression.source_range().start.line, expression.source_range().start.column }; 2265 Parser parser { lexer }; 2266 2267 parser.m_state.strict_mode = m_state.strict_mode; 2268 parser.m_state.allow_super_property_lookup = m_state.allow_super_property_lookup; 2269 parser.m_state.allow_super_constructor_call = m_state.allow_super_constructor_call; 2270 parser.m_state.in_function_context = m_state.in_function_context; 2271 parser.m_state.in_formal_parameter_context = m_state.in_formal_parameter_context; 2272 parser.m_state.in_generator_function_context = m_state.in_generator_function_context; 2273 parser.m_state.await_expression_is_valid = m_state.await_expression_is_valid; 2274 parser.m_state.in_arrow_function_context = m_state.in_arrow_function_context; 2275 parser.m_state.in_break_context = m_state.in_break_context; 2276 parser.m_state.in_continue_context = m_state.in_continue_context; 2277 parser.m_state.string_legacy_octal_escape_sequence_in_scope = m_state.string_legacy_octal_escape_sequence_in_scope; 2278 parser.m_state.in_class_field_initializer = m_state.in_class_field_initializer; 2279 parser.m_state.in_class_static_init_block = m_state.in_class_static_init_block; 2280 parser.m_state.referenced_private_names = m_state.referenced_private_names; 2281 2282 auto result = parser.parse_binding_pattern(AllowDuplicates::Yes, AllowMemberExpressions::Yes); 2283 if (parser.has_errors()) 2284 m_state.errors.extend(parser.errors()); 2285 return result; 2286} 2287 2288NonnullRefPtr<AssignmentExpression const> Parser::parse_assignment_expression(AssignmentOp assignment_op, NonnullRefPtr<Expression const> lhs, int min_precedence, Associativity associativity, ForbiddenTokens forbidden) 2289{ 2290 auto rule_start = push_start(); 2291 VERIFY(match(TokenType::Equals) 2292 || match(TokenType::PlusEquals) 2293 || match(TokenType::MinusEquals) 2294 || match(TokenType::AsteriskEquals) 2295 || match(TokenType::SlashEquals) 2296 || match(TokenType::PercentEquals) 2297 || match(TokenType::DoubleAsteriskEquals) 2298 || match(TokenType::AmpersandEquals) 2299 || match(TokenType::PipeEquals) 2300 || match(TokenType::CaretEquals) 2301 || match(TokenType::ShiftLeftEquals) 2302 || match(TokenType::ShiftRightEquals) 2303 || match(TokenType::UnsignedShiftRightEquals) 2304 || match(TokenType::DoubleAmpersandEquals) 2305 || match(TokenType::DoublePipeEquals) 2306 || match(TokenType::DoubleQuestionMarkEquals)); 2307 consume(); 2308 2309 if (assignment_op == AssignmentOp::Assignment) { 2310 if (is<ArrayExpression>(*lhs) || is<ObjectExpression>(*lhs)) { 2311 auto binding_pattern = synthesize_binding_pattern(*lhs); 2312 if (binding_pattern) { 2313 auto rhs = parse_expression(min_precedence, associativity); 2314 return create_ast_node<AssignmentExpression>( 2315 { m_source_code, rule_start.position(), position() }, 2316 assignment_op, 2317 binding_pattern.release_nonnull(), 2318 move(rhs)); 2319 } 2320 } 2321 } 2322 2323 // Note: The web reality is that all but &&=, ||= and ??= do allow left hand side CallExpresions. 2324 // These are the exception as they are newer. 2325 auto has_web_reality_assignment_target_exceptions = assignment_op != AssignmentOp::AndAssignment 2326 && assignment_op != AssignmentOp::OrAssignment 2327 && assignment_op != AssignmentOp::NullishAssignment; 2328 2329 if (!is_simple_assignment_target(*lhs, has_web_reality_assignment_target_exceptions)) { 2330 syntax_error("Invalid left-hand side in assignment"); 2331 } else if (m_state.strict_mode && is<Identifier>(*lhs)) { 2332 auto const& name = static_cast<Identifier const&>(*lhs).string(); 2333 check_identifier_name_for_assignment_validity(name); 2334 } 2335 auto rhs = parse_expression(min_precedence, associativity, forbidden); 2336 return create_ast_node<AssignmentExpression>({ m_source_code, rule_start.position(), position() }, assignment_op, move(lhs), move(rhs)); 2337} 2338 2339NonnullRefPtr<Identifier const> Parser::parse_identifier() 2340{ 2341 auto identifier_start = position(); 2342 auto token = consume_identifier(); 2343 if (m_state.in_class_field_initializer && token.value() == "arguments"sv) 2344 syntax_error("'arguments' is not allowed in class field initializer"); 2345 return create_ast_node<Identifier>( 2346 { m_source_code, identifier_start, position() }, 2347 token.DeprecatedFlyString_value()); 2348} 2349 2350Vector<CallExpression::Argument> Parser::parse_arguments() 2351{ 2352 Vector<CallExpression::Argument> arguments; 2353 2354 consume(TokenType::ParenOpen); 2355 while (match_expression() || match(TokenType::TripleDot)) { 2356 if (match(TokenType::TripleDot)) { 2357 consume(); 2358 arguments.append({ parse_expression(2), true }); 2359 } else { 2360 arguments.append({ parse_expression(2), false }); 2361 } 2362 if (!match(TokenType::Comma)) 2363 break; 2364 consume(); 2365 } 2366 2367 consume(TokenType::ParenClose); 2368 return arguments; 2369} 2370 2371NonnullRefPtr<Expression const> Parser::parse_call_expression(NonnullRefPtr<Expression const> lhs) 2372{ 2373 auto rule_start = push_start(); 2374 if (!m_state.allow_super_constructor_call && is<SuperExpression>(*lhs)) 2375 syntax_error("'super' keyword unexpected here"); 2376 2377 auto arguments = parse_arguments(); 2378 2379 if (is<SuperExpression>(*lhs)) 2380 return create_ast_node<SuperCall>({ m_source_code, rule_start.position(), position() }, move(arguments)); 2381 2382 return CallExpression::create({ m_source_code, rule_start.position(), position() }, move(lhs), arguments.span()); 2383} 2384 2385NonnullRefPtr<NewExpression const> Parser::parse_new_expression() 2386{ 2387 auto rule_start = push_start(); 2388 consume(TokenType::New); 2389 2390 auto callee = parse_expression(g_operator_precedence.get(TokenType::New), Associativity::Right, { TokenType::ParenOpen, TokenType::QuestionMarkPeriod }); 2391 if (is<ImportCall>(*callee)) 2392 syntax_error("Cannot call new on dynamic import", callee->source_range().start); 2393 2394 Vector<CallExpression::Argument> arguments; 2395 2396 if (match(TokenType::ParenOpen)) { 2397 consume(TokenType::ParenOpen); 2398 while (match_expression() || match(TokenType::TripleDot)) { 2399 if (match(TokenType::TripleDot)) { 2400 consume(); 2401 arguments.append({ parse_expression(2), true }); 2402 } else { 2403 arguments.append({ parse_expression(2), false }); 2404 } 2405 if (!match(TokenType::Comma)) 2406 break; 2407 consume(); 2408 } 2409 consume(TokenType::ParenClose); 2410 } 2411 2412 return NewExpression::create({ m_source_code, rule_start.position(), position() }, move(callee), move(arguments)); 2413} 2414 2415NonnullRefPtr<YieldExpression const> Parser::parse_yield_expression() 2416{ 2417 auto rule_start = push_start(); 2418 2419 if (m_state.in_formal_parameter_context) 2420 syntax_error("'Yield' expression is not allowed in formal parameters of generator function"); 2421 2422 consume(TokenType::Yield); 2423 RefPtr<Expression const> argument; 2424 bool yield_from = false; 2425 2426 if (!m_state.current_token.trivia_contains_line_terminator()) { 2427 if (match(TokenType::Asterisk)) { 2428 consume(); 2429 yield_from = true; 2430 } 2431 2432 if (yield_from || match_expression() || match(TokenType::Class)) 2433 argument = parse_expression(2); 2434 } 2435 2436 return create_ast_node<YieldExpression>({ m_source_code, rule_start.position(), position() }, move(argument), yield_from); 2437} 2438 2439NonnullRefPtr<AwaitExpression const> Parser::parse_await_expression() 2440{ 2441 auto rule_start = push_start(); 2442 2443 if (m_state.in_formal_parameter_context) 2444 syntax_error("'Await' expression is not allowed in formal parameters of an async function"); 2445 2446 consume(TokenType::Await); 2447 2448 auto precedence = g_operator_precedence.get(TokenType::Await); 2449 auto associativity = operator_associativity(TokenType::Await); 2450 auto argument = parse_expression(precedence, associativity); 2451 2452 m_state.current_scope_pusher->set_contains_await_expression(); 2453 2454 return create_ast_node<AwaitExpression>({ m_source_code, rule_start.position(), position() }, move(argument)); 2455} 2456 2457NonnullRefPtr<ReturnStatement const> Parser::parse_return_statement() 2458{ 2459 auto rule_start = push_start(); 2460 if (!m_state.in_function_context && !m_state.in_arrow_function_context) 2461 syntax_error("'return' not allowed outside of a function"); 2462 2463 consume(TokenType::Return); 2464 2465 // Automatic semicolon insertion: terminate statement when return is followed by newline 2466 if (m_state.current_token.trivia_contains_line_terminator()) 2467 return create_ast_node<ReturnStatement>({ m_source_code, rule_start.position(), position() }, nullptr); 2468 2469 if (match_expression()) { 2470 auto expression = parse_expression(0); 2471 consume_or_insert_semicolon(); 2472 return create_ast_node<ReturnStatement>({ m_source_code, rule_start.position(), position() }, move(expression)); 2473 } 2474 2475 consume_or_insert_semicolon(); 2476 return create_ast_node<ReturnStatement>({ m_source_code, rule_start.position(), position() }, nullptr); 2477} 2478 2479void Parser::parse_statement_list(ScopeNode& output_node, AllowLabelledFunction allow_labelled_functions) 2480{ 2481 while (!done()) { 2482 if (match_declaration(AllowUsingDeclaration::Yes)) { 2483 auto declaration = parse_declaration(); 2484 VERIFY(m_state.current_scope_pusher); 2485 m_state.current_scope_pusher->add_declaration(declaration); 2486 output_node.append(move(declaration)); 2487 } else if (match_statement()) { 2488 output_node.append(parse_statement(allow_labelled_functions)); 2489 } else { 2490 break; 2491 } 2492 } 2493 2494 output_node.shrink_to_fit(); 2495} 2496 2497// FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody 2498NonnullRefPtr<FunctionBody const> Parser::parse_function_body(Vector<FunctionParameter> const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval) 2499{ 2500 auto rule_start = push_start(); 2501 auto function_body = create_ast_node<FunctionBody>({ m_source_code, rule_start.position(), position() }); 2502 ScopePusher function_scope = ScopePusher::function_scope(*this, function_body, parameters); // FIXME <- 2503 auto has_use_strict = parse_directive(function_body); 2504 bool previous_strict_mode = m_state.strict_mode; 2505 if (has_use_strict) { 2506 m_state.strict_mode = true; 2507 function_body->set_strict_mode(); 2508 if (!is_simple_parameter_list(parameters)) 2509 syntax_error("Illegal 'use strict' directive in function with non-simple parameter list"); 2510 } else if (previous_strict_mode) { 2511 function_body->set_strict_mode(); 2512 } 2513 2514 parse_statement_list(function_body); 2515 2516 // If we're parsing the function body standalone, e.g. via CreateDynamicFunction, we must have reached EOF here. 2517 // Otherwise, we need a closing curly bracket (which is consumed elsewhere). If we get neither, it's an error. 2518 if (!match(TokenType::Eof) && !match(TokenType::CurlyClose)) 2519 expected(Token::name(TokenType::CurlyClose)); 2520 2521 // If the function contains 'use strict' we need to check the parameters (again). 2522 if (function_body->in_strict_mode() || function_kind != FunctionKind::Normal) { 2523 Vector<StringView> parameter_names; 2524 for (auto& parameter : parameters) { 2525 parameter.binding.visit( 2526 [&](DeprecatedFlyString const& parameter_name) { 2527 check_identifier_name_for_assignment_validity(parameter_name, function_body->in_strict_mode()); 2528 if (function_kind == FunctionKind::Generator && parameter_name == "yield"sv) 2529 syntax_error("Parameter name 'yield' not allowed in this context"); 2530 2531 if (function_kind == FunctionKind::Async && parameter_name == "await"sv) 2532 syntax_error("Parameter name 'await' not allowed in this context"); 2533 2534 for (auto& previous_name : parameter_names) { 2535 if (previous_name == parameter_name) { 2536 syntax_error(DeprecatedString::formatted("Duplicate parameter '{}' not allowed in strict mode", parameter_name)); 2537 } 2538 } 2539 2540 parameter_names.append(parameter_name); 2541 }, 2542 [&](NonnullRefPtr<BindingPattern const> const& binding) { 2543 // NOTE: Nothing in the callback throws an exception. 2544 MUST(binding->for_each_bound_name([&](auto& bound_name) { 2545 if (function_kind == FunctionKind::Generator && bound_name == "yield"sv) 2546 syntax_error("Parameter name 'yield' not allowed in this context"); 2547 2548 if (function_kind == FunctionKind::Async && bound_name == "await"sv) 2549 syntax_error("Parameter name 'await' not allowed in this context"); 2550 2551 for (auto& previous_name : parameter_names) { 2552 if (previous_name == bound_name) { 2553 syntax_error(DeprecatedString::formatted("Duplicate parameter '{}' not allowed in strict mode", bound_name)); 2554 break; 2555 } 2556 } 2557 parameter_names.append(bound_name); 2558 })); 2559 }); 2560 } 2561 } 2562 2563 m_state.strict_mode = previous_strict_mode; 2564 contains_direct_call_to_eval = function_scope.contains_direct_call_to_eval(); 2565 return function_body; 2566} 2567 2568NonnullRefPtr<BlockStatement const> Parser::parse_block_statement() 2569{ 2570 auto rule_start = push_start(); 2571 auto block = create_ast_node<BlockStatement>({ m_source_code, rule_start.position(), position() }); 2572 ScopePusher block_scope = ScopePusher::block_scope(*this, block); 2573 consume(TokenType::CurlyOpen); 2574 parse_statement_list(block); 2575 consume(TokenType::CurlyClose); 2576 2577 return block; 2578} 2579 2580template<typename FunctionNodeType> 2581NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(u16 parse_options, Optional<Position> const& function_start) 2582{ 2583 auto rule_start = function_start.has_value() 2584 ? RulePosition { *this, *function_start } 2585 : push_start(); 2586 VERIFY(!(parse_options & FunctionNodeParseOptions::IsGetterFunction && parse_options & FunctionNodeParseOptions::IsSetterFunction)); 2587 2588 TemporaryChange super_property_access_rollback(m_state.allow_super_property_lookup, !!(parse_options & FunctionNodeParseOptions::AllowSuperPropertyLookup)); 2589 TemporaryChange super_constructor_call_rollback(m_state.allow_super_constructor_call, !!(parse_options & FunctionNodeParseOptions::AllowSuperConstructorCall)); 2590 TemporaryChange break_context_rollback(m_state.in_break_context, false); 2591 TemporaryChange continue_context_rollback(m_state.in_continue_context, false); 2592 TemporaryChange class_field_initializer_rollback(m_state.in_class_field_initializer, false); 2593 TemporaryChange might_need_arguments_object_rollback(m_state.function_might_need_arguments_object, false); 2594 2595 constexpr auto is_function_expression = IsSame<FunctionNodeType, FunctionExpression>; 2596 FunctionKind function_kind; 2597 if ((parse_options & FunctionNodeParseOptions::IsGeneratorFunction) != 0 && (parse_options & FunctionNodeParseOptions::IsAsyncFunction) != 0) 2598 function_kind = FunctionKind::AsyncGenerator; 2599 else if ((parse_options & FunctionNodeParseOptions::IsGeneratorFunction) != 0) 2600 function_kind = FunctionKind::Generator; 2601 else if ((parse_options & FunctionNodeParseOptions::IsAsyncFunction) != 0) 2602 function_kind = FunctionKind::Async; 2603 else 2604 function_kind = FunctionKind::Normal; 2605 DeprecatedFlyString name; 2606 if (parse_options & FunctionNodeParseOptions::CheckForFunctionAndName) { 2607 if (function_kind == FunctionKind::Normal && match(TokenType::Async) && !next_token().trivia_contains_line_terminator()) { 2608 function_kind = FunctionKind::Async; 2609 consume(TokenType::Async); 2610 parse_options |= FunctionNodeParseOptions::IsAsyncFunction; 2611 } 2612 consume(TokenType::Function); 2613 if (match(TokenType::Asterisk)) { 2614 function_kind = function_kind == FunctionKind::Normal ? FunctionKind::Generator : FunctionKind::AsyncGenerator; 2615 consume(TokenType::Asterisk); 2616 parse_options |= FunctionNodeParseOptions::IsGeneratorFunction; 2617 } 2618 2619 if (parse_options & FunctionNodeParseOptions::HasDefaultExportName) 2620 name = ExportStatement::local_name_for_default; 2621 else if (FunctionNodeType::must_have_name() || match_identifier()) 2622 name = consume_identifier().DeprecatedFlyString_value(); 2623 else if (is_function_expression && (match(TokenType::Yield) || match(TokenType::Await))) 2624 name = consume().DeprecatedFlyString_value(); 2625 2626 check_identifier_name_for_assignment_validity(name); 2627 2628 if (function_kind == FunctionKind::AsyncGenerator && (name == "await"sv || name == "yield"sv)) 2629 syntax_error(DeprecatedString::formatted("async generator function is not allowed to be called '{}'", name)); 2630 2631 if (m_state.in_class_static_init_block && name == "await"sv) 2632 syntax_error("'await' is a reserved word"); 2633 } 2634 TemporaryChange class_static_initializer_rollback(m_state.in_class_static_init_block, false); 2635 TemporaryChange generator_change(m_state.in_generator_function_context, function_kind == FunctionKind::Generator || function_kind == FunctionKind::AsyncGenerator); 2636 TemporaryChange async_change(m_state.await_expression_is_valid, function_kind == FunctionKind::Async || function_kind == FunctionKind::AsyncGenerator); 2637 2638 consume(TokenType::ParenOpen); 2639 i32 function_length = -1; 2640 auto parameters = parse_formal_parameters(function_length, parse_options); 2641 consume(TokenType::ParenClose); 2642 2643 if (function_length == -1) 2644 function_length = parameters.size(); 2645 2646 TemporaryChange function_context_rollback(m_state.in_function_context, true); 2647 2648 auto old_labels_in_scope = move(m_state.labels_in_scope); 2649 ScopeGuard guard([&]() { 2650 m_state.labels_in_scope = move(old_labels_in_scope); 2651 }); 2652 2653 consume(TokenType::CurlyOpen); 2654 bool contains_direct_call_to_eval = false; 2655 auto body = parse_function_body(parameters, function_kind, contains_direct_call_to_eval); 2656 consume(TokenType::CurlyClose); 2657 2658 auto has_strict_directive = body->in_strict_mode(); 2659 2660 if (has_strict_directive) 2661 check_identifier_name_for_assignment_validity(name, true); 2662 2663 auto function_start_offset = rule_start.position().offset; 2664 auto function_end_offset = position().offset - m_state.current_token.trivia().length(); 2665 auto source_text = DeprecatedString { m_state.lexer.source().substring_view(function_start_offset, function_end_offset - function_start_offset) }; 2666 return create_ast_node<FunctionNodeType>( 2667 { m_source_code, rule_start.position(), position() }, 2668 name, move(source_text), move(body), move(parameters), function_length, 2669 function_kind, has_strict_directive, m_state.function_might_need_arguments_object, 2670 contains_direct_call_to_eval); 2671} 2672 2673Vector<FunctionParameter> Parser::parse_formal_parameters(int& function_length, u16 parse_options) 2674{ 2675 auto rule_start = push_start(); 2676 bool has_default_parameter = false; 2677 bool has_rest_parameter = false; 2678 TemporaryChange formal_parameter_context_change { m_state.in_formal_parameter_context, true }; 2679 2680 Vector<FunctionParameter> parameters; 2681 2682 auto consume_identifier_or_binding_pattern = [&]() -> Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> { 2683 if (auto pattern = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No)) 2684 return pattern.release_nonnull(); 2685 2686 auto token = consume_identifier(); 2687 auto parameter_name = token.DeprecatedFlyString_value(); 2688 2689 check_identifier_name_for_assignment_validity(parameter_name); 2690 2691 for (auto& parameter : parameters) { 2692 bool has_same_name = parameter.binding.visit( 2693 [&](DeprecatedFlyString const& name) { 2694 return name == parameter_name; 2695 }, 2696 [&](NonnullRefPtr<BindingPattern const> const& bindings) { 2697 bool found_duplicate = false; 2698 // NOTE: Nothing in the callback throws an exception. 2699 MUST(bindings->for_each_bound_name([&](auto& bound_name) { 2700 if (bound_name == parameter_name) 2701 found_duplicate = true; 2702 })); 2703 return found_duplicate; 2704 }); 2705 2706 if (!has_same_name) 2707 continue; 2708 2709 DeprecatedString message; 2710 if (parse_options & FunctionNodeParseOptions::IsArrowFunction) 2711 message = DeprecatedString::formatted("Duplicate parameter '{}' not allowed in arrow function", parameter_name); 2712 else if (m_state.strict_mode) 2713 message = DeprecatedString::formatted("Duplicate parameter '{}' not allowed in strict mode", parameter_name); 2714 else if (has_default_parameter || match(TokenType::Equals)) 2715 message = DeprecatedString::formatted("Duplicate parameter '{}' not allowed in function with default parameter", parameter_name); 2716 else if (has_rest_parameter) 2717 message = DeprecatedString::formatted("Duplicate parameter '{}' not allowed in function with rest parameter", parameter_name); 2718 if (!message.is_empty()) 2719 syntax_error(message, Position { token.line_number(), token.line_column() }); 2720 break; 2721 } 2722 return DeprecatedFlyString { token.value() }; 2723 }; 2724 2725 while (match(TokenType::CurlyOpen) || match(TokenType::BracketOpen) || match_identifier() || match(TokenType::TripleDot)) { 2726 if (parse_options & FunctionNodeParseOptions::IsGetterFunction) 2727 syntax_error("Getter function must have no arguments"); 2728 if (parse_options & FunctionNodeParseOptions::IsSetterFunction && (parameters.size() >= 1 || match(TokenType::TripleDot))) 2729 syntax_error("Setter function must have one argument"); 2730 auto is_rest = false; 2731 if (match(TokenType::TripleDot)) { 2732 consume(); 2733 has_rest_parameter = true; 2734 function_length = parameters.size(); 2735 is_rest = true; 2736 } 2737 auto parameter = consume_identifier_or_binding_pattern(); 2738 RefPtr<Expression const> default_value; 2739 if (match(TokenType::Equals)) { 2740 consume(); 2741 2742 if (is_rest) 2743 syntax_error("Rest parameter may not have a default initializer"); 2744 2745 TemporaryChange change(m_state.in_function_context, true); 2746 has_default_parameter = true; 2747 function_length = parameters.size(); 2748 default_value = parse_expression(2); 2749 2750 bool is_generator = parse_options & FunctionNodeParseOptions::IsGeneratorFunction; 2751 if ((is_generator || m_state.strict_mode) && default_value && default_value->fast_is<Identifier>() && static_cast<Identifier const&>(*default_value).string() == "yield"sv) 2752 syntax_error("Generator function parameter initializer cannot contain a reference to an identifier named \"yield\""); 2753 } 2754 parameters.append({ move(parameter), default_value, is_rest }); 2755 if (!match(TokenType::Comma) || is_rest) 2756 break; 2757 consume(TokenType::Comma); 2758 } 2759 if (parse_options & FunctionNodeParseOptions::IsSetterFunction && parameters.is_empty()) 2760 syntax_error("Setter function must have one argument"); 2761 // If we're parsing the parameters standalone, e.g. via CreateDynamicFunction, we must have reached EOF here. 2762 // Otherwise, we need a closing parenthesis (which is consumed elsewhere). If we get neither, it's an error. 2763 if (!match(TokenType::Eof) && !match(TokenType::ParenClose)) 2764 expected(Token::name(TokenType::ParenClose)); 2765 2766 parameters.shrink_to_fit(); 2767 return parameters; 2768} 2769 2770static AK::Array<DeprecatedFlyString, 36> s_reserved_words = { "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true", "try", "typeof", "var", "void", "while", "with" }; 2771 2772RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicates allow_duplicates, Parser::AllowMemberExpressions allow_member_expressions) 2773{ 2774 auto rule_start = push_start(); 2775 2776 TokenType closing_token; 2777 bool is_object = true; 2778 2779 if (match(TokenType::BracketOpen)) { 2780 consume(); 2781 closing_token = TokenType::BracketClose; 2782 is_object = false; 2783 } else if (match(TokenType::CurlyOpen)) { 2784 consume(); 2785 closing_token = TokenType::CurlyClose; 2786 } else { 2787 return {}; 2788 } 2789 2790 Vector<BindingPattern::BindingEntry> entries; 2791 2792 while (!match(closing_token)) { 2793 if (!is_object && match(TokenType::Comma)) { 2794 consume(); 2795 entries.append(BindingPattern::BindingEntry {}); 2796 continue; 2797 } 2798 2799 auto is_rest = false; 2800 2801 if (match(TokenType::TripleDot)) { 2802 consume(); 2803 is_rest = true; 2804 } 2805 2806 decltype(BindingPattern::BindingEntry::name) name = Empty {}; 2807 decltype(BindingPattern::BindingEntry::alias) alias = Empty {}; 2808 RefPtr<Expression const> initializer = {}; 2809 2810 if (is_object) { 2811 bool needs_alias = false; 2812 if (allow_member_expressions == AllowMemberExpressions::Yes && is_rest) { 2813 auto expression_position = position(); 2814 auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals }); 2815 if (is<MemberExpression>(*expression)) 2816 alias = static_ptr_cast<MemberExpression const>(expression); 2817 else if (is<Identifier>(*expression)) 2818 name = static_ptr_cast<Identifier const>(expression); 2819 else 2820 syntax_error("Invalid destructuring assignment target", expression_position); 2821 } else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) { 2822 if (match(TokenType::StringLiteral) || match(TokenType::NumericLiteral)) 2823 needs_alias = true; 2824 2825 if (match(TokenType::StringLiteral)) { 2826 auto token = consume(TokenType::StringLiteral); 2827 auto string_literal = parse_string_literal(token); 2828 2829 name = create_ast_node<Identifier const>( 2830 { m_source_code, rule_start.position(), position() }, 2831 string_literal->value()); 2832 } else if (match(TokenType::BigIntLiteral)) { 2833 auto string_value = consume().DeprecatedFlyString_value(); 2834 VERIFY(string_value.ends_with("n"sv)); 2835 name = create_ast_node<Identifier const>( 2836 { m_source_code, rule_start.position(), position() }, 2837 DeprecatedFlyString(string_value.view().substring_view(0, string_value.length() - 1))); 2838 } else { 2839 name = create_ast_node<Identifier const>( 2840 { m_source_code, rule_start.position(), position() }, 2841 consume().DeprecatedFlyString_value()); 2842 } 2843 } else if (match(TokenType::BracketOpen)) { 2844 consume(); 2845 auto expression = parse_expression(0); 2846 2847 name = move(expression); 2848 consume(TokenType::BracketClose); 2849 } else { 2850 expected("identifier or computed property name"); 2851 return {}; 2852 } 2853 2854 if (!is_rest && match(TokenType::Colon)) { 2855 consume(); 2856 if (allow_member_expressions == AllowMemberExpressions::Yes) { 2857 auto expression_position = position(); 2858 auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals }); 2859 if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) { 2860 if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression)) 2861 alias = synthesized_binding_pattern.release_nonnull(); 2862 else 2863 syntax_error("Invalid destructuring assignment target", expression_position); 2864 } else if (is<MemberExpression>(*expression)) { 2865 alias = static_ptr_cast<MemberExpression const>(expression); 2866 } else if (is<Identifier>(*expression)) { 2867 alias = static_ptr_cast<Identifier const>(expression); 2868 } else { 2869 syntax_error("Invalid destructuring assignment target", expression_position); 2870 } 2871 } else if (match(TokenType::CurlyOpen) || match(TokenType::BracketOpen)) { 2872 auto binding_pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions); 2873 if (!binding_pattern) 2874 return {}; 2875 alias = binding_pattern.release_nonnull(); 2876 } else if (match_identifier_name()) { 2877 alias = create_ast_node<Identifier const>( 2878 { m_source_code, rule_start.position(), position() }, 2879 consume().DeprecatedFlyString_value()); 2880 2881 } else { 2882 expected("identifier or binding pattern"); 2883 return {}; 2884 } 2885 } else if (needs_alias) { 2886 expected("alias for string or numeric literal name"); 2887 return {}; 2888 } 2889 } else { 2890 if (allow_member_expressions == AllowMemberExpressions::Yes) { 2891 auto expression_position = position(); 2892 auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals }); 2893 2894 if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) { 2895 if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression)) 2896 alias = synthesized_binding_pattern.release_nonnull(); 2897 else 2898 syntax_error("Invalid destructuring assignment target", expression_position); 2899 } else if (is<MemberExpression>(*expression)) { 2900 alias = static_ptr_cast<MemberExpression const>(expression); 2901 } else if (is<Identifier>(*expression)) { 2902 alias = static_ptr_cast<Identifier const>(expression); 2903 } else { 2904 syntax_error("Invalid destructuring assignment target", expression_position); 2905 } 2906 } else if (match(TokenType::BracketOpen) || match(TokenType::CurlyOpen)) { 2907 auto pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions); 2908 if (!pattern) { 2909 expected("binding pattern"); 2910 return {}; 2911 } 2912 alias = pattern.release_nonnull(); 2913 } else if (match_identifier_name()) { 2914 // BindingElement must always have an Empty name field 2915 auto identifier_name = consume_identifier().DeprecatedFlyString_value(); 2916 alias = create_ast_node<Identifier const>( 2917 { m_source_code, rule_start.position(), position() }, 2918 identifier_name); 2919 } else { 2920 expected("identifier or binding pattern"); 2921 return {}; 2922 } 2923 } 2924 2925 if (match(TokenType::Equals)) { 2926 if (is_rest) { 2927 syntax_error("Unexpected initializer after rest element"); 2928 return {}; 2929 } 2930 2931 consume(); 2932 2933 initializer = parse_expression(2); 2934 if (!initializer) { 2935 expected("initialization expression"); 2936 return {}; 2937 } 2938 } 2939 2940 entries.append(BindingPattern::BindingEntry { move(name), move(alias), move(initializer), is_rest }); 2941 2942 if (match(TokenType::Comma)) { 2943 if (is_rest) { 2944 syntax_error("Rest element may not be followed by a comma"); 2945 return {}; 2946 } 2947 consume(); 2948 } else if (is_object && !match(TokenType::CurlyClose)) { 2949 consume(TokenType::Comma); 2950 } 2951 } 2952 2953 while (!is_object && match(TokenType::Comma)) 2954 consume(); 2955 2956 consume(closing_token); 2957 2958 auto kind = is_object ? BindingPattern::Kind::Object : BindingPattern::Kind::Array; 2959 auto pattern = adopt_ref(*new BindingPattern); 2960 pattern->entries = move(entries); 2961 pattern->kind = kind; 2962 2963 Vector<StringView> bound_names; 2964 // NOTE: Nothing in the callback throws an exception. 2965 MUST(pattern->for_each_bound_name([&](auto& name) { 2966 if (allow_duplicates == AllowDuplicates::No) { 2967 if (bound_names.contains_slow(name)) 2968 syntax_error("Duplicate parameter names in bindings"); 2969 bound_names.append(name); 2970 } 2971 check_identifier_name_for_assignment_validity(name); 2972 })); 2973 2974 return pattern; 2975} 2976 2977RefPtr<Identifier const> Parser::parse_lexical_binding() 2978{ 2979 auto binding_start = push_start(); 2980 2981 if (match_identifier()) { 2982 auto name = consume_identifier().DeprecatedFlyString_value(); 2983 return create_ast_node<Identifier>( 2984 { m_source_code, binding_start.position(), position() }, 2985 name); 2986 } 2987 if (!m_state.in_generator_function_context && match(TokenType::Yield)) { 2988 if (m_state.strict_mode) 2989 syntax_error("Identifier must not be a reserved word in strict mode ('yield')"); 2990 2991 return create_ast_node<Identifier>( 2992 { m_source_code, binding_start.position(), position() }, 2993 consume().DeprecatedFlyString_value()); 2994 } 2995 if (!m_state.await_expression_is_valid && match(TokenType::Async)) { 2996 if (m_program_type == Program::Type::Module) 2997 syntax_error("Identifier must not be a reserved word in modules ('async')"); 2998 2999 return create_ast_node<Identifier>( 3000 { m_source_code, binding_start.position(), position() }, 3001 consume().DeprecatedFlyString_value()); 3002 } 3003 3004 return {}; 3005} 3006 3007NonnullRefPtr<VariableDeclaration const> Parser::parse_variable_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration) 3008{ 3009 auto rule_start = push_start(); 3010 DeclarationKind declaration_kind; 3011 3012 switch (m_state.current_token.type()) { 3013 case TokenType::Var: 3014 declaration_kind = DeclarationKind::Var; 3015 break; 3016 case TokenType::Let: 3017 declaration_kind = DeclarationKind::Let; 3018 break; 3019 case TokenType::Const: 3020 declaration_kind = DeclarationKind::Const; 3021 break; 3022 default: 3023 VERIFY_NOT_REACHED(); 3024 } 3025 consume(); 3026 3027 Vector<NonnullRefPtr<VariableDeclarator const>> declarations; 3028 for (;;) { 3029 Variant<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>, Empty> target {}; 3030 if (auto pattern = parse_binding_pattern(declaration_kind != DeclarationKind::Var ? AllowDuplicates::No : AllowDuplicates::Yes, AllowMemberExpressions::No)) { 3031 if ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const)) { 3032 // NOTE: Nothing in the callback throws an exception. 3033 MUST(pattern->for_each_bound_name([this](auto& name) { 3034 if (name == "let"sv) 3035 syntax_error("Lexical binding may not be called 'let'"); 3036 })); 3037 } 3038 3039 target = pattern.release_nonnull(); 3040 } else if (auto lexical_binding = parse_lexical_binding()) { 3041 check_identifier_name_for_assignment_validity(lexical_binding->string()); 3042 if ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const) && lexical_binding->string() == "let"sv) 3043 syntax_error("Lexical binding may not be called 'let'"); 3044 3045 target = lexical_binding.release_nonnull(); 3046 } 3047 3048 if (target.has<Empty>()) { 3049 expected("identifier or a binding pattern"); 3050 if (match(TokenType::Comma)) { 3051 consume(); 3052 continue; 3053 } 3054 break; 3055 } 3056 3057 RefPtr<Expression const> init; 3058 if (match(TokenType::Equals)) { 3059 consume(); 3060 // In a for loop 'in' can be ambiguous so we do not allow it 3061 // 14.7.4 The for Statement, https://tc39.es/ecma262/#prod-ForStatement and 14.7.5 The for-in, for-of, and for-await-of Statements, https://tc39.es/ecma262/#prod-ForInOfStatement 3062 if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::Yes) 3063 init = parse_expression(2, Associativity::Right, { TokenType::In }); 3064 else 3065 init = parse_expression(2); 3066 } else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && declaration_kind == DeclarationKind::Const) { 3067 syntax_error("Missing initializer in 'const' variable declaration"); 3068 } else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No && target.has<NonnullRefPtr<BindingPattern const>>()) { 3069 syntax_error("Missing initializer in destructuring assignment"); 3070 } 3071 3072 declarations.append(create_ast_node<VariableDeclarator>( 3073 { m_source_code, rule_start.position(), position() }, 3074 move(target).downcast<NonnullRefPtr<Identifier const>, NonnullRefPtr<BindingPattern const>>(), 3075 move(init))); 3076 3077 if (match(TokenType::Comma)) { 3078 consume(); 3079 continue; 3080 } 3081 break; 3082 } 3083 if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No) 3084 consume_or_insert_semicolon(); 3085 3086 declarations.shrink_to_fit(); 3087 3088 auto declaration = create_ast_node<VariableDeclaration>({ m_source_code, rule_start.position(), position() }, declaration_kind, move(declarations)); 3089 return declaration; 3090} 3091 3092NonnullRefPtr<UsingDeclaration const> Parser::parse_using_declaration(IsForLoopVariableDeclaration is_for_loop_variable_declaration) 3093{ 3094 // using [no LineTerminator here] BindingList[?In, ?Yield, ?Await, +Using] ; 3095 auto rule_start = push_start(); 3096 VERIFY(m_state.current_token.original_value() == "using"sv); 3097 consume(TokenType::Identifier); 3098 VERIFY(!m_state.current_token.trivia_contains_line_terminator()); 3099 Vector<NonnullRefPtr<VariableDeclarator const>> declarations; 3100 3101 for (;;) { 3102 auto lexical_binding = parse_lexical_binding(); 3103 if (!lexical_binding) { 3104 expected("lexical binding"); 3105 break; 3106 } 3107 3108 check_identifier_name_for_assignment_validity(lexical_binding->string()); 3109 if (lexical_binding->string() == "let"sv) 3110 syntax_error("Lexical binding may not be called 'let'"); 3111 3112 RefPtr<Expression const> initializer; 3113 if (match(TokenType::Equals)) { 3114 consume(); 3115 3116 if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::Yes) 3117 initializer = parse_expression(2, Associativity::Right, { TokenType::In }); 3118 else 3119 initializer = parse_expression(2); 3120 } else if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No) { 3121 consume(TokenType::Equals); 3122 } 3123 3124 declarations.append(create_ast_node<VariableDeclarator>( 3125 { m_source_code, rule_start.position(), position() }, 3126 lexical_binding.release_nonnull(), 3127 move(initializer))); 3128 3129 if (match(TokenType::Comma)) { 3130 consume(); 3131 continue; 3132 } 3133 break; 3134 } 3135 if (is_for_loop_variable_declaration == IsForLoopVariableDeclaration::No) 3136 consume_or_insert_semicolon(); 3137 3138 return create_ast_node<UsingDeclaration>({ m_source_code, rule_start.position(), position() }, move(declarations)); 3139} 3140 3141NonnullRefPtr<ThrowStatement const> Parser::parse_throw_statement() 3142{ 3143 auto rule_start = push_start(); 3144 consume(TokenType::Throw); 3145 3146 // Automatic semicolon insertion: terminate statement when throw is followed by newline 3147 if (m_state.current_token.trivia_contains_line_terminator()) { 3148 syntax_error("No line break is allowed between 'throw' and its expression"); 3149 return create_ast_node<ThrowStatement>({ m_source_code, rule_start.position(), position() }, create_ast_node<ErrorExpression>({ m_source_code, rule_start.position(), position() })); 3150 } 3151 3152 auto expression = parse_expression(0); 3153 consume_or_insert_semicolon(); 3154 return create_ast_node<ThrowStatement>({ m_source_code, rule_start.position(), position() }, move(expression)); 3155} 3156 3157NonnullRefPtr<BreakStatement const> Parser::parse_break_statement() 3158{ 3159 auto rule_start = push_start(); 3160 consume(TokenType::Break); 3161 DeprecatedFlyString target_label; 3162 if (match(TokenType::Semicolon)) { 3163 consume(); 3164 } else { 3165 if (!m_state.current_token.trivia_contains_line_terminator() && match_identifier()) { 3166 target_label = consume().value(); 3167 3168 auto label = m_state.labels_in_scope.find(target_label); 3169 if (label == m_state.labels_in_scope.end()) 3170 syntax_error(DeprecatedString::formatted("Label '{}' not found", target_label)); 3171 } 3172 consume_or_insert_semicolon(); 3173 } 3174 3175 if (target_label.is_null() && !m_state.in_break_context) 3176 syntax_error("Unlabeled 'break' not allowed outside of a loop or switch statement"); 3177 3178 return create_ast_node<BreakStatement>({ m_source_code, rule_start.position(), position() }, target_label); 3179} 3180 3181NonnullRefPtr<ContinueStatement const> Parser::parse_continue_statement() 3182{ 3183 auto rule_start = push_start(); 3184 if (!m_state.in_continue_context) 3185 syntax_error("'continue' not allow outside of a loop"); 3186 3187 consume(TokenType::Continue); 3188 DeprecatedFlyString target_label; 3189 if (match(TokenType::Semicolon)) { 3190 consume(); 3191 return create_ast_node<ContinueStatement>({ m_source_code, rule_start.position(), position() }, target_label); 3192 } 3193 if (!m_state.current_token.trivia_contains_line_terminator() && match_identifier()) { 3194 auto label_position = position(); 3195 target_label = consume().value(); 3196 3197 auto label = m_state.labels_in_scope.find(target_label); 3198 if (label == m_state.labels_in_scope.end()) 3199 syntax_error(DeprecatedString::formatted("Label '{}' not found or invalid", target_label)); 3200 else 3201 label->value = label_position; 3202 } 3203 consume_or_insert_semicolon(); 3204 return create_ast_node<ContinueStatement>({ m_source_code, rule_start.position(), position() }, target_label); 3205} 3206 3207NonnullRefPtr<ConditionalExpression const> Parser::parse_conditional_expression(NonnullRefPtr<Expression const> test, ForbiddenTokens forbidden) 3208{ 3209 auto rule_start = push_start(); 3210 consume(TokenType::QuestionMark); 3211 auto consequent = parse_expression(2); 3212 consume(TokenType::Colon); 3213 auto alternate = parse_expression(2, Associativity::Right, forbidden); 3214 return create_ast_node<ConditionalExpression>({ m_source_code, rule_start.position(), position() }, move(test), move(consequent), move(alternate)); 3215} 3216 3217NonnullRefPtr<OptionalChain const> Parser::parse_optional_chain(NonnullRefPtr<Expression const> base) 3218{ 3219 auto rule_start = push_start(); 3220 Vector<OptionalChain::Reference> chain; 3221 do { 3222 if (match(TokenType::QuestionMarkPeriod)) { 3223 consume(TokenType::QuestionMarkPeriod); 3224 switch (m_state.current_token.type()) { 3225 case TokenType::ParenOpen: 3226 chain.append(OptionalChain::Call { parse_arguments(), OptionalChain::Mode::Optional }); 3227 break; 3228 case TokenType::BracketOpen: 3229 consume(); 3230 chain.append(OptionalChain::ComputedReference { parse_expression(0), OptionalChain::Mode::Optional }); 3231 consume(TokenType::BracketClose); 3232 break; 3233 case TokenType::PrivateIdentifier: { 3234 if (!is_private_identifier_valid()) 3235 syntax_error(DeprecatedString::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); 3236 3237 auto start = position(); 3238 auto private_identifier = consume(); 3239 chain.append(OptionalChain::PrivateMemberReference { 3240 create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.value()), 3241 OptionalChain::Mode::Optional }); 3242 break; 3243 } 3244 case TokenType::TemplateLiteralStart: 3245 // 13.3.1.1 - Static Semantics: Early Errors 3246 // OptionalChain : 3247 // ?. TemplateLiteral 3248 // OptionalChain TemplateLiteral 3249 // This is a hard error. 3250 syntax_error("Invalid tagged template literal after ?.", position()); 3251 break; 3252 default: 3253 if (match_identifier_name()) { 3254 auto start = position(); 3255 auto identifier = consume(); 3256 chain.append(OptionalChain::MemberReference { 3257 create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.DeprecatedFlyString_value()), 3258 OptionalChain::Mode::Optional, 3259 }); 3260 } else { 3261 syntax_error("Invalid optional chain reference after ?.", position()); 3262 } 3263 break; 3264 } 3265 } else if (match(TokenType::ParenOpen)) { 3266 chain.append(OptionalChain::Call { parse_arguments(), OptionalChain::Mode::NotOptional }); 3267 } else if (match(TokenType::Period)) { 3268 consume(); 3269 if (match(TokenType::PrivateIdentifier)) { 3270 if (!is_private_identifier_valid()) 3271 syntax_error(DeprecatedString::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); 3272 3273 auto start = position(); 3274 auto private_identifier = consume(); 3275 chain.append(OptionalChain::PrivateMemberReference { 3276 create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.value()), 3277 OptionalChain::Mode::NotOptional, 3278 }); 3279 } else if (match_identifier_name()) { 3280 auto start = position(); 3281 auto identifier = consume(); 3282 chain.append(OptionalChain::MemberReference { 3283 create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.DeprecatedFlyString_value()), 3284 OptionalChain::Mode::NotOptional, 3285 }); 3286 } else { 3287 expected("an identifier"); 3288 break; 3289 } 3290 } else if (match(TokenType::TemplateLiteralStart)) { 3291 // 13.3.1.1 - Static Semantics: Early Errors 3292 // OptionalChain : 3293 // ?. TemplateLiteral 3294 // OptionalChain TemplateLiteral 3295 syntax_error("Invalid tagged template literal after optional chain", position()); 3296 break; 3297 } else if (match(TokenType::BracketOpen)) { 3298 consume(); 3299 chain.append(OptionalChain::ComputedReference { parse_expression(2), OptionalChain::Mode::NotOptional }); 3300 consume(TokenType::BracketClose); 3301 } else { 3302 break; 3303 } 3304 } while (!done()); 3305 3306 return create_ast_node<OptionalChain>( 3307 { m_source_code, rule_start.position(), position() }, 3308 move(base), 3309 move(chain)); 3310} 3311 3312NonnullRefPtr<TryStatement const> Parser::parse_try_statement() 3313{ 3314 auto rule_start = push_start(); 3315 consume(TokenType::Try); 3316 3317 auto block = parse_block_statement(); 3318 3319 RefPtr<CatchClause const> handler; 3320 if (match(TokenType::Catch)) 3321 handler = parse_catch_clause(); 3322 3323 RefPtr<BlockStatement const> finalizer; 3324 if (match(TokenType::Finally)) { 3325 consume(); 3326 finalizer = parse_block_statement(); 3327 } 3328 3329 if (!handler && !finalizer) 3330 syntax_error("try statement must have a 'catch' or 'finally' clause"); 3331 3332 return create_ast_node<TryStatement>({ m_source_code, rule_start.position(), position() }, move(block), move(handler), move(finalizer)); 3333} 3334 3335NonnullRefPtr<DoWhileStatement const> Parser::parse_do_while_statement() 3336{ 3337 auto rule_start = push_start(); 3338 consume(TokenType::Do); 3339 3340 auto body = [&]() -> NonnullRefPtr<Statement const> { 3341 TemporaryChange break_change(m_state.in_break_context, true); 3342 TemporaryChange continue_change(m_state.in_continue_context, true); 3343 return parse_statement(); 3344 }(); 3345 3346 consume(TokenType::While); 3347 consume(TokenType::ParenOpen); 3348 3349 auto test = parse_expression(0); 3350 3351 consume(TokenType::ParenClose); 3352 3353 // Since ES 2015 a missing semicolon is inserted here, despite the regular ASI rules not applying 3354 if (match(TokenType::Semicolon)) 3355 consume(); 3356 3357 return create_ast_node<DoWhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body)); 3358} 3359 3360NonnullRefPtr<WhileStatement const> Parser::parse_while_statement() 3361{ 3362 auto rule_start = push_start(); 3363 consume(TokenType::While); 3364 consume(TokenType::ParenOpen); 3365 3366 auto test = parse_expression(0); 3367 3368 consume(TokenType::ParenClose); 3369 3370 TemporaryChange break_change(m_state.in_break_context, true); 3371 TemporaryChange continue_change(m_state.in_continue_context, true); 3372 auto body = parse_statement(); 3373 3374 return create_ast_node<WhileStatement>({ m_source_code, rule_start.position(), position() }, move(test), move(body)); 3375} 3376 3377NonnullRefPtr<SwitchStatement const> Parser::parse_switch_statement() 3378{ 3379 auto rule_start = push_start(); 3380 consume(TokenType::Switch); 3381 3382 consume(TokenType::ParenOpen); 3383 auto determinant = parse_expression(0); 3384 consume(TokenType::ParenClose); 3385 3386 consume(TokenType::CurlyOpen); 3387 3388 Vector<NonnullRefPtr<SwitchCase>> cases; 3389 3390 auto switch_statement = create_ast_node<SwitchStatement>({ m_source_code, rule_start.position(), position() }, move(determinant)); 3391 3392 ScopePusher switch_scope = ScopePusher::block_scope(*this, switch_statement); 3393 3394 auto has_default = false; 3395 while (match(TokenType::Case) || match(TokenType::Default)) { 3396 if (match(TokenType::Default)) { 3397 if (has_default) 3398 syntax_error("Multiple 'default' clauses in switch statement"); 3399 has_default = true; 3400 } 3401 switch_statement->add_case(parse_switch_case()); 3402 } 3403 3404 consume(TokenType::CurlyClose); 3405 3406 return switch_statement; 3407} 3408 3409NonnullRefPtr<WithStatement const> Parser::parse_with_statement() 3410{ 3411 auto rule_start = push_start(); 3412 consume(TokenType::With); 3413 consume(TokenType::ParenOpen); 3414 3415 auto object = parse_expression(0); 3416 3417 consume(TokenType::ParenClose); 3418 3419 auto body = parse_statement(); 3420 return create_ast_node<WithStatement>({ m_source_code, rule_start.position(), position() }, move(object), move(body)); 3421} 3422 3423NonnullRefPtr<SwitchCase const> Parser::parse_switch_case() 3424{ 3425 auto rule_start = push_start(); 3426 RefPtr<Expression const> test; 3427 3428 if (consume().type() == TokenType::Case) { 3429 test = parse_expression(0); 3430 } 3431 3432 consume(TokenType::Colon); 3433 3434 Vector<NonnullRefPtr<Statement>> consequent; 3435 TemporaryChange break_change(m_state.in_break_context, true); 3436 auto switch_case = create_ast_node<SwitchCase>({ m_source_code, rule_start.position(), position() }, move(test)); 3437 parse_statement_list(switch_case); 3438 3439 return switch_case; 3440} 3441 3442NonnullRefPtr<CatchClause const> Parser::parse_catch_clause() 3443{ 3444 auto rule_start = push_start(); 3445 consume(TokenType::Catch); 3446 3447 DeprecatedFlyString parameter; 3448 RefPtr<BindingPattern const> pattern_parameter; 3449 auto should_expect_parameter = false; 3450 if (match(TokenType::ParenOpen)) { 3451 should_expect_parameter = true; 3452 consume(); 3453 if (match_identifier_name() 3454 && (!match(TokenType::Yield) || !m_state.in_generator_function_context) 3455 && (!match(TokenType::Async) || !m_state.await_expression_is_valid) 3456 && (!match(TokenType::Await) || !m_state.in_class_static_init_block)) 3457 parameter = consume().value(); 3458 else 3459 pattern_parameter = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No); 3460 consume(TokenType::ParenClose); 3461 } 3462 3463 if (should_expect_parameter && parameter.is_empty() && !pattern_parameter) 3464 expected("an identifier or a binding pattern"); 3465 3466 HashTable<DeprecatedFlyString> bound_names; 3467 3468 if (pattern_parameter) { 3469 // NOTE: Nothing in the callback throws an exception. 3470 MUST(pattern_parameter->for_each_bound_name( 3471 [&](auto& name) { 3472 check_identifier_name_for_assignment_validity(name); 3473 bound_names.set(name); 3474 })); 3475 } 3476 3477 if (!parameter.is_empty()) { 3478 check_identifier_name_for_assignment_validity(parameter); 3479 bound_names.set(parameter); 3480 } 3481 3482 ScopePusher catch_scope = ScopePusher::catch_scope(*this, pattern_parameter, parameter); 3483 auto body = parse_block_statement(); 3484 3485 // NOTE: Nothing in the callback throws an exception. 3486 MUST(body->for_each_lexically_declared_name([&](auto const& name) { 3487 if (bound_names.contains(name)) 3488 syntax_error(DeprecatedString::formatted("Identifier '{}' already declared as catch parameter", name)); 3489 })); 3490 3491 if (pattern_parameter) { 3492 return create_ast_node<CatchClause>( 3493 { m_source_code, rule_start.position(), position() }, 3494 pattern_parameter.release_nonnull(), 3495 move(body)); 3496 } 3497 3498 return create_ast_node<CatchClause>( 3499 { m_source_code, rule_start.position(), position() }, 3500 move(parameter), 3501 move(body)); 3502} 3503 3504NonnullRefPtr<IfStatement const> Parser::parse_if_statement() 3505{ 3506 auto rule_start = push_start(); 3507 auto parse_function_declaration_as_block_statement = [&] { 3508 // https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses 3509 // This production only applies when parsing non-strict code. Source text matched 3510 // by this production is processed as if each matching occurrence of 3511 // FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem 3512 // of a BlockStatement occupying that position in the source text. 3513 // The semantics of such a synthetic BlockStatement includes the web legacy 3514 // compatibility semantics specified in B.3.2. 3515 VERIFY(match(TokenType::Function)); 3516 auto block = create_ast_node<BlockStatement>({ m_source_code, rule_start.position(), position() }); 3517 ScopePusher block_scope = ScopePusher::block_scope(*this, *block); 3518 auto declaration = parse_declaration(); 3519 VERIFY(m_state.current_scope_pusher); 3520 block_scope.add_declaration(declaration); 3521 3522 VERIFY(is<FunctionDeclaration>(*declaration)); 3523 auto& function_declaration = static_cast<FunctionDeclaration const&>(*declaration); 3524 if (function_declaration.kind() == FunctionKind::Generator) 3525 syntax_error("Generator functions can only be declared in top-level or within a block"); 3526 if (function_declaration.kind() == FunctionKind::Async) 3527 syntax_error("Async functions can only be declared in top-level or within a block"); 3528 block->append(move(declaration)); 3529 return block; 3530 }; 3531 3532 consume(TokenType::If); 3533 consume(TokenType::ParenOpen); 3534 auto predicate = parse_expression(0); 3535 consume(TokenType::ParenClose); 3536 3537 RefPtr<Statement const> consequent; 3538 if (!m_state.strict_mode && match(TokenType::Function)) 3539 consequent = parse_function_declaration_as_block_statement(); 3540 else 3541 consequent = parse_statement(); 3542 3543 RefPtr<Statement const> alternate; 3544 if (match(TokenType::Else)) { 3545 consume(); 3546 if (!m_state.strict_mode && match(TokenType::Function)) 3547 alternate = parse_function_declaration_as_block_statement(); 3548 else 3549 alternate = parse_statement(); 3550 } 3551 return create_ast_node<IfStatement>({ m_source_code, rule_start.position(), position() }, move(predicate), move(*consequent), move(alternate)); 3552} 3553 3554NonnullRefPtr<Statement const> Parser::parse_for_statement() 3555{ 3556 auto rule_start = push_start(); 3557 auto is_await_loop = IsForAwaitLoop::No; 3558 3559 auto match_of = [&](Token const& token) { 3560 return token.type() == TokenType::Identifier && token.original_value() == "of"sv; 3561 }; 3562 3563 auto match_for_in_of = [&]() { 3564 bool is_of = match_of(m_state.current_token); 3565 if (is_await_loop == IsForAwaitLoop::Yes) { 3566 if (!is_of) 3567 syntax_error("for await loop is only valid with 'of'"); 3568 else if (!m_state.await_expression_is_valid) 3569 syntax_error("for await loop is only valid in async function or generator"); 3570 return true; 3571 } 3572 3573 return match(TokenType::In) || is_of; 3574 }; 3575 3576 consume(TokenType::For); 3577 3578 if (match(TokenType::Await)) { 3579 consume(); 3580 if (!m_state.await_expression_is_valid) 3581 syntax_error("for-await-of is only allowed in async function context"); 3582 is_await_loop = IsForAwaitLoop::Yes; 3583 } 3584 3585 consume(TokenType::ParenOpen); 3586 3587 Optional<ScopePusher> scope_pusher; 3588 3589 RefPtr<ASTNode const> init; 3590 if (!match(TokenType::Semicolon)) { 3591 3592 auto match_for_using_declaration = [&] { 3593 if (!match(TokenType::Identifier) || m_state.current_token.original_value() != "using"sv) 3594 return false; 3595 3596 auto lookahead = next_token(); 3597 if (lookahead.trivia_contains_line_terminator()) 3598 return false; 3599 3600 if (lookahead.original_value() == "of"sv) 3601 return false; 3602 3603 return token_is_identifier(lookahead); 3604 }; 3605 3606 if (match_for_using_declaration()) { 3607 auto declaration = parse_using_declaration(IsForLoopVariableDeclaration::Yes); 3608 3609 if (match_of(m_state.current_token)) { 3610 if (declaration->declarations().size() != 1) 3611 syntax_error("Must have exactly one declaration in for using of"); 3612 else if (declaration->declarations().first()->init()) 3613 syntax_error("Using declaration cannot have initializer"); 3614 3615 return parse_for_in_of_statement(move(declaration), is_await_loop); 3616 } 3617 3618 if (match(TokenType::In)) 3619 syntax_error("Using declaration not allowed in for-in loop"); 3620 3621 init = move(declaration); 3622 } else if (match_variable_declaration()) { 3623 auto declaration = parse_variable_declaration(IsForLoopVariableDeclaration::Yes); 3624 if (declaration->declaration_kind() == DeclarationKind::Var) { 3625 m_state.current_scope_pusher->add_declaration(declaration); 3626 } else { 3627 // This does not follow the normal declaration structure so we need additional checks. 3628 HashTable<DeprecatedFlyString> bound_names; 3629 // NOTE: Nothing in the callback throws an exception. 3630 MUST(declaration->for_each_bound_name([&](auto const& name) { 3631 if (bound_names.set(name) != AK::HashSetResult::InsertedNewEntry) 3632 syntax_error(DeprecatedString::formatted("Identifier '{}' already declared in for loop initializer", name), declaration->source_range().start); 3633 })); 3634 } 3635 3636 if (match_for_in_of()) { 3637 if (declaration->declarations().size() > 1) 3638 syntax_error("Multiple declarations not allowed in for..in/of"); 3639 else if (declaration->declarations().size() < 1) 3640 syntax_error("Need exactly one variable declaration in for..in/of"); 3641 3642 return parse_for_in_of_statement(move(declaration), is_await_loop); 3643 } 3644 if (declaration->declaration_kind() == DeclarationKind::Const) { 3645 for (auto const& variable : declaration->declarations()) { 3646 if (!variable->init()) 3647 syntax_error("Missing initializer in 'const' variable declaration"); 3648 } 3649 } 3650 3651 init = move(declaration); 3652 } else if (match_expression()) { 3653 auto lookahead_token = next_token(); 3654 bool starts_with_async_of = match(TokenType::Async) && match_of(lookahead_token); 3655 3656 init = parse_expression(0, Associativity::Right, { TokenType::In }); 3657 if (match_for_in_of()) { 3658 if (is_await_loop != IsForAwaitLoop::Yes 3659 && starts_with_async_of && match_of(m_state.current_token)) 3660 syntax_error("for-of loop may not start with async of"); 3661 return parse_for_in_of_statement(*init, is_await_loop); 3662 } 3663 } else { 3664 syntax_error("Unexpected token in for loop"); 3665 } 3666 } 3667 consume(TokenType::Semicolon); 3668 3669 RefPtr<Expression const> test; 3670 if (!match(TokenType::Semicolon)) 3671 test = parse_expression(0); 3672 3673 consume(TokenType::Semicolon); 3674 3675 RefPtr<Expression const> update; 3676 if (!match(TokenType::ParenClose)) 3677 update = parse_expression(0); 3678 3679 consume(TokenType::ParenClose); 3680 3681 TemporaryChange break_change(m_state.in_break_context, true); 3682 TemporaryChange continue_change(m_state.in_continue_context, true); 3683 ScopePusher for_loop_scope = ScopePusher::for_loop_scope(*this, init); 3684 auto body = parse_statement(); 3685 3686 return create_ast_node<ForStatement>({ m_source_code, rule_start.position(), position() }, move(init), move(test), move(update), move(body)); 3687} 3688 3689NonnullRefPtr<Statement const> Parser::parse_for_in_of_statement(NonnullRefPtr<ASTNode const> lhs, IsForAwaitLoop is_for_await_loop) 3690{ 3691 Variant<NonnullRefPtr<ASTNode const>, NonnullRefPtr<BindingPattern const>> for_declaration = lhs; 3692 auto rule_start = push_start(); 3693 3694 auto has_annexB_for_in_init_extension = false; 3695 3696 if (is<VariableDeclaration>(*lhs)) { 3697 auto& declaration = static_cast<VariableDeclaration const&>(*lhs); 3698 // Syntax errors for wrong amounts of declaration should have already been hit. 3699 if (!declaration.declarations().is_empty()) { 3700 // AnnexB extension B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads 3701 auto& variable = declaration.declarations().first(); 3702 if (variable->init()) { 3703 if (m_state.strict_mode || declaration.declaration_kind() != DeclarationKind::Var || !variable->target().has<NonnullRefPtr<Identifier const>>()) 3704 syntax_error("Variable initializer not allowed in for..in/of"); 3705 else 3706 has_annexB_for_in_init_extension = true; 3707 } 3708 } 3709 } else if (!lhs->is_identifier() && !is<MemberExpression>(*lhs) && !is<CallExpression>(*lhs) && !is<UsingDeclaration>(*lhs)) { 3710 bool valid = false; 3711 if (is<ObjectExpression>(*lhs) || is<ArrayExpression>(*lhs)) { 3712 auto synthesized_binding_pattern = synthesize_binding_pattern(static_cast<Expression const&>(*lhs)); 3713 if (synthesized_binding_pattern) { 3714 for_declaration = synthesized_binding_pattern.release_nonnull(); 3715 valid = true; 3716 } 3717 } 3718 if (!valid) 3719 syntax_error(DeprecatedString::formatted("Invalid left-hand side in for-loop ('{}')", lhs->class_name())); 3720 } 3721 auto in_or_of = consume(); 3722 auto is_in = in_or_of.type() == TokenType::In; 3723 3724 if (!is_in) { 3725 if (is<MemberExpression>(*lhs)) { 3726 auto& member = static_cast<MemberExpression const&>(*lhs); 3727 if (member.object().is_identifier() && static_cast<Identifier const&>(member.object()).string() == "let"sv) 3728 syntax_error("For of statement may not start with let."); 3729 } 3730 if (has_annexB_for_in_init_extension) 3731 syntax_error("Variable initializer not allowed in for..of", rule_start.position()); 3732 } 3733 3734 auto rhs = parse_expression(is_in ? 0 : 2); 3735 consume(TokenType::ParenClose); 3736 3737 TemporaryChange break_change(m_state.in_break_context, true); 3738 TemporaryChange continue_change(m_state.in_continue_context, true); 3739 ScopePusher for_loop_scope = ScopePusher::for_loop_scope(*this, lhs); 3740 auto body = parse_statement(); 3741 if (is_in) 3742 return create_ast_node<ForInStatement>({ m_source_code, rule_start.position(), position() }, move(for_declaration), move(rhs), move(body)); 3743 if (is_for_await_loop == IsForAwaitLoop::Yes) 3744 return create_ast_node<ForAwaitOfStatement>({ m_source_code, rule_start.position(), position() }, move(for_declaration), move(rhs), move(body)); 3745 return create_ast_node<ForOfStatement>({ m_source_code, rule_start.position(), position() }, move(for_declaration), move(rhs), move(body)); 3746} 3747 3748NonnullRefPtr<DebuggerStatement const> Parser::parse_debugger_statement() 3749{ 3750 auto rule_start = push_start(); 3751 consume(TokenType::Debugger); 3752 consume_or_insert_semicolon(); 3753 return create_ast_node<DebuggerStatement>({ m_source_code, rule_start.position(), position() }); 3754} 3755 3756bool Parser::match(TokenType type) const 3757{ 3758 return m_state.current_token.type() == type; 3759} 3760 3761bool Parser::match_expression() const 3762{ 3763 auto type = m_state.current_token.type(); 3764 if (type == TokenType::Import) { 3765 auto lookahead_token = next_token(); 3766 return lookahead_token.type() == TokenType::Period || lookahead_token.type() == TokenType::ParenOpen; 3767 } 3768 3769 return type == TokenType::BoolLiteral 3770 || type == TokenType::NumericLiteral 3771 || type == TokenType::BigIntLiteral 3772 || type == TokenType::StringLiteral 3773 || type == TokenType::TemplateLiteralStart 3774 || type == TokenType::NullLiteral 3775 || match_identifier() 3776 || type == TokenType::PrivateIdentifier 3777 || type == TokenType::Await 3778 || type == TokenType::New 3779 || type == TokenType::Class 3780 || type == TokenType::CurlyOpen 3781 || type == TokenType::BracketOpen 3782 || type == TokenType::ParenOpen 3783 || type == TokenType::Function 3784 || type == TokenType::Async 3785 || type == TokenType::This 3786 || type == TokenType::Super 3787 || type == TokenType::RegexLiteral 3788 || type == TokenType::Slash // Wrongly recognized regex by lexer 3789 || type == TokenType::SlashEquals // Wrongly recognized regex by lexer (/=a/ is a valid regex) 3790 || type == TokenType::Yield 3791 || match_unary_prefixed_expression(); 3792} 3793 3794bool Parser::match_unary_prefixed_expression() const 3795{ 3796 auto type = m_state.current_token.type(); 3797 return type == TokenType::PlusPlus 3798 || type == TokenType::MinusMinus 3799 || type == TokenType::ExclamationMark 3800 || type == TokenType::Tilde 3801 || type == TokenType::Plus 3802 || type == TokenType::Minus 3803 || type == TokenType::Typeof 3804 || type == TokenType::Void 3805 || type == TokenType::Delete; 3806} 3807 3808bool Parser::match_secondary_expression(ForbiddenTokens forbidden) const 3809{ 3810 auto type = m_state.current_token.type(); 3811 if (!forbidden.allows(type)) 3812 return false; 3813 return type == TokenType::Plus 3814 || type == TokenType::PlusEquals 3815 || type == TokenType::Minus 3816 || type == TokenType::MinusEquals 3817 || type == TokenType::Asterisk 3818 || type == TokenType::AsteriskEquals 3819 || type == TokenType::Slash 3820 || type == TokenType::SlashEquals 3821 || type == TokenType::Percent 3822 || type == TokenType::PercentEquals 3823 || type == TokenType::DoubleAsterisk 3824 || type == TokenType::DoubleAsteriskEquals 3825 || type == TokenType::Equals 3826 || type == TokenType::EqualsEqualsEquals 3827 || type == TokenType::ExclamationMarkEqualsEquals 3828 || type == TokenType::EqualsEquals 3829 || type == TokenType::ExclamationMarkEquals 3830 || type == TokenType::GreaterThan 3831 || type == TokenType::GreaterThanEquals 3832 || type == TokenType::LessThan 3833 || type == TokenType::LessThanEquals 3834 || type == TokenType::ParenOpen 3835 || type == TokenType::Period 3836 || type == TokenType::BracketOpen 3837 || (type == TokenType::PlusPlus && !m_state.current_token.trivia_contains_line_terminator()) 3838 || (type == TokenType::MinusMinus && !m_state.current_token.trivia_contains_line_terminator()) 3839 || type == TokenType::In 3840 || type == TokenType::Instanceof 3841 || type == TokenType::QuestionMark 3842 || type == TokenType::Ampersand 3843 || type == TokenType::AmpersandEquals 3844 || type == TokenType::Pipe 3845 || type == TokenType::PipeEquals 3846 || type == TokenType::Caret 3847 || type == TokenType::CaretEquals 3848 || type == TokenType::ShiftLeft 3849 || type == TokenType::ShiftLeftEquals 3850 || type == TokenType::ShiftRight 3851 || type == TokenType::ShiftRightEquals 3852 || type == TokenType::UnsignedShiftRight 3853 || type == TokenType::UnsignedShiftRightEquals 3854 || type == TokenType::DoubleAmpersand 3855 || type == TokenType::DoubleAmpersandEquals 3856 || type == TokenType::DoublePipe 3857 || type == TokenType::DoublePipeEquals 3858 || type == TokenType::DoubleQuestionMark 3859 || type == TokenType::DoubleQuestionMarkEquals 3860 || type == TokenType::QuestionMarkPeriod; 3861} 3862 3863bool Parser::match_statement() const 3864{ 3865 auto type = m_state.current_token.type(); 3866 return match_expression() 3867 || type == TokenType::Return 3868 || type == TokenType::Yield 3869 || type == TokenType::Do 3870 || type == TokenType::If 3871 || type == TokenType::Throw 3872 || type == TokenType::Try 3873 || type == TokenType::While 3874 || type == TokenType::With 3875 || type == TokenType::For 3876 || type == TokenType::CurlyOpen 3877 || type == TokenType::Switch 3878 || type == TokenType::Break 3879 || type == TokenType::Continue 3880 || type == TokenType::Var 3881 || type == TokenType::Debugger 3882 || type == TokenType::Semicolon; 3883} 3884 3885bool Parser::match_export_or_import() const 3886{ 3887 auto type = m_state.current_token.type(); 3888 return type == TokenType::Export 3889 || type == TokenType::Import; 3890} 3891 3892bool Parser::match_declaration(AllowUsingDeclaration allow_using) const 3893{ 3894 auto type = m_state.current_token.type(); 3895 3896 if (type == TokenType::Let && !m_state.strict_mode) { 3897 return try_match_let_declaration(); 3898 } 3899 3900 if (type == TokenType::Async) { 3901 auto lookahead_token = next_token(); 3902 return lookahead_token.type() == TokenType::Function && !lookahead_token.trivia_contains_line_terminator(); 3903 } 3904 3905 if (allow_using == AllowUsingDeclaration::Yes && type == TokenType::Identifier && m_state.current_token.original_value() == "using"sv) 3906 return try_match_using_declaration(); 3907 3908 return type == TokenType::Function 3909 || type == TokenType::Class 3910 || type == TokenType::Const 3911 || type == TokenType::Let; 3912} 3913 3914Token Parser::next_token(size_t steps) const 3915{ 3916 Lexer lookahead_lexer = m_state.lexer; 3917 3918 Token lookahead_token; 3919 3920 while (steps > 0) { 3921 lookahead_token = lookahead_lexer.next(); 3922 steps--; 3923 } 3924 3925 return lookahead_token; 3926} 3927 3928bool Parser::try_match_let_declaration() const 3929{ 3930 VERIFY(m_state.current_token.type() == TokenType::Let); 3931 auto token_after = next_token(); 3932 3933 if (token_after.is_identifier_name() && token_after.value() != "in"sv) 3934 return true; 3935 3936 if (token_after.type() == TokenType::CurlyOpen || token_after.type() == TokenType::BracketOpen) 3937 return true; 3938 3939 return false; 3940} 3941 3942bool Parser::try_match_using_declaration() const 3943{ 3944 VERIFY(m_state.current_token.type() == TokenType::Identifier); 3945 VERIFY(m_state.current_token.original_value() == "using"sv); 3946 3947 auto token_after = next_token(); 3948 if (token_after.trivia_contains_line_terminator()) 3949 return false; 3950 3951 return token_after.is_identifier_name(); 3952} 3953 3954bool Parser::match_variable_declaration() const 3955{ 3956 auto type = m_state.current_token.type(); 3957 3958 if (type == TokenType::Let && !m_state.strict_mode) { 3959 return try_match_let_declaration(); 3960 } 3961 3962 return type == TokenType::Var 3963 || type == TokenType::Let 3964 || type == TokenType::Const; 3965} 3966 3967bool Parser::match_identifier() const 3968{ 3969 return token_is_identifier(m_state.current_token); 3970} 3971 3972bool Parser::token_is_identifier(Token const& token) const 3973{ 3974 if (token.type() == TokenType::EscapedKeyword) { 3975 if (token.value() == "let"sv) 3976 return !m_state.strict_mode; 3977 if (token.value() == "yield"sv) 3978 return !m_state.strict_mode && !m_state.in_generator_function_context; 3979 if (token.value() == "await"sv) 3980 return m_program_type != Program::Type::Module && !m_state.await_expression_is_valid && !m_state.in_class_static_init_block; 3981 return true; 3982 } 3983 3984 return token.type() == TokenType::Identifier 3985 || token.type() == TokenType::Async 3986 || (token.type() == TokenType::Let && !m_state.strict_mode) 3987 || (token.type() == TokenType::Await && m_program_type != Program::Type::Module && !m_state.await_expression_is_valid && !m_state.in_class_static_init_block) 3988 || (token.type() == TokenType::Yield && !m_state.in_generator_function_context && !m_state.strict_mode); // See note in Parser::parse_identifier(). 3989} 3990 3991bool Parser::match_identifier_name() const 3992{ 3993 return m_state.current_token.is_identifier_name(); 3994} 3995 3996bool Parser::match_property_key() const 3997{ 3998 auto type = m_state.current_token.type(); 3999 return match_identifier_name() 4000 || type == TokenType::BracketOpen 4001 || type == TokenType::StringLiteral 4002 || type == TokenType::NumericLiteral 4003 || type == TokenType::BigIntLiteral; 4004} 4005 4006bool Parser::done() const 4007{ 4008 return match(TokenType::Eof); 4009} 4010 4011Token Parser::consume() 4012{ 4013 auto old_token = m_state.current_token; 4014 m_state.current_token = m_state.lexer.next(); 4015 // NOTE: This is the bare minimum needed to decide whether we might need an arguments object 4016 // in a function expression or declaration. ("might" because the AST implements some further 4017 // conditions from the spec that rule out the need for allocating one) 4018 if (old_token.type() == TokenType::Identifier && old_token.value().is_one_of("arguments"sv, "eval"sv)) 4019 m_state.function_might_need_arguments_object = true; 4020 return old_token; 4021} 4022 4023void Parser::consume_or_insert_semicolon() 4024{ 4025 // Semicolon was found and will be consumed 4026 if (match(TokenType::Semicolon)) { 4027 consume(); 4028 return; 4029 } 4030 // Insert semicolon if... 4031 // ...token is preceded by one or more newlines 4032 if (m_state.current_token.trivia_contains_line_terminator()) 4033 return; 4034 // ...token is a closing curly brace 4035 if (match(TokenType::CurlyClose)) 4036 return; 4037 // ...token is eof 4038 if (match(TokenType::Eof)) 4039 return; 4040 4041 // No rule for semicolon insertion applies -> syntax error 4042 expected("Semicolon"); 4043} 4044 4045Token Parser::consume_identifier() 4046{ 4047 if (match(TokenType::Identifier)) 4048 return consume(TokenType::Identifier); 4049 4050 if (match(TokenType::EscapedKeyword)) 4051 return consume(TokenType::EscapedKeyword); 4052 4053 // Note that 'let' is not a reserved keyword, but our lexer considers it such 4054 // As it's pretty nice to have that (for syntax highlighting and such), we'll 4055 // special-case it here instead. 4056 if (match(TokenType::Let)) { 4057 if (m_state.strict_mode) 4058 syntax_error("'let' is not allowed as an identifier in strict mode"); 4059 return consume(); 4060 } 4061 4062 if (match(TokenType::Yield)) { 4063 if (m_state.strict_mode || m_state.in_generator_function_context) 4064 syntax_error("Identifier must not be a reserved word in strict mode ('yield')"); 4065 return consume(); 4066 } 4067 4068 if (match(TokenType::Await)) { 4069 if (m_program_type == Program::Type::Module || m_state.await_expression_is_valid || m_state.in_class_static_init_block) 4070 syntax_error("Identifier must not be a reserved word in modules ('await')"); 4071 return consume(); 4072 } 4073 4074 if (match(TokenType::Async)) 4075 return consume(); 4076 4077 expected("Identifier"); 4078 return consume(); 4079} 4080 4081// https://tc39.es/ecma262/#prod-IdentifierReference 4082Token Parser::consume_identifier_reference() 4083{ 4084 if (match(TokenType::Identifier)) 4085 return consume(TokenType::Identifier); 4086 4087 if (match(TokenType::EscapedKeyword)) { 4088 auto name = m_state.current_token.value(); 4089 if (m_state.strict_mode && (name == "let"sv || name == "yield"sv)) 4090 syntax_error(DeprecatedString::formatted("'{}' is not allowed as an identifier in strict mode", name)); 4091 if (m_program_type == Program::Type::Module && name == "await"sv) 4092 syntax_error("'await' is not allowed as an identifier in module"); 4093 4094 return consume(); 4095 } 4096 4097 // See note in Parser::parse_identifier(). 4098 if (match(TokenType::Let)) { 4099 if (m_state.strict_mode) 4100 syntax_error("'let' is not allowed as an identifier in strict mode"); 4101 return consume(); 4102 } 4103 4104 if (match(TokenType::Yield)) { 4105 if (m_state.strict_mode) 4106 syntax_error("Identifier reference may not be 'yield' in strict mode"); 4107 return consume(); 4108 } 4109 4110 if (match(TokenType::Await)) { 4111 if (m_program_type == Program::Type::Module) 4112 syntax_error("'await' is not allowed as an identifier in module"); 4113 return consume(); 4114 } 4115 4116 if (match(TokenType::Async)) 4117 return consume(); 4118 4119 expected(Token::name(TokenType::Identifier)); 4120 return consume(); 4121} 4122 4123Token Parser::consume(TokenType expected_type) 4124{ 4125 if (!match(expected_type)) { 4126 expected(Token::name(expected_type)); 4127 } 4128 auto token = consume(); 4129 if (expected_type == TokenType::Identifier) { 4130 if (m_state.strict_mode && is_strict_reserved_word(token.value())) 4131 syntax_error(DeprecatedString::formatted("Identifier must not be a reserved word in strict mode ('{}')", token.value())); 4132 } 4133 return token; 4134} 4135 4136Token Parser::consume_and_validate_numeric_literal() 4137{ 4138 auto is_unprefixed_octal_number = [](StringView value) { 4139 return value.length() > 1 && value[0] == '0' && is_ascii_digit(value[1]); 4140 }; 4141 auto literal_start = position(); 4142 auto token = consume(TokenType::NumericLiteral); 4143 if (m_state.strict_mode && is_unprefixed_octal_number(token.value())) 4144 syntax_error("Unprefixed octal number not allowed in strict mode", literal_start); 4145 if (match_identifier_name() && m_state.current_token.trivia().is_empty()) 4146 syntax_error("Numeric literal must not be immediately followed by identifier"); 4147 return token; 4148} 4149 4150void Parser::expected(char const* what) 4151{ 4152 auto message = m_state.current_token.message().to_deprecated_string(); 4153 if (message.is_empty()) 4154 message = DeprecatedString::formatted("Unexpected token {}. Expected {}", m_state.current_token.name(), what); 4155 syntax_error(message); 4156} 4157 4158Position Parser::position() const 4159{ 4160 return { 4161 m_state.current_token.line_number(), 4162 m_state.current_token.line_column(), 4163 m_state.current_token.offset(), 4164 }; 4165} 4166 4167bool Parser::try_parse_arrow_function_expression_failed_at_position(Position const& position) const 4168{ 4169 auto it = m_token_memoizations.find(position); 4170 if (it == m_token_memoizations.end()) 4171 return false; 4172 4173 return (*it).value.try_parse_arrow_function_expression_failed; 4174} 4175 4176void Parser::set_try_parse_arrow_function_expression_failed_at_position(Position const& position, bool failed) 4177{ 4178 m_token_memoizations.set(position, { failed }); 4179} 4180 4181void Parser::syntax_error(DeprecatedString const& message, Optional<Position> position) 4182{ 4183 if (!position.has_value()) 4184 position = this->position(); 4185 m_state.errors.append({ message, position }); 4186} 4187 4188void Parser::save_state() 4189{ 4190 m_saved_state.append(m_state); 4191} 4192 4193void Parser::load_state() 4194{ 4195 VERIFY(!m_saved_state.is_empty()); 4196 m_state = m_saved_state.take_last(); 4197} 4198 4199void Parser::discard_saved_state() 4200{ 4201 m_saved_state.take_last(); 4202} 4203 4204void Parser::check_identifier_name_for_assignment_validity(DeprecatedFlyString const& name, bool force_strict) 4205{ 4206 // FIXME: this is now called from multiple places maybe the error message should be dynamic? 4207 if (any_of(s_reserved_words, [&](auto& value) { return name == value; })) { 4208 syntax_error("Binding pattern target may not be a reserved word"); 4209 } else if (m_state.strict_mode || force_strict) { 4210 if (name.is_one_of("arguments"sv, "eval"sv)) 4211 syntax_error("Binding pattern target may not be called 'arguments' or 'eval' in strict mode"); 4212 else if (is_strict_reserved_word(name)) 4213 syntax_error(DeprecatedString::formatted("Binding pattern target may not be called '{}' in strict mode", name)); 4214 } 4215} 4216 4217bool Parser::match_assert_clause() const 4218{ 4219 return !m_state.current_token.trivia_contains_line_terminator() && m_state.current_token.original_value() == "assert"sv; 4220} 4221 4222DeprecatedFlyString Parser::consume_string_value() 4223{ 4224 VERIFY(match(TokenType::StringLiteral)); 4225 auto string_token = consume(); 4226 DeprecatedFlyString value = parse_string_literal(string_token)->value(); 4227 4228 // This also checks IsStringWellFormedUnicode which makes sure there is no unpaired surrogate 4229 // Surrogates are at least 3 bytes 4230 if (value.length() < 3) 4231 return value; 4232 4233 Utf8View view { value.view().substring_view(value.length() - 3) }; 4234 VERIFY(view.length() <= 3); 4235 auto codepoint = *view.begin(); 4236 if (Utf16View::is_high_surrogate(codepoint)) { 4237 syntax_error("StringValue ending with unpaired high surrogate"); 4238 VERIFY(view.length() == 1); 4239 } 4240 4241 return value; 4242} 4243 4244// AssertClause, https://tc39.es/proposal-import-assertions/#prod-AssertClause 4245ModuleRequest Parser::parse_module_request() 4246{ 4247 // Does not include the 'from' since that is not always required. 4248 4249 if (!match(TokenType::StringLiteral)) { 4250 expected("ModuleSpecifier (string)"); 4251 return ModuleRequest { "!!invalid!!" }; 4252 } 4253 4254 ModuleRequest request { consume_string_value() }; 4255 4256 if (!match_assert_clause()) 4257 return request; 4258 4259 VERIFY(m_state.current_token.original_value() == "assert"sv); 4260 consume(TokenType::Identifier); 4261 consume(TokenType::CurlyOpen); 4262 4263 while (!done() && !match(TokenType::CurlyClose)) { 4264 DeprecatedString key; 4265 if (match(TokenType::StringLiteral)) { 4266 key = parse_string_literal(m_state.current_token)->value().to_deprecated_string(); 4267 consume(); 4268 } else if (match_identifier_name()) { 4269 key = consume().value(); 4270 } else { 4271 expected("IdentifierName or StringValue as AssertionKey"); 4272 consume(); 4273 } 4274 4275 consume(TokenType::Colon); 4276 4277 if (match(TokenType::StringLiteral)) { 4278 for (auto& entries : request.assertions) { 4279 if (entries.key == key) 4280 syntax_error(DeprecatedString::formatted("Duplicate assertion clauses with name: {}", key)); 4281 } 4282 request.add_assertion(move(key), parse_string_literal(m_state.current_token)->value().to_deprecated_string()); 4283 } 4284 consume(TokenType::StringLiteral); 4285 4286 if (match(TokenType::Comma)) 4287 consume(TokenType::Comma); 4288 else 4289 break; 4290 } 4291 4292 consume(TokenType::CurlyClose); 4293 4294 return request; 4295} 4296 4297static DeprecatedFlyString default_string_value = "default"; 4298 4299NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& program) 4300{ 4301 // We use the extended syntax which adds: 4302 // ImportDeclaration: 4303 // import ImportClause FromClause [no LineTerminator here] AssertClause; 4304 // import ModuleSpecifier [no LineTerminator here] AssertClause; 4305 // From: https://tc39.es/proposal-import-assertions/#prod-ImportDeclaration 4306 4307 auto rule_start = push_start(); 4308 if (program.type() != Program::Type::Module) 4309 syntax_error("Cannot use import statement outside a module"); 4310 4311 consume(TokenType::Import); 4312 4313 if (match(TokenType::StringLiteral)) { 4314 // import ModuleSpecifier ; 4315 auto module_request = parse_module_request(); 4316 return create_ast_node<ImportStatement>({ m_source_code, rule_start.position(), position() }, move(module_request)); 4317 } 4318 4319 auto match_imported_binding = [&] { 4320 return match_identifier() || match(TokenType::Yield) || match(TokenType::Await); 4321 }; 4322 4323 auto match_as = [&] { 4324 return match(TokenType::Identifier) && m_state.current_token.original_value() == "as"sv; 4325 }; 4326 4327 bool continue_parsing = true; 4328 4329 struct ImportWithLocation { 4330 ImportEntry entry; 4331 Position position; 4332 }; 4333 4334 Vector<ImportWithLocation> entries_with_location; 4335 4336 // import ImportClause FromClause ; 4337 // ImportClause : 4338 // ImportedDefaultBinding 4339 // NameSpaceImport 4340 // NamedImports 4341 // ImportedDefaultBinding , NameSpaceImport 4342 // ImportedDefaultBinding , NamedImports 4343 4344 if (match_imported_binding()) { 4345 // ImportedDefaultBinding : ImportedBinding 4346 auto id_position = position(); 4347 auto bound_name = consume().value(); 4348 entries_with_location.append({ { default_string_value, bound_name }, id_position }); 4349 4350 if (match(TokenType::Comma)) { 4351 consume(TokenType::Comma); 4352 } else { 4353 continue_parsing = false; 4354 } 4355 } 4356 4357 if (!continue_parsing) { 4358 // skip the rest 4359 } else if (match(TokenType::Asterisk)) { 4360 // NameSpaceImport : * as ImportedBinding 4361 consume(TokenType::Asterisk); 4362 4363 if (!match_as()) 4364 syntax_error(DeprecatedString::formatted("Unexpected token: {}", m_state.current_token.name())); 4365 4366 consume(TokenType::Identifier); 4367 4368 if (match_imported_binding()) { 4369 auto namespace_position = position(); 4370 auto namespace_name = consume().value(); 4371 entries_with_location.append({ ImportEntry({}, namespace_name, true), namespace_position }); 4372 } else { 4373 syntax_error(DeprecatedString::formatted("Unexpected token: {}", m_state.current_token.name())); 4374 } 4375 4376 } else if (match(TokenType::CurlyOpen)) { 4377 // NamedImports : 4378 // { ImportSpecifier ,_opt } (repeated any amount of times) 4379 4380 consume(TokenType::CurlyOpen); 4381 while (!done() && !match(TokenType::CurlyClose)) { 4382 if (match_identifier_name()) { 4383 // ImportSpecifier : ImportedBinding 4384 auto require_as = !match_imported_binding(); 4385 auto name_position = position(); 4386 auto name = consume().DeprecatedFlyString_value(); 4387 4388 if (match_as()) { 4389 consume(TokenType::Identifier); 4390 4391 auto alias_position = position(); 4392 auto alias = consume_identifier().DeprecatedFlyString_value(); 4393 check_identifier_name_for_assignment_validity(alias); 4394 4395 entries_with_location.append({ { name, alias }, alias_position }); 4396 } else if (require_as) { 4397 syntax_error(DeprecatedString::formatted("Unexpected reserved word '{}'", name)); 4398 } else { 4399 check_identifier_name_for_assignment_validity(name); 4400 4401 entries_with_location.append({ { name, name }, name_position }); 4402 } 4403 } else if (match(TokenType::StringLiteral)) { 4404 // ImportSpecifier : ModuleExportName as ImportedBinding 4405 auto name = consume_string_value(); 4406 4407 if (!match_as()) 4408 expected("as"); 4409 4410 consume(TokenType::Identifier); 4411 4412 auto alias_position = position(); 4413 auto alias = consume_identifier().DeprecatedFlyString_value(); 4414 check_identifier_name_for_assignment_validity(alias); 4415 4416 entries_with_location.append({ { move(name), alias }, alias_position }); 4417 } else { 4418 expected("identifier"); 4419 break; 4420 } 4421 4422 if (!match(TokenType::Comma)) 4423 break; 4424 4425 consume(TokenType::Comma); 4426 } 4427 4428 consume(TokenType::CurlyClose); 4429 } else { 4430 expected("import clauses"); 4431 } 4432 4433 auto from_statement = consume(TokenType::Identifier).original_value(); 4434 if (from_statement != "from"sv) 4435 syntax_error(DeprecatedString::formatted("Expected 'from' got {}", from_statement)); 4436 4437 auto module_request = parse_module_request(); 4438 4439 Vector<ImportEntry> entries; 4440 entries.ensure_capacity(entries_with_location.size()); 4441 4442 for (auto& entry : entries_with_location) { 4443 for (auto& import_statement : program.imports()) { 4444 if (import_statement->has_bound_name(entry.entry.local_name)) 4445 syntax_error(DeprecatedString::formatted("Identifier '{}' already declared", entry.entry.local_name), entry.position); 4446 } 4447 4448 for (auto& new_entry : entries) { 4449 if (new_entry.local_name == entry.entry.local_name) 4450 syntax_error(DeprecatedString::formatted("Identifier '{}' already declared", entry.entry.local_name), entry.position); 4451 } 4452 4453 entries.append(move(entry.entry)); 4454 } 4455 4456 return create_ast_node<ImportStatement>({ m_source_code, rule_start.position(), position() }, move(module_request), move(entries)); 4457} 4458 4459NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& program) 4460{ 4461 // We use the extended syntax which adds: 4462 // ExportDeclaration: 4463 // export ExportFromClause FromClause [no LineTerminator here] AssertClause ; 4464 // From: https://tc39.es/proposal-import-assertions/#prod-ExportDeclaration 4465 4466 auto rule_start = push_start(); 4467 if (program.type() != Program::Type::Module) 4468 syntax_error("Cannot use export statement outside a module"); 4469 4470 auto match_as = [&] { 4471 return match(TokenType::Identifier) && m_state.current_token.original_value() == "as"sv; 4472 }; 4473 4474 auto match_from = [&] { 4475 return match(TokenType::Identifier) && m_state.current_token.original_value() == "from"sv; 4476 }; 4477 4478 auto match_default = [&] { 4479 return match(TokenType::Default) && m_state.current_token.original_value() == "default"sv; 4480 }; 4481 4482 consume(TokenType::Export); 4483 4484 struct EntryAndLocation { 4485 ExportEntry entry; 4486 Position position; 4487 }; 4488 4489 Vector<EntryAndLocation> entries_with_location; 4490 4491 RefPtr<ASTNode const> expression = {}; 4492 bool is_default = false; 4493 ModuleRequest from_specifier; 4494 4495 if (match_default()) { 4496 is_default = true; 4497 auto default_position = position(); 4498 consume(TokenType::Default); 4499 4500 DeprecatedFlyString local_name; 4501 4502 auto lookahead_token = next_token(); 4503 4504 enum class MatchesFunctionDeclaration { 4505 Yes, 4506 No, 4507 WithoutName, 4508 }; 4509 4510 // Note: For some reason the spec here has declaration which can have no name 4511 // and the rest of the parser is just not setup for that. With these 4512 // hacks below we get through most things but we should probably figure 4513 // out a better solution. I have attempted to explain why/what these "hacks" do below. 4514 // The summary is treat named declarations just as declarations and hack around unnamed 4515 // declarations with expression see also SourceTextModule::initialize_environment. 4516 // As far as I'm aware the only problem (which is a tricky one) is: 4517 // `export default function() {}()` 4518 // Since we parse this as an expression you are immediately allowed to call it 4519 // which is incorrect and this should give a SyntaxError. 4520 4521 auto has_name = [&](Token const& token) { 4522 if (token.type() != TokenType::ParenOpen) 4523 return MatchesFunctionDeclaration::Yes; 4524 4525 return MatchesFunctionDeclaration::WithoutName; 4526 }; 4527 4528 auto match_function_declaration = [&] { 4529 // Hack part 1. 4530 // Match a function declaration with a name, since we have async and generator 4531 // and asyncgenerator variants this is quite complicated. 4532 auto current_type = m_state.current_token.type(); 4533 Lexer lookahead_lexer = m_state.lexer; 4534 lookahead_lexer.next(); 4535 4536 if (current_type == TokenType::Function) { 4537 if (lookahead_token.type() == TokenType::Asterisk) 4538 return has_name(lookahead_lexer.next()); // function * [name] 4539 else 4540 return has_name(lookahead_token); // function [name] 4541 } 4542 4543 if (current_type == TokenType::Async) { 4544 if (lookahead_token.type() != TokenType::Function) 4545 return MatchesFunctionDeclaration::No; 4546 4547 if (lookahead_token.trivia_contains_line_terminator()) 4548 return MatchesFunctionDeclaration::No; 4549 4550 auto lookahead_two_token = lookahead_lexer.next(); 4551 if (lookahead_two_token.type() == TokenType::Asterisk) 4552 return has_name(lookahead_lexer.next()); // async function * [name] 4553 else 4554 return has_name(lookahead_two_token); // async function [name] 4555 } 4556 4557 return MatchesFunctionDeclaration::No; 4558 }; 4559 4560 if (auto matches_function = match_function_declaration(); matches_function != MatchesFunctionDeclaration::No) { 4561 4562 auto function_declaration = parse_function_node<FunctionDeclaration>( 4563 (matches_function == MatchesFunctionDeclaration::WithoutName ? FunctionNodeParseOptions::HasDefaultExportName : 0) 4564 | FunctionNodeParseOptions::CheckForFunctionAndName); 4565 4566 m_state.current_scope_pusher->add_declaration(function_declaration); 4567 if (matches_function == MatchesFunctionDeclaration::WithoutName) 4568 local_name = ExportStatement::local_name_for_default; 4569 else 4570 local_name = function_declaration->name(); 4571 4572 expression = move(function_declaration); 4573 } else if (match(TokenType::Class) && lookahead_token.type() != TokenType::CurlyOpen && lookahead_token.type() != TokenType::Extends) { 4574 // Hack part 2. 4575 // Attempt to detect classes with names only as those are declarations, 4576 // this actually seems to cover all cases already. 4577 auto class_expression = parse_class_declaration(); 4578 m_state.current_scope_pusher->add_declaration(class_expression); 4579 local_name = class_expression->name(); 4580 expression = move(class_expression); 4581 4582 } else if (match_expression()) { 4583 // Hack part 3. 4584 // Even though the unnamed declarations look like expression we should 4585 // not treat them as such and thus not consume a semicolon after them. 4586 4587 bool special_case_declaration_without_name = match(TokenType::Class) || match(TokenType::Function) || (match(TokenType::Async) && lookahead_token.type() == TokenType::Function && !lookahead_token.trivia_contains_line_terminator()); 4588 expression = parse_expression(2); 4589 4590 if (!special_case_declaration_without_name) 4591 consume_or_insert_semicolon(); 4592 4593 if (is<ClassExpression>(*expression)) { 4594 auto const& class_expression = static_cast<ClassExpression const&>(*expression); 4595 if (class_expression.has_name()) 4596 local_name = class_expression.name(); 4597 } 4598 } else { 4599 expected("Declaration or assignment expression"); 4600 local_name = "!!invalid!!"; 4601 } 4602 4603 if (local_name.is_null()) { 4604 local_name = ExportStatement::local_name_for_default; 4605 } 4606 4607 entries_with_location.append({ ExportEntry::named_export(default_string_value, move(local_name)), default_position }); 4608 } else { 4609 enum class FromSpecifier { 4610 NotAllowed, 4611 Optional, 4612 Required 4613 } check_for_from { FromSpecifier::NotAllowed }; 4614 4615 auto parse_module_export_name = [&](bool lhs) -> DeprecatedFlyString { 4616 // https://tc39.es/ecma262/#prod-ModuleExportName 4617 // ModuleExportName : 4618 // IdentifierName 4619 // StringLiteral 4620 if (match_identifier_name()) { 4621 return consume().value(); 4622 } 4623 if (match(TokenType::StringLiteral)) { 4624 // It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals. 4625 // Only for export { "a" as "b" }; // <-- no from 4626 if (lhs) 4627 check_for_from = FromSpecifier::Required; 4628 return consume_string_value(); 4629 } 4630 expected("ExportSpecifier (string or identifier)"); 4631 return {}; 4632 }; 4633 4634 if (match(TokenType::Asterisk)) { 4635 auto asterisk_position = position(); 4636 consume(TokenType::Asterisk); 4637 4638 if (match_as()) { 4639 // * as ModuleExportName 4640 consume(TokenType::Identifier); 4641 auto namespace_position = position(); 4642 auto exported_name = parse_module_export_name(false); 4643 entries_with_location.append({ ExportEntry::all_module_request(exported_name), namespace_position }); 4644 } else { 4645 entries_with_location.append({ ExportEntry::all_but_default_entry(), asterisk_position }); 4646 } 4647 check_for_from = FromSpecifier::Required; 4648 } else if (match_declaration()) { 4649 auto decl_position = position(); 4650 auto declaration = parse_declaration(); 4651 m_state.current_scope_pusher->add_declaration(declaration); 4652 if (is<FunctionDeclaration>(*declaration)) { 4653 auto& func = static_cast<FunctionDeclaration const&>(*declaration); 4654 entries_with_location.append({ ExportEntry::named_export(func.name(), func.name()), func.source_range().start }); 4655 } else if (is<ClassDeclaration>(*declaration)) { 4656 auto& class_declaration = static_cast<ClassDeclaration const&>(*declaration); 4657 entries_with_location.append({ ExportEntry::named_export(class_declaration.name(), class_declaration.name()), class_declaration.source_range().start }); 4658 } else { 4659 VERIFY(is<VariableDeclaration>(*declaration)); 4660 auto& variables = static_cast<VariableDeclaration const&>(*declaration); 4661 VERIFY(variables.is_lexical_declaration()); 4662 for (auto& decl : variables.declarations()) { 4663 decl->target().visit( 4664 [&](NonnullRefPtr<Identifier const> const& identifier) { 4665 entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); 4666 }, 4667 [&](NonnullRefPtr<BindingPattern const> const& binding) { 4668 // NOTE: Nothing in the callback throws an exception. 4669 MUST(binding->for_each_bound_name([&](auto& name) { 4670 entries_with_location.append({ ExportEntry::named_export(name, name), decl_position }); 4671 })); 4672 }); 4673 } 4674 } 4675 expression = declaration; 4676 } else if (match(TokenType::Var)) { 4677 auto variable_position = position(); 4678 auto variable_declaration = parse_variable_declaration(); 4679 m_state.current_scope_pusher->add_declaration(variable_declaration); 4680 for (auto& decl : variable_declaration->declarations()) { 4681 decl->target().visit( 4682 [&](NonnullRefPtr<Identifier const> const& identifier) { 4683 entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); 4684 }, 4685 [&](NonnullRefPtr<BindingPattern const> const& binding) { 4686 // NOTE: Nothing in the callback throws an exception. 4687 MUST(binding->for_each_bound_name([&](auto& name) { 4688 entries_with_location.append({ ExportEntry::named_export(name, name), variable_position }); 4689 })); 4690 }); 4691 } 4692 expression = variable_declaration; 4693 } else if (match(TokenType::CurlyOpen)) { 4694 consume(TokenType::CurlyOpen); 4695 check_for_from = FromSpecifier::Optional; 4696 4697 // FIXME: Even when empty should add module to requiredModules! 4698 while (!done() && !match(TokenType::CurlyClose)) { 4699 auto identifier_position = position(); 4700 auto identifier = parse_module_export_name(true); 4701 4702 if (match_as()) { 4703 consume(TokenType::Identifier); 4704 auto export_name = parse_module_export_name(false); 4705 4706 entries_with_location.append({ ExportEntry::named_export(move(export_name), move(identifier)), identifier_position }); 4707 } else { 4708 entries_with_location.append({ ExportEntry::named_export(identifier, identifier), identifier_position }); 4709 } 4710 4711 if (!match(TokenType::Comma)) 4712 break; 4713 4714 consume(TokenType::Comma); 4715 } 4716 4717 if (entries_with_location.is_empty()) { 4718 // export {} from "module"; Since this will never be a 4719 // duplicate we can give a slightly wrong location. 4720 entries_with_location.append({ ExportEntry::empty_named_export(), position() }); 4721 } 4722 4723 consume(TokenType::CurlyClose); 4724 4725 } else { 4726 syntax_error("Unexpected token 'export'", rule_start.position()); 4727 } 4728 4729 if (check_for_from != FromSpecifier::NotAllowed && match_from()) { 4730 consume(TokenType::Identifier); 4731 from_specifier = parse_module_request(); 4732 } else if (check_for_from == FromSpecifier::Required) { 4733 expected("from"); 4734 } 4735 4736 if (check_for_from != FromSpecifier::NotAllowed) 4737 consume_or_insert_semicolon(); 4738 } 4739 4740 Vector<ExportEntry> entries; 4741 entries.ensure_capacity(entries_with_location.size()); 4742 4743 for (auto& entry : entries_with_location) { 4744 for (auto& export_statement : program.exports()) { 4745 if (export_statement->has_export(entry.entry.export_name)) 4746 syntax_error(DeprecatedString::formatted("Duplicate export with name: '{}'", entry.entry.export_name), entry.position); 4747 } 4748 4749 for (auto& new_entry : entries) { 4750 if (new_entry.kind != ExportEntry::Kind::EmptyNamedExport && new_entry.export_name == entry.entry.export_name) 4751 syntax_error(DeprecatedString::formatted("Duplicate export with name: '{}'", entry.entry.export_name), entry.position); 4752 } 4753 4754 entries.append(move(entry.entry)); 4755 } 4756 4757 return create_ast_node<ExportStatement>({ m_source_code, rule_start.position(), position() }, move(expression), move(entries), is_default, move(from_specifier)); 4758} 4759 4760Parser::ForbiddenTokens::ForbiddenTokens(std::initializer_list<TokenType> const& forbidden) 4761{ 4762 forbid_tokens(forbidden); 4763} 4764 4765void Parser::ForbiddenTokens::forbid_tokens(std::initializer_list<TokenType> const& forbidden) 4766{ 4767 for (auto token : forbidden) { 4768 switch (token) { 4769 case TokenType::In: 4770 m_forbid_in_token = true; 4771 break; 4772 case TokenType::DoubleAmpersand: 4773 case TokenType::DoublePipe: 4774 m_forbid_logical_tokens = true; 4775 break; 4776 case TokenType::DoubleQuestionMark: 4777 m_forbid_coalesce_token = true; 4778 break; 4779 case TokenType::QuestionMarkPeriod: 4780 m_forbid_question_mark_period = true; 4781 break; 4782 case TokenType::ParenOpen: 4783 m_forbid_paren_open = true; 4784 break; 4785 case TokenType::Equals: 4786 m_forbid_equals = true; 4787 break; 4788 default: 4789 VERIFY_NOT_REACHED(); 4790 } 4791 } 4792} 4793 4794bool Parser::ForbiddenTokens::allows(TokenType token) const 4795{ 4796 switch (token) { 4797 case TokenType::In: 4798 return !m_forbid_in_token; 4799 case TokenType::DoubleAmpersand: 4800 case TokenType::DoublePipe: 4801 return !m_forbid_logical_tokens; 4802 case TokenType::DoubleQuestionMark: 4803 return !m_forbid_coalesce_token; 4804 case TokenType::QuestionMarkPeriod: 4805 return !m_forbid_question_mark_period; 4806 case TokenType::ParenOpen: 4807 return !m_forbid_paren_open; 4808 case TokenType::Equals: 4809 return !m_forbid_equals; 4810 default: 4811 return true; 4812 } 4813} 4814 4815Parser::ForbiddenTokens Parser::ForbiddenTokens::merge(ForbiddenTokens other) const 4816{ 4817 ForbiddenTokens result = *this; 4818 result.m_forbid_in_token |= other.m_forbid_in_token; 4819 result.m_forbid_logical_tokens |= other.m_forbid_logical_tokens; 4820 result.m_forbid_coalesce_token |= other.m_forbid_coalesce_token; 4821 result.m_forbid_paren_open |= other.m_forbid_paren_open; 4822 result.m_forbid_question_mark_period |= other.m_forbid_question_mark_period; 4823 result.m_forbid_equals |= other.m_forbid_equals; 4824 return result; 4825} 4826 4827Parser::ForbiddenTokens Parser::ForbiddenTokens::forbid(std::initializer_list<TokenType> const& forbidden) const 4828{ 4829 ForbiddenTokens result = *this; 4830 result.forbid_tokens(forbidden); 4831 return result; 4832} 4833 4834template NonnullRefPtr<FunctionExpression> Parser::parse_function_node(u16, Optional<Position> const&); 4835template NonnullRefPtr<FunctionDeclaration> Parser::parse_function_node(u16, Optional<Position> const&); 4836 4837}