1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_PARSING_PARSER_BASE_H 6#define V8_PARSING_PARSER_BASE_H 7 8#include "src/ast/scopes.h" 9#include "src/bailout-reason.h" 10#include "src/base/hashmap.h" 11#include "src/messages.h" 12#include "src/parsing/expression-classifier.h" 13#include "src/parsing/func-name-inferrer.h" 14#include "src/parsing/scanner.h" 15#include "src/parsing/token.h" 16 17namespace v8 { 18namespace internal { 19 20 21enum FunctionNameValidity { 22 kFunctionNameIsStrictReserved, 23 kSkipFunctionNameCheck, 24 kFunctionNameValidityUnknown 25}; 26 27enum AllowLabelledFunctionStatement { 28 kAllowLabelledFunctionStatement, 29 kDisallowLabelledFunctionStatement, 30}; 31 32enum class FunctionBody { Normal, SingleExpression }; 33 34enum class ParseFunctionFlags { 35 kIsNormal = 0, 36 kIsGenerator = 1, 37 kIsAsync = 2, 38 kIsDefault = 4 39}; 40 41static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, 42 ParseFunctionFlags rhs) { 43 typedef unsigned char T; 44 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | 45 static_cast<T>(rhs)); 46} 47 48static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, 49 const ParseFunctionFlags& rhs) { 50 lhs = lhs | rhs; 51 return lhs; 52} 53 54static inline bool operator&(ParseFunctionFlags bitfield, 55 ParseFunctionFlags mask) { 56 typedef unsigned char T; 57 return static_cast<T>(bitfield) & static_cast<T>(mask); 58} 59 60enum class MethodKind { 61 Normal = 0, 62 Static = 1 << 0, 63 Generator = 1 << 1, 64 StaticGenerator = Static | Generator, 65 Async = 1 << 2, 66 StaticAsync = Static | Async, 67 68 /* Any non-ordinary method kinds */ 69 SpecialMask = Generator | Async 70}; 71 72inline bool IsValidMethodKind(MethodKind kind) { 73 return kind == MethodKind::Normal || kind == MethodKind::Static || 74 kind == MethodKind::Generator || kind == MethodKind::StaticGenerator || 75 kind == MethodKind::Async || kind == MethodKind::StaticAsync; 76} 77 78static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) { 79 typedef unsigned char T; 80 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs)); 81} 82 83static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) { 84 lhs = lhs | rhs; 85 DCHECK(IsValidMethodKind(lhs)); 86 return lhs; 87} 88 89static inline bool operator&(MethodKind bitfield, MethodKind mask) { 90 typedef unsigned char T; 91 return static_cast<T>(bitfield) & static_cast<T>(mask); 92} 93 94inline bool IsNormalMethod(MethodKind kind) { 95 return kind == MethodKind::Normal; 96} 97 98inline bool IsSpecialMethod(MethodKind kind) { 99 return kind & MethodKind::SpecialMask; 100} 101 102inline bool IsStaticMethod(MethodKind kind) { 103 return kind & MethodKind::Static; 104} 105 106inline bool IsGeneratorMethod(MethodKind kind) { 107 return kind & MethodKind::Generator; 108} 109 110inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; } 111 112struct FormalParametersBase { 113 explicit FormalParametersBase(Scope* scope) : scope(scope) {} 114 Scope* scope; 115 bool has_rest = false; 116 bool is_simple = true; 117 int materialized_literals_count = 0; 118}; 119 120 121// Common base class shared between parser and pre-parser. Traits encapsulate 122// the differences between Parser and PreParser: 123 124// - Return types: For example, Parser functions return Expression* and 125// PreParser functions return PreParserExpression. 126 127// - Creating parse tree nodes: Parser generates an AST during the recursive 128// descent. PreParser doesn't create a tree. Instead, it passes around minimal 129// data objects (PreParserExpression, PreParserIdentifier etc.) which contain 130// just enough data for the upper layer functions. PreParserFactory is 131// responsible for creating these dummy objects. It provides a similar kind of 132// interface as AstNodeFactory, so ParserBase doesn't need to care which one is 133// used. 134 135// - Miscellaneous other tasks interleaved with the recursive descent. For 136// example, Parser keeps track of which function literals should be marked as 137// pretenured, and PreParser doesn't care. 138 139// The traits are expected to contain the following typedefs: 140// struct Traits { 141// // In particular... 142// struct Type { 143// // Used by FunctionState and BlockState. 144// typedef Scope; 145// typedef GeneratorVariable; 146// // Return types for traversing functions. 147// typedef Identifier; 148// typedef Expression; 149// typedef FunctionLiteral; 150// typedef ClassLiteral; 151// typedef ObjectLiteralProperty; 152// typedef Literal; 153// typedef ExpressionList; 154// typedef PropertyList; 155// typedef FormalParameter; 156// typedef FormalParameters; 157// // For constructing objects returned by the traversing functions. 158// typedef Factory; 159// }; 160// // ... 161// }; 162 163template <typename Traits> 164class ParserBase : public Traits { 165 public: 166 // Shorten type names defined by Traits. 167 typedef typename Traits::Type::Expression ExpressionT; 168 typedef typename Traits::Type::Identifier IdentifierT; 169 typedef typename Traits::Type::FormalParameter FormalParameterT; 170 typedef typename Traits::Type::FormalParameters FormalParametersT; 171 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; 172 typedef typename Traits::Type::Literal LiteralT; 173 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; 174 typedef typename Traits::Type::StatementList StatementListT; 175 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; 176 177 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, 178 v8::Extension* extension, AstValueFactory* ast_value_factory, 179 ParserRecorder* log, typename Traits::Type::Parser this_object) 180 : Traits(this_object), 181 scope_(NULL), 182 function_state_(NULL), 183 extension_(extension), 184 fni_(NULL), 185 ast_value_factory_(ast_value_factory), 186 log_(log), 187 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 188 parsing_module_(false), 189 stack_limit_(stack_limit), 190 zone_(zone), 191 scanner_(scanner), 192 stack_overflow_(false), 193 allow_lazy_(false), 194 allow_natives_(false), 195 allow_tailcalls_(false), 196 allow_harmony_restrictive_declarations_(false), 197 allow_harmony_do_expressions_(false), 198 allow_harmony_for_in_(false), 199 allow_harmony_function_sent_(false), 200 allow_harmony_async_await_(false), 201 allow_harmony_restrictive_generators_(false) {} 202 203#define ALLOW_ACCESSORS(name) \ 204 bool allow_##name() const { return allow_##name##_; } \ 205 void set_allow_##name(bool allow) { allow_##name##_ = allow; } 206 207#define SCANNER_ACCESSORS(name) \ 208 bool allow_##name() const { return scanner_->allow_##name(); } \ 209 void set_allow_##name(bool allow) { \ 210 return scanner_->set_allow_##name(allow); \ 211 } 212 213 ALLOW_ACCESSORS(lazy); 214 ALLOW_ACCESSORS(natives); 215 ALLOW_ACCESSORS(tailcalls); 216 ALLOW_ACCESSORS(harmony_restrictive_declarations); 217 ALLOW_ACCESSORS(harmony_do_expressions); 218 ALLOW_ACCESSORS(harmony_for_in); 219 ALLOW_ACCESSORS(harmony_function_sent); 220 ALLOW_ACCESSORS(harmony_async_await); 221 ALLOW_ACCESSORS(harmony_restrictive_generators); 222 SCANNER_ACCESSORS(harmony_exponentiation_operator); 223 224#undef SCANNER_ACCESSORS 225#undef ALLOW_ACCESSORS 226 227 uintptr_t stack_limit() const { return stack_limit_; } 228 229 protected: 230 enum AllowRestrictedIdentifiers { 231 kAllowRestrictedIdentifiers, 232 kDontAllowRestrictedIdentifiers 233 }; 234 235 enum Mode { 236 PARSE_LAZILY, 237 PARSE_EAGERLY 238 }; 239 240 enum VariableDeclarationContext { 241 kStatementListItem, 242 kStatement, 243 kForStatement 244 }; 245 246 class Checkpoint; 247 class ObjectLiteralCheckerBase; 248 249 // --------------------------------------------------------------------------- 250 // FunctionState and BlockState together implement the parser's scope stack. 251 // The parser's current scope is in scope_. BlockState and FunctionState 252 // constructors push on the scope stack and the destructors pop. They are also 253 // used to hold the parser's per-function and per-block state. 254 class BlockState BASE_EMBEDDED { 255 public: 256 BlockState(Scope** scope_stack, Scope* scope) 257 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { 258 *scope_stack_ = scope; 259 } 260 ~BlockState() { *scope_stack_ = outer_scope_; } 261 262 private: 263 Scope** scope_stack_; 264 Scope* outer_scope_; 265 }; 266 267 struct DestructuringAssignment { 268 public: 269 DestructuringAssignment(ExpressionT expression, Scope* scope) 270 : assignment(expression), scope(scope) {} 271 272 ExpressionT assignment; 273 Scope* scope; 274 }; 275 276 class TailCallExpressionList { 277 public: 278 explicit TailCallExpressionList(Zone* zone) 279 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {} 280 281 const ZoneList<ExpressionT>& expressions() const { return expressions_; } 282 const Scanner::Location& location() const { return loc_; } 283 284 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; } 285 286 void Swap(TailCallExpressionList& other) { 287 expressions_.Swap(&other.expressions_); 288 std::swap(loc_, other.loc_); 289 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_); 290 } 291 292 void AddImplicitTailCall(ExpressionT expr) { 293 expressions_.Add(expr, zone_); 294 } 295 296 void AddExplicitTailCall(ExpressionT expr, const Scanner::Location& loc) { 297 if (!has_explicit_tail_calls()) { 298 loc_ = loc; 299 has_explicit_tail_calls_ = true; 300 } 301 expressions_.Add(expr, zone_); 302 } 303 304 void Append(const TailCallExpressionList& other) { 305 if (!has_explicit_tail_calls()) { 306 loc_ = other.loc_; 307 has_explicit_tail_calls_ = other.has_explicit_tail_calls_; 308 } 309 expressions_.AddAll(other.expressions_, zone_); 310 } 311 312 private: 313 Zone* zone_; 314 ZoneList<ExpressionT> expressions_; 315 Scanner::Location loc_; 316 bool has_explicit_tail_calls_; 317 }; 318 319 // Defines whether tail call expressions are allowed or not. 320 enum class ReturnExprContext { 321 // We are inside return statement which is allowed to contain tail call 322 // expressions. Tail call expressions are allowed. 323 kInsideValidReturnStatement, 324 325 // We are inside a block in which tail call expressions are allowed but 326 // not yet inside a return statement. 327 kInsideValidBlock, 328 329 // Tail call expressions are not allowed in the following blocks. 330 kInsideTryBlock, 331 kInsideForInOfBody, 332 }; 333 334 class FunctionState BASE_EMBEDDED { 335 public: 336 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, 337 Scope* scope, FunctionKind kind, 338 typename Traits::Type::Factory* factory); 339 ~FunctionState(); 340 341 int NextMaterializedLiteralIndex() { 342 return next_materialized_literal_index_++; 343 } 344 int materialized_literal_count() { 345 return next_materialized_literal_index_; 346 } 347 348 void SkipMaterializedLiterals(int count) { 349 next_materialized_literal_index_ += count; 350 } 351 352 void AddProperty() { expected_property_count_++; } 353 int expected_property_count() { return expected_property_count_; } 354 355 Scanner::Location this_location() const { return this_location_; } 356 Scanner::Location super_location() const { return super_location_; } 357 Scanner::Location return_location() const { return return_location_; } 358 void set_this_location(Scanner::Location location) { 359 this_location_ = location; 360 } 361 void set_super_location(Scanner::Location location) { 362 super_location_ = location; 363 } 364 void set_return_location(Scanner::Location location) { 365 return_location_ = location; 366 } 367 368 bool is_generator() const { return IsGeneratorFunction(kind_); } 369 bool is_async_function() const { return IsAsyncFunction(kind_); } 370 bool is_resumable() const { return is_generator() || is_async_function(); } 371 372 FunctionKind kind() const { return kind_; } 373 FunctionState* outer() const { return outer_function_state_; } 374 375 void set_generator_object_variable( 376 typename Traits::Type::GeneratorVariable* variable) { 377 DCHECK(variable != NULL); 378 DCHECK(is_resumable()); 379 generator_object_variable_ = variable; 380 } 381 typename Traits::Type::GeneratorVariable* generator_object_variable() 382 const { 383 return generator_object_variable_; 384 } 385 386 typename Traits::Type::Factory* factory() { return factory_; } 387 388 const ZoneList<DestructuringAssignment>& 389 destructuring_assignments_to_rewrite() const { 390 return destructuring_assignments_to_rewrite_; 391 } 392 393 TailCallExpressionList& tail_call_expressions() { 394 return tail_call_expressions_; 395 } 396 void AddImplicitTailCallExpression(ExpressionT expression) { 397 if (return_expr_context() == 398 ReturnExprContext::kInsideValidReturnStatement) { 399 tail_call_expressions_.AddImplicitTailCall(expression); 400 } 401 } 402 void AddExplicitTailCallExpression(ExpressionT expression, 403 const Scanner::Location& loc) { 404 DCHECK(expression->IsCall()); 405 if (return_expr_context() == 406 ReturnExprContext::kInsideValidReturnStatement) { 407 tail_call_expressions_.AddExplicitTailCall(expression, loc); 408 } 409 } 410 411 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() { 412 return &reported_errors_; 413 } 414 415 ReturnExprContext return_expr_context() const { 416 return return_expr_context_; 417 } 418 void set_return_expr_context(ReturnExprContext context) { 419 return_expr_context_ = context; 420 } 421 422 ZoneList<ExpressionT>* non_patterns_to_rewrite() { 423 return &non_patterns_to_rewrite_; 424 } 425 426 void next_function_is_parenthesized(bool parenthesized) { 427 next_function_is_parenthesized_ = parenthesized; 428 } 429 430 bool this_function_is_parenthesized() const { 431 return this_function_is_parenthesized_; 432 } 433 434 private: 435 void AddDestructuringAssignment(DestructuringAssignment pair) { 436 destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone()); 437 } 438 439 V8_INLINE Scope* scope() { return *scope_stack_; } 440 441 void AddNonPatternForRewriting(ExpressionT expr, bool* ok) { 442 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); 443 if (non_patterns_to_rewrite_.length() >= 444 std::numeric_limits<uint16_t>::max()) 445 *ok = false; 446 } 447 448 // Used to assign an index to each literal that needs materialization in 449 // the function. Includes regexp literals, and boilerplate for object and 450 // array literals. 451 int next_materialized_literal_index_; 452 453 // Properties count estimation. 454 int expected_property_count_; 455 456 // Location of most recent use of 'this' (invalid if none). 457 Scanner::Location this_location_; 458 459 // Location of most recent 'return' statement (invalid if none). 460 Scanner::Location return_location_; 461 462 // Location of call to the "super" constructor (invalid if none). 463 Scanner::Location super_location_; 464 465 FunctionKind kind_; 466 // For generators, this variable may hold the generator object. It variable 467 // is used by yield expressions and return statements. It is not necessary 468 // for generator functions to have this variable set. 469 Variable* generator_object_variable_; 470 471 FunctionState** function_state_stack_; 472 FunctionState* outer_function_state_; 473 Scope** scope_stack_; 474 Scope* outer_scope_; 475 476 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; 477 TailCallExpressionList tail_call_expressions_; 478 ReturnExprContext return_expr_context_; 479 ZoneList<ExpressionT> non_patterns_to_rewrite_; 480 481 ZoneList<typename ExpressionClassifier::Error> reported_errors_; 482 483 typename Traits::Type::Factory* factory_; 484 485 // If true, the next (and immediately following) function literal is 486 // preceded by a parenthesis. 487 bool next_function_is_parenthesized_; 488 489 // The value of the parents' next_function_is_parenthesized_, as it applies 490 // to this function. Filled in by constructor. 491 bool this_function_is_parenthesized_; 492 493 friend class ParserTraits; 494 friend class PreParserTraits; 495 friend class Checkpoint; 496 }; 497 498 // This scope sets current ReturnExprContext to given value. 499 class ReturnExprScope { 500 public: 501 explicit ReturnExprScope(FunctionState* function_state, 502 ReturnExprContext return_expr_context) 503 : function_state_(function_state), 504 sav_return_expr_context_(function_state->return_expr_context()) { 505 // Don't update context if we are requested to enable tail call 506 // expressions but current block does not allow them. 507 if (return_expr_context != 508 ReturnExprContext::kInsideValidReturnStatement || 509 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) { 510 function_state->set_return_expr_context(return_expr_context); 511 } 512 } 513 ~ReturnExprScope() { 514 function_state_->set_return_expr_context(sav_return_expr_context_); 515 } 516 517 private: 518 FunctionState* function_state_; 519 ReturnExprContext sav_return_expr_context_; 520 }; 521 522 // Collects all return expressions at tail call position in this scope 523 // to a separate list. 524 class CollectExpressionsInTailPositionToListScope { 525 public: 526 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, 527 TailCallExpressionList* list) 528 : function_state_(function_state), list_(list) { 529 function_state->tail_call_expressions().Swap(*list_); 530 } 531 ~CollectExpressionsInTailPositionToListScope() { 532 function_state_->tail_call_expressions().Swap(*list_); 533 } 534 535 private: 536 FunctionState* function_state_; 537 TailCallExpressionList* list_; 538 }; 539 540 // Annoyingly, arrow functions first parse as comma expressions, then when we 541 // see the => we have to go back and reinterpret the arguments as being formal 542 // parameters. To do so we need to reset some of the parser state back to 543 // what it was before the arguments were first seen. 544 class Checkpoint BASE_EMBEDDED { 545 public: 546 explicit Checkpoint(ParserBase* parser) { 547 function_state_ = parser->function_state_; 548 next_materialized_literal_index_ = 549 function_state_->next_materialized_literal_index_; 550 expected_property_count_ = function_state_->expected_property_count_; 551 } 552 553 void Restore(int* materialized_literal_index_delta) { 554 *materialized_literal_index_delta = 555 function_state_->next_materialized_literal_index_ - 556 next_materialized_literal_index_; 557 function_state_->next_materialized_literal_index_ = 558 next_materialized_literal_index_; 559 function_state_->expected_property_count_ = expected_property_count_; 560 } 561 562 private: 563 FunctionState* function_state_; 564 int next_materialized_literal_index_; 565 int expected_property_count_; 566 }; 567 568 class ParsingModeScope BASE_EMBEDDED { 569 public: 570 ParsingModeScope(ParserBase* parser, Mode mode) 571 : parser_(parser), 572 old_mode_(parser->mode()) { 573 parser_->mode_ = mode; 574 } 575 ~ParsingModeScope() { 576 parser_->mode_ = old_mode_; 577 } 578 579 private: 580 ParserBase* parser_; 581 Mode old_mode_; 582 }; 583 584 Scope* NewScope(Scope* parent, ScopeType scope_type) { 585 // Must always pass the function kind for FUNCTION_SCOPE. 586 DCHECK(scope_type != FUNCTION_SCOPE); 587 return NewScope(parent, scope_type, kNormalFunction); 588 } 589 590 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) { 591 DCHECK(ast_value_factory()); 592 Scope* result = new (zone()) 593 Scope(zone(), parent, scope_type, ast_value_factory(), kind); 594 result->Initialize(); 595 return result; 596 } 597 598 Scanner* scanner() const { return scanner_; } 599 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } 600 int position() { return scanner_->location().beg_pos; } 601 int peek_position() { return scanner_->peek_location().beg_pos; } 602 bool stack_overflow() const { return stack_overflow_; } 603 void set_stack_overflow() { stack_overflow_ = true; } 604 Mode mode() const { return mode_; } 605 Zone* zone() const { return zone_; } 606 607 INLINE(Token::Value peek()) { 608 if (stack_overflow_) return Token::ILLEGAL; 609 return scanner()->peek(); 610 } 611 612 INLINE(Token::Value PeekAhead()) { 613 if (stack_overflow_) return Token::ILLEGAL; 614 return scanner()->PeekAhead(); 615 } 616 617 INLINE(Token::Value Next()) { 618 if (stack_overflow_) return Token::ILLEGAL; 619 { 620 if (GetCurrentStackPosition() < stack_limit_) { 621 // Any further calls to Next or peek will return the illegal token. 622 // The current call must return the next token, which might already 623 // have been peek'ed. 624 stack_overflow_ = true; 625 } 626 } 627 return scanner()->Next(); 628 } 629 630 void Consume(Token::Value token) { 631 Token::Value next = Next(); 632 USE(next); 633 USE(token); 634 DCHECK(next == token); 635 } 636 637 bool Check(Token::Value token) { 638 Token::Value next = peek(); 639 if (next == token) { 640 Consume(next); 641 return true; 642 } 643 return false; 644 } 645 646 void Expect(Token::Value token, bool* ok) { 647 Token::Value next = Next(); 648 if (next != token) { 649 ReportUnexpectedToken(next); 650 *ok = false; 651 } 652 } 653 654 void ExpectSemicolon(bool* ok) { 655 // Check for automatic semicolon insertion according to 656 // the rules given in ECMA-262, section 7.9, page 21. 657 Token::Value tok = peek(); 658 if (tok == Token::SEMICOLON) { 659 Next(); 660 return; 661 } 662 if (scanner()->HasAnyLineTerminatorBeforeNext() || 663 tok == Token::RBRACE || 664 tok == Token::EOS) { 665 return; 666 } 667 Expect(Token::SEMICOLON, ok); 668 } 669 670 bool is_any_identifier(Token::Value token) { 671 return token == Token::IDENTIFIER || token == Token::ENUM || 672 token == Token::AWAIT || token == Token::ASYNC || 673 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET || 674 token == Token::STATIC || token == Token::YIELD; 675 } 676 bool peek_any_identifier() { return is_any_identifier(peek()); } 677 678 bool CheckContextualKeyword(Vector<const char> keyword) { 679 if (PeekContextualKeyword(keyword)) { 680 Consume(Token::IDENTIFIER); 681 return true; 682 } 683 return false; 684 } 685 686 bool PeekContextualKeyword(Vector<const char> keyword) { 687 return peek() == Token::IDENTIFIER && 688 scanner()->is_next_contextual_keyword(keyword); 689 } 690 691 void ExpectMetaProperty(Vector<const char> property_name, 692 const char* full_name, int pos, bool* ok); 693 694 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 695 Expect(Token::IDENTIFIER, ok); 696 if (!*ok) return; 697 if (!scanner()->is_literal_contextual_keyword(keyword)) { 698 ReportUnexpectedToken(scanner()->current_token()); 699 *ok = false; 700 } 701 } 702 703 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { 704 if (Check(Token::IN)) { 705 *visit_mode = ForEachStatement::ENUMERATE; 706 return true; 707 } else if (CheckContextualKeyword(CStrVector("of"))) { 708 *visit_mode = ForEachStatement::ITERATE; 709 return true; 710 } 711 return false; 712 } 713 714 bool PeekInOrOf() { 715 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); 716 } 717 718 // Checks whether an octal literal was last seen between beg_pos and end_pos. 719 // If so, reports an error. Only called for strict mode and template strings. 720 void CheckOctalLiteral(int beg_pos, int end_pos, 721 MessageTemplate::Template message, bool* ok) { 722 Scanner::Location octal = scanner()->octal_position(); 723 if (octal.IsValid() && beg_pos <= octal.beg_pos && 724 octal.end_pos <= end_pos) { 725 ReportMessageAt(octal, message); 726 scanner()->clear_octal_position(); 727 *ok = false; 728 } 729 } 730 // for now, this check just collects statistics. 731 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos, 732 int end_pos) { 733 Scanner::Location token_location = 734 scanner()->decimal_with_leading_zero_position(); 735 if (token_location.IsValid() && beg_pos <= token_location.beg_pos && 736 token_location.end_pos <= end_pos) { 737 scanner()->clear_decimal_with_leading_zero_position(); 738 if (use_counts != nullptr) 739 ++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode]; 740 } 741 } 742 743 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { 744 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, 745 ok); 746 } 747 748 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { 749 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, 750 ok); 751 } 752 753 void CheckDestructuringElement(ExpressionT element, 754 ExpressionClassifier* classifier, int beg_pos, 755 int end_pos); 756 757 // Checking the name of a function literal. This has to be done after parsing 758 // the function, since the function can declare itself strict. 759 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, 760 FunctionNameValidity function_name_validity, 761 const Scanner::Location& function_name_loc, bool* ok) { 762 if (function_name_validity == kSkipFunctionNameCheck) return; 763 // The function name needs to be checked in strict mode. 764 if (is_sloppy(language_mode)) return; 765 766 if (this->IsEvalOrArguments(function_name)) { 767 Traits::ReportMessageAt(function_name_loc, 768 MessageTemplate::kStrictEvalArguments); 769 *ok = false; 770 return; 771 } 772 if (function_name_validity == kFunctionNameIsStrictReserved) { 773 Traits::ReportMessageAt(function_name_loc, 774 MessageTemplate::kUnexpectedStrictReserved); 775 *ok = false; 776 return; 777 } 778 } 779 780 // Determine precedence of given token. 781 static int Precedence(Token::Value token, bool accept_IN) { 782 if (token == Token::IN && !accept_IN) 783 return 0; // 0 precedence will terminate binary expression parsing 784 return Token::Precedence(token); 785 } 786 787 typename Traits::Type::Factory* factory() { 788 return function_state_->factory(); 789 } 790 791 LanguageMode language_mode() { return scope_->language_mode(); } 792 bool is_generator() const { return function_state_->is_generator(); } 793 bool is_async_function() const { 794 return function_state_->is_async_function(); 795 } 796 bool is_resumable() const { return function_state_->is_resumable(); } 797 798 // Report syntax errors. 799 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, 800 ParseErrorType error_type = kSyntaxError) { 801 Scanner::Location source_location = scanner()->location(); 802 Traits::ReportMessageAt(source_location, message, arg, error_type); 803 } 804 805 void ReportMessageAt(Scanner::Location location, 806 MessageTemplate::Template message, 807 ParseErrorType error_type = kSyntaxError) { 808 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), 809 error_type); 810 } 811 812 void GetUnexpectedTokenMessage( 813 Token::Value token, MessageTemplate::Template* message, 814 Scanner::Location* location, const char** arg, 815 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); 816 817 void ReportUnexpectedToken(Token::Value token); 818 void ReportUnexpectedTokenAt( 819 Scanner::Location location, Token::Value token, 820 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); 821 822 void ReportClassifierError( 823 const typename ExpressionClassifier::Error& error) { 824 Traits::ReportMessageAt(error.location, error.message, error.arg, 825 error.type); 826 } 827 828 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { 829 if (!classifier->is_valid_expression() || 830 classifier->has_cover_initialized_name()) { 831 const Scanner::Location& a = classifier->expression_error().location; 832 const Scanner::Location& b = 833 classifier->cover_initialized_name_error().location; 834 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { 835 ReportClassifierError(classifier->cover_initialized_name_error()); 836 } else { 837 ReportClassifierError(classifier->expression_error()); 838 } 839 *ok = false; 840 } 841 } 842 843 void ValidateFormalParameterInitializer( 844 const ExpressionClassifier* classifier, bool* ok) { 845 if (!classifier->is_valid_formal_parameter_initializer()) { 846 ReportClassifierError(classifier->formal_parameter_initializer_error()); 847 *ok = false; 848 } 849 } 850 851 void ValidateBindingPattern(const ExpressionClassifier* classifier, 852 bool* ok) { 853 if (!classifier->is_valid_binding_pattern() || 854 !classifier->is_valid_async_binding_pattern()) { 855 const Scanner::Location& a = classifier->binding_pattern_error().location; 856 const Scanner::Location& b = 857 classifier->async_binding_pattern_error().location; 858 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { 859 ReportClassifierError(classifier->async_binding_pattern_error()); 860 } else { 861 ReportClassifierError(classifier->binding_pattern_error()); 862 } 863 *ok = false; 864 } 865 } 866 867 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, 868 bool* ok) { 869 if (!classifier->is_valid_assignment_pattern()) { 870 ReportClassifierError(classifier->assignment_pattern_error()); 871 *ok = false; 872 } 873 } 874 875 void ValidateFormalParameters(const ExpressionClassifier* classifier, 876 LanguageMode language_mode, 877 bool allow_duplicates, bool* ok) { 878 if (!allow_duplicates && 879 !classifier->is_valid_formal_parameter_list_without_duplicates()) { 880 ReportClassifierError(classifier->duplicate_formal_parameter_error()); 881 *ok = false; 882 } else if (is_strict(language_mode) && 883 !classifier->is_valid_strict_mode_formal_parameters()) { 884 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); 885 *ok = false; 886 } 887 } 888 889 bool IsValidArrowFormalParametersStart(Token::Value token) { 890 return is_any_identifier(token) || token == Token::LPAREN; 891 } 892 893 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, 894 ExpressionT expr, 895 bool parenthesized_formals, bool is_async, 896 bool* ok) { 897 if (classifier->is_valid_binding_pattern()) { 898 // A simple arrow formal parameter: IDENTIFIER => BODY. 899 if (!this->IsIdentifier(expr)) { 900 Traits::ReportMessageAt(scanner()->location(), 901 MessageTemplate::kUnexpectedToken, 902 Token::String(scanner()->current_token())); 903 *ok = false; 904 } 905 } else if (!classifier->is_valid_arrow_formal_parameters()) { 906 // If after parsing the expr, we see an error but the expression is 907 // neither a valid binding pattern nor a valid parenthesized formal 908 // parameter list, show the "arrow formal parameters" error if the formals 909 // started with a parenthesis, and the binding pattern error otherwise. 910 const typename ExpressionClassifier::Error& error = 911 parenthesized_formals ? classifier->arrow_formal_parameters_error() 912 : classifier->binding_pattern_error(); 913 ReportClassifierError(error); 914 *ok = false; 915 } 916 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { 917 const typename ExpressionClassifier::Error& error = 918 classifier->async_arrow_formal_parameters_error(); 919 ReportClassifierError(error); 920 *ok = false; 921 } 922 } 923 924 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { 925 if (!classifier->is_valid_let_pattern()) { 926 ReportClassifierError(classifier->let_pattern_error()); 927 *ok = false; 928 } 929 } 930 931 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, 932 bool* ok) { 933 if (FLAG_harmony_explicit_tailcalls && 934 classifier->has_tail_call_expression()) { 935 ReportClassifierError(classifier->tail_call_expression_error()); 936 *ok = false; 937 } 938 } 939 940 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { 941 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 942 const char* arg; 943 Scanner::Location location = scanner()->peek_location(); 944 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); 945 classifier->RecordExpressionError(location, message, arg); 946 } 947 948 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { 949 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 950 const char* arg; 951 Scanner::Location location = scanner()->peek_location(); 952 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); 953 classifier->RecordBindingPatternError(location, message, arg); 954 } 955 956 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { 957 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 958 const char* arg; 959 Scanner::Location location = scanner()->peek_location(); 960 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); 961 classifier->RecordArrowFormalParametersError(location, message, arg); 962 } 963 964 // Recursive descent functions: 965 966 // Parses an identifier that is valid for the current scope, in particular it 967 // fails on strict mode future reserved keywords in a strict scope. If 968 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 969 // "arguments" as identifier even in strict mode (this is needed in cases like 970 // "var foo = eval;"). 971 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); 972 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 973 bool* ok); 974 // Parses an identifier or a strict mode future reserved word, and indicate 975 // whether it is strict mode future reserved. Allows passing in is_generator 976 // for the case of parsing the identifier in a function expression, where the 977 // relevant "is_generator" bit is of the function being parsed, not the 978 // containing 979 // function. 980 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator, 981 bool* is_strict_reserved, 982 bool* ok); 983 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 984 bool* ok) { 985 return ParseIdentifierOrStrictReservedWord(this->is_generator(), 986 is_strict_reserved, ok); 987 } 988 989 IdentifierT ParseIdentifierName(bool* ok); 990 991 ExpressionT ParseRegExpLiteral(bool seen_equal, 992 ExpressionClassifier* classifier, bool* ok); 993 994 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 995 bool* is_async, bool* ok); 996 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 997 bool* ok) { 998 bool is_async; 999 return ParsePrimaryExpression(classifier, &is_async, ok); 1000 } 1001 ExpressionT ParseExpression(bool accept_IN, bool* ok); 1002 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, 1003 bool* ok); 1004 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); 1005 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 1006 bool* is_await, bool* is_computed_name, 1007 ExpressionClassifier* classifier, bool* ok); 1008 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 1009 ObjectLiteralPropertyT ParsePropertyDefinition( 1010 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 1011 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, 1012 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); 1013 typename Traits::Type::ExpressionList ParseArguments( 1014 Scanner::Location* first_spread_pos, bool maybe_arrow, 1015 ExpressionClassifier* classifier, bool* ok); 1016 typename Traits::Type::ExpressionList ParseArguments( 1017 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 1018 bool* ok) { 1019 return ParseArguments(first_spread_pos, false, classifier, ok); 1020 } 1021 1022 ExpressionT ParseAssignmentExpression(bool accept_IN, 1023 ExpressionClassifier* classifier, 1024 bool* ok); 1025 ExpressionT ParseYieldExpression(bool accept_IN, 1026 ExpressionClassifier* classifier, bool* ok); 1027 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, 1028 bool* ok); 1029 ExpressionT ParseConditionalExpression(bool accept_IN, 1030 ExpressionClassifier* classifier, 1031 bool* ok); 1032 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, 1033 ExpressionClassifier* classifier, bool* ok); 1034 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); 1035 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, 1036 bool* ok); 1037 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, 1038 bool* ok); 1039 ExpressionT ParseMemberWithNewPrefixesExpression( 1040 ExpressionClassifier* classifier, bool* is_async, bool* ok); 1041 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, 1042 bool* is_async, bool* ok); 1043 ExpressionT ParseMemberExpressionContinuation( 1044 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, 1045 bool* ok); 1046 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, 1047 const FormalParametersT& parameters, 1048 bool is_async, 1049 const ExpressionClassifier& classifier, 1050 bool* ok); 1051 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, 1052 ExpressionClassifier* classifier, bool* ok); 1053 void AddTemplateExpression(ExpressionT); 1054 ExpressionT ParseSuperExpression(bool is_new, 1055 ExpressionClassifier* classifier, bool* ok); 1056 ExpressionT ParseNewTargetExpression(bool* ok); 1057 1058 void ParseFormalParameter(FormalParametersT* parameters, 1059 ExpressionClassifier* classifier, bool* ok); 1060 void ParseFormalParameterList(FormalParametersT* parameters, 1061 ExpressionClassifier* classifier, bool* ok); 1062 void CheckArityRestrictions(int param_count, FunctionKind function_type, 1063 bool has_rest, int formals_start_pos, 1064 int formals_end_pos, bool* ok); 1065 1066 bool IsNextLetKeyword(); 1067 1068 // Checks if the expression is a valid reference expression (e.g., on the 1069 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1070 // we allow calls for web compatibility and rewrite them to a runtime throw. 1071 ExpressionT CheckAndRewriteReferenceExpression( 1072 ExpressionT expression, int beg_pos, int end_pos, 1073 MessageTemplate::Template message, bool* ok); 1074 ExpressionT CheckAndRewriteReferenceExpression( 1075 ExpressionT expression, int beg_pos, int end_pos, 1076 MessageTemplate::Template message, ParseErrorType type, bool* ok); 1077 1078 bool IsValidReferenceExpression(ExpressionT expression); 1079 1080 bool IsAssignableIdentifier(ExpressionT expression) { 1081 if (!Traits::IsIdentifier(expression)) return false; 1082 if (is_strict(language_mode()) && 1083 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { 1084 return false; 1085 } 1086 return true; 1087 } 1088 1089 bool IsValidPattern(ExpressionT expression) { 1090 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); 1091 } 1092 1093 // Keep track of eval() calls since they disable all local variable 1094 // optimizations. This checks if expression is an eval call, and if yes, 1095 // forwards the information to scope. 1096 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) { 1097 if (Traits::IsIdentifier(expression) && 1098 Traits::IsEval(Traits::AsIdentifier(expression))) { 1099 scope->RecordEvalCall(); 1100 if (is_sloppy(scope->language_mode())) { 1101 // For sloppy scopes we also have to record the call at function level, 1102 // in case it includes declarations that will be hoisted. 1103 scope->DeclarationScope()->RecordEvalCall(); 1104 } 1105 } 1106 } 1107 1108 // Used to validate property names in object literals and class literals 1109 enum PropertyKind { 1110 kAccessorProperty, 1111 kValueProperty, 1112 kMethodProperty 1113 }; 1114 1115 class ObjectLiteralCheckerBase { 1116 public: 1117 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} 1118 1119 virtual void CheckProperty(Token::Value property, PropertyKind type, 1120 MethodKind method_type, bool* ok) = 0; 1121 1122 virtual ~ObjectLiteralCheckerBase() {} 1123 1124 protected: 1125 ParserBase* parser() const { return parser_; } 1126 Scanner* scanner() const { return parser_->scanner(); } 1127 1128 private: 1129 ParserBase* parser_; 1130 }; 1131 1132 // Validation per ES6 object literals. 1133 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { 1134 public: 1135 explicit ObjectLiteralChecker(ParserBase* parser) 1136 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} 1137 1138 void CheckProperty(Token::Value property, PropertyKind type, 1139 MethodKind method_type, bool* ok) override; 1140 1141 private: 1142 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } 1143 1144 bool has_seen_proto_; 1145 }; 1146 1147 // Validation per ES6 class literals. 1148 class ClassLiteralChecker : public ObjectLiteralCheckerBase { 1149 public: 1150 explicit ClassLiteralChecker(ParserBase* parser) 1151 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} 1152 1153 void CheckProperty(Token::Value property, PropertyKind type, 1154 MethodKind method_type, bool* ok) override; 1155 1156 private: 1157 bool IsConstructor() { 1158 return this->scanner()->LiteralMatches("constructor", 11); 1159 } 1160 bool IsPrototype() { 1161 return this->scanner()->LiteralMatches("prototype", 9); 1162 } 1163 1164 bool has_seen_constructor_; 1165 }; 1166 1167 Scope* scope_; // Scope stack. 1168 FunctionState* function_state_; // Function state stack. 1169 v8::Extension* extension_; 1170 FuncNameInferrer* fni_; 1171 AstValueFactory* ast_value_factory_; // Not owned. 1172 ParserRecorder* log_; 1173 Mode mode_; 1174 bool parsing_module_; 1175 uintptr_t stack_limit_; 1176 1177 private: 1178 Zone* zone_; 1179 1180 Scanner* scanner_; 1181 bool stack_overflow_; 1182 1183 bool allow_lazy_; 1184 bool allow_natives_; 1185 bool allow_tailcalls_; 1186 bool allow_harmony_restrictive_declarations_; 1187 bool allow_harmony_do_expressions_; 1188 bool allow_harmony_for_in_; 1189 bool allow_harmony_function_sent_; 1190 bool allow_harmony_async_await_; 1191 bool allow_harmony_restrictive_generators_; 1192}; 1193 1194template <class Traits> 1195ParserBase<Traits>::FunctionState::FunctionState( 1196 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, 1197 FunctionKind kind, typename Traits::Type::Factory* factory) 1198 : next_materialized_literal_index_(0), 1199 expected_property_count_(0), 1200 this_location_(Scanner::Location::invalid()), 1201 return_location_(Scanner::Location::invalid()), 1202 super_location_(Scanner::Location::invalid()), 1203 kind_(kind), 1204 generator_object_variable_(NULL), 1205 function_state_stack_(function_state_stack), 1206 outer_function_state_(*function_state_stack), 1207 scope_stack_(scope_stack), 1208 outer_scope_(*scope_stack), 1209 destructuring_assignments_to_rewrite_(16, scope->zone()), 1210 tail_call_expressions_(scope->zone()), 1211 return_expr_context_(ReturnExprContext::kInsideValidBlock), 1212 non_patterns_to_rewrite_(0, scope->zone()), 1213 reported_errors_(16, scope->zone()), 1214 factory_(factory), 1215 next_function_is_parenthesized_(false), 1216 this_function_is_parenthesized_(false) { 1217 *scope_stack_ = scope; 1218 *function_state_stack = this; 1219 if (outer_function_state_) { 1220 this_function_is_parenthesized_ = 1221 outer_function_state_->next_function_is_parenthesized_; 1222 outer_function_state_->next_function_is_parenthesized_ = false; 1223 } 1224} 1225 1226 1227template <class Traits> 1228ParserBase<Traits>::FunctionState::~FunctionState() { 1229 *scope_stack_ = outer_scope_; 1230 *function_state_stack_ = outer_function_state_; 1231} 1232 1233template <class Traits> 1234void ParserBase<Traits>::GetUnexpectedTokenMessage( 1235 Token::Value token, MessageTemplate::Template* message, 1236 Scanner::Location* location, const char** arg, 1237 MessageTemplate::Template default_) { 1238 *arg = nullptr; 1239 switch (token) { 1240 case Token::EOS: 1241 *message = MessageTemplate::kUnexpectedEOS; 1242 break; 1243 case Token::SMI: 1244 case Token::NUMBER: 1245 *message = MessageTemplate::kUnexpectedTokenNumber; 1246 break; 1247 case Token::STRING: 1248 *message = MessageTemplate::kUnexpectedTokenString; 1249 break; 1250 case Token::IDENTIFIER: 1251 *message = MessageTemplate::kUnexpectedTokenIdentifier; 1252 break; 1253 case Token::AWAIT: 1254 case Token::ENUM: 1255 *message = MessageTemplate::kUnexpectedReserved; 1256 break; 1257 case Token::LET: 1258 case Token::STATIC: 1259 case Token::YIELD: 1260 case Token::FUTURE_STRICT_RESERVED_WORD: 1261 *message = is_strict(language_mode()) 1262 ? MessageTemplate::kUnexpectedStrictReserved 1263 : MessageTemplate::kUnexpectedTokenIdentifier; 1264 break; 1265 case Token::TEMPLATE_SPAN: 1266 case Token::TEMPLATE_TAIL: 1267 *message = MessageTemplate::kUnexpectedTemplateString; 1268 break; 1269 case Token::ESCAPED_STRICT_RESERVED_WORD: 1270 case Token::ESCAPED_KEYWORD: 1271 *message = MessageTemplate::kInvalidEscapedReservedWord; 1272 break; 1273 case Token::ILLEGAL: 1274 if (scanner()->has_error()) { 1275 *message = scanner()->error(); 1276 *location = scanner()->error_location(); 1277 } else { 1278 *message = MessageTemplate::kInvalidOrUnexpectedToken; 1279 } 1280 break; 1281 default: 1282 const char* name = Token::String(token); 1283 DCHECK(name != NULL); 1284 *arg = name; 1285 break; 1286 } 1287} 1288 1289 1290template <class Traits> 1291void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1292 return ReportUnexpectedTokenAt(scanner_->location(), token); 1293} 1294 1295 1296template <class Traits> 1297void ParserBase<Traits>::ReportUnexpectedTokenAt( 1298 Scanner::Location source_location, Token::Value token, 1299 MessageTemplate::Template message) { 1300 const char* arg; 1301 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); 1302 Traits::ReportMessageAt(source_location, message, arg); 1303} 1304 1305 1306template <class Traits> 1307typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1308 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { 1309 ExpressionClassifier classifier(this); 1310 auto result = ParseAndClassifyIdentifier(&classifier, ok); 1311 if (!*ok) return Traits::EmptyIdentifier(); 1312 1313 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { 1314 ValidateAssignmentPattern(&classifier, ok); 1315 if (!*ok) return Traits::EmptyIdentifier(); 1316 ValidateBindingPattern(&classifier, ok); 1317 if (!*ok) return Traits::EmptyIdentifier(); 1318 } 1319 1320 return result; 1321} 1322 1323 1324template <class Traits> 1325typename ParserBase<Traits>::IdentifierT 1326ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 1327 bool* ok) { 1328 Token::Value next = Next(); 1329 if (next == Token::IDENTIFIER || next == Token::ASYNC || 1330 (next == Token::AWAIT && !parsing_module_)) { 1331 IdentifierT name = this->GetSymbol(scanner()); 1332 // When this function is used to read a formal parameter, we don't always 1333 // know whether the function is going to be strict or sloppy. Indeed for 1334 // arrow functions we don't always know that the identifier we are reading 1335 // is actually a formal parameter. Therefore besides the errors that we 1336 // must detect because we know we're in strict mode, we also record any 1337 // error that we might make in the future once we know the language mode. 1338 if (this->IsEval(name)) { 1339 classifier->RecordStrictModeFormalParameterError( 1340 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1341 if (is_strict(language_mode())) { 1342 classifier->RecordBindingPatternError( 1343 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1344 } 1345 } 1346 if (this->IsArguments(name)) { 1347 scope_->RecordArgumentsUsage(); 1348 classifier->RecordStrictModeFormalParameterError( 1349 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1350 if (is_strict(language_mode())) { 1351 classifier->RecordBindingPatternError( 1352 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1353 } 1354 } 1355 if (this->IsAwait(name)) { 1356 if (is_async_function()) { 1357 classifier->RecordPatternError( 1358 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); 1359 } 1360 classifier->RecordAsyncArrowFormalParametersError( 1361 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); 1362 } 1363 1364 if (classifier->duplicate_finder() != nullptr && 1365 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1366 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1367 } 1368 return name; 1369 } else if (is_sloppy(language_mode()) && 1370 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1371 next == Token::ESCAPED_STRICT_RESERVED_WORD || 1372 next == Token::LET || next == Token::STATIC || 1373 (next == Token::YIELD && !is_generator()))) { 1374 classifier->RecordStrictModeFormalParameterError( 1375 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); 1376 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && 1377 is_strict(language_mode())) { 1378 ReportUnexpectedToken(next); 1379 *ok = false; 1380 return Traits::EmptyIdentifier(); 1381 } 1382 if (next == Token::LET || 1383 (next == Token::ESCAPED_STRICT_RESERVED_WORD && 1384 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { 1385 classifier->RecordLetPatternError(scanner()->location(), 1386 MessageTemplate::kLetInLexicalBinding); 1387 } 1388 return this->GetSymbol(scanner()); 1389 } else { 1390 this->ReportUnexpectedToken(next); 1391 *ok = false; 1392 return Traits::EmptyIdentifier(); 1393 } 1394} 1395 1396 1397template <class Traits> 1398typename ParserBase<Traits>::IdentifierT 1399ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( 1400 bool is_generator, bool* is_strict_reserved, bool* ok) { 1401 Token::Value next = Next(); 1402 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) || 1403 next == Token::ASYNC) { 1404 *is_strict_reserved = false; 1405 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1406 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { 1407 *is_strict_reserved = true; 1408 } else { 1409 ReportUnexpectedToken(next); 1410 *ok = false; 1411 return Traits::EmptyIdentifier(); 1412 } 1413 1414 IdentifierT name = this->GetSymbol(scanner()); 1415 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1416 return name; 1417} 1418 1419template <class Traits> 1420typename ParserBase<Traits>::IdentifierT 1421ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1422 Token::Value next = Next(); 1423 if (next != Token::IDENTIFIER && next != Token::ASYNC && 1424 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && 1425 next != Token::STATIC && next != Token::YIELD && 1426 next != Token::FUTURE_STRICT_RESERVED_WORD && 1427 next != Token::ESCAPED_KEYWORD && 1428 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1429 this->ReportUnexpectedToken(next); 1430 *ok = false; 1431 return Traits::EmptyIdentifier(); 1432 } 1433 1434 IdentifierT name = this->GetSymbol(scanner()); 1435 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1436 return name; 1437} 1438 1439 1440template <class Traits> 1441typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( 1442 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { 1443 int pos = peek_position(); 1444 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1445 Next(); 1446 ReportMessage(MessageTemplate::kUnterminatedRegExp); 1447 *ok = false; 1448 return Traits::EmptyExpression(); 1449 } 1450 1451 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1452 1453 IdentifierT js_pattern = this->GetNextSymbol(scanner()); 1454 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); 1455 if (flags.IsNothing()) { 1456 Next(); 1457 ReportMessage(MessageTemplate::kMalformedRegExpFlags); 1458 *ok = false; 1459 return Traits::EmptyExpression(); 1460 } 1461 int js_flags = flags.FromJust(); 1462 Next(); 1463 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1464} 1465 1466 1467#define CHECK_OK ok); \ 1468 if (!*ok) return this->EmptyExpression(); \ 1469 ((void)0 1470#define DUMMY ) // to make indentation work 1471#undef DUMMY 1472 1473// Used in functions where the return type is not ExpressionT. 1474#define CHECK_OK_CUSTOM(x) ok); \ 1475 if (!*ok) return this->x(); \ 1476 ((void)0 1477#define DUMMY ) // to make indentation work 1478#undef DUMMY 1479 1480template <class Traits> 1481typename ParserBase<Traits>::ExpressionT 1482ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, 1483 bool* is_async, bool* ok) { 1484 // PrimaryExpression :: 1485 // 'this' 1486 // 'null' 1487 // 'true' 1488 // 'false' 1489 // Identifier 1490 // Number 1491 // String 1492 // ArrayLiteral 1493 // ObjectLiteral 1494 // RegExpLiteral 1495 // ClassLiteral 1496 // '(' Expression ')' 1497 // TemplateLiteral 1498 // do Block 1499 // AsyncFunctionExpression 1500 1501 int beg_pos = peek_position(); 1502 switch (peek()) { 1503 case Token::THIS: { 1504 BindingPatternUnexpectedToken(classifier); 1505 Consume(Token::THIS); 1506 return this->ThisExpression(scope_, factory(), beg_pos); 1507 } 1508 1509 case Token::NULL_LITERAL: 1510 case Token::TRUE_LITERAL: 1511 case Token::FALSE_LITERAL: 1512 BindingPatternUnexpectedToken(classifier); 1513 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1514 case Token::SMI: 1515 case Token::NUMBER: 1516 BindingPatternUnexpectedToken(classifier); 1517 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1518 1519 case Token::ASYNC: 1520 if (allow_harmony_async_await() && 1521 !scanner()->HasAnyLineTerminatorAfterNext() && 1522 PeekAhead() == Token::FUNCTION) { 1523 Consume(Token::ASYNC); 1524 return this->ParseAsyncFunctionExpression(CHECK_OK); 1525 } 1526 // CoverCallExpressionAndAsyncArrowHead 1527 *is_async = true; 1528 /* falls through */ 1529 case Token::IDENTIFIER: 1530 case Token::LET: 1531 case Token::STATIC: 1532 case Token::YIELD: 1533 case Token::AWAIT: 1534 case Token::ESCAPED_STRICT_RESERVED_WORD: 1535 case Token::FUTURE_STRICT_RESERVED_WORD: { 1536 // Using eval or arguments in this context is OK even in strict mode. 1537 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 1538 return this->ExpressionFromIdentifier( 1539 name, beg_pos, scanner()->location().end_pos, scope_, factory()); 1540 } 1541 1542 case Token::STRING: { 1543 BindingPatternUnexpectedToken(classifier); 1544 Consume(Token::STRING); 1545 return this->ExpressionFromString(beg_pos, scanner(), factory()); 1546 } 1547 1548 case Token::ASSIGN_DIV: 1549 classifier->RecordBindingPatternError( 1550 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); 1551 return this->ParseRegExpLiteral(true, classifier, ok); 1552 1553 case Token::DIV: 1554 classifier->RecordBindingPatternError( 1555 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); 1556 return this->ParseRegExpLiteral(false, classifier, ok); 1557 1558 case Token::LBRACK: 1559 return this->ParseArrayLiteral(classifier, ok); 1560 1561 case Token::LBRACE: 1562 return this->ParseObjectLiteral(classifier, ok); 1563 1564 case Token::LPAREN: { 1565 // Arrow function formal parameters are either a single identifier or a 1566 // list of BindingPattern productions enclosed in parentheses. 1567 // Parentheses are not valid on the LHS of a BindingPattern, so we use the 1568 // is_valid_binding_pattern() check to detect multiple levels of 1569 // parenthesization. 1570 bool pattern_error = !classifier->is_valid_binding_pattern(); 1571 classifier->RecordPatternError(scanner()->peek_location(), 1572 MessageTemplate::kUnexpectedToken, 1573 Token::String(Token::LPAREN)); 1574 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); 1575 Consume(Token::LPAREN); 1576 if (Check(Token::RPAREN)) { 1577 // ()=>x. The continuation that looks for the => is in 1578 // ParseAssignmentExpression. 1579 classifier->RecordExpressionError(scanner()->location(), 1580 MessageTemplate::kUnexpectedToken, 1581 Token::String(Token::RPAREN)); 1582 return factory()->NewEmptyParentheses(beg_pos); 1583 } else if (Check(Token::ELLIPSIS)) { 1584 // (...x)=>x. The continuation that looks for the => is in 1585 // ParseAssignmentExpression. 1586 int ellipsis_pos = position(); 1587 int expr_pos = peek_position(); 1588 classifier->RecordExpressionError(scanner()->location(), 1589 MessageTemplate::kUnexpectedToken, 1590 Token::String(Token::ELLIPSIS)); 1591 classifier->RecordNonSimpleParameter(); 1592 ExpressionClassifier binding_classifier(this); 1593 ExpressionT expr = this->ParseAssignmentExpression( 1594 true, &binding_classifier, CHECK_OK); 1595 classifier->Accumulate(&binding_classifier, 1596 ExpressionClassifier::AllProductions); 1597 if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) { 1598 classifier->RecordArrowFormalParametersError( 1599 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), 1600 MessageTemplate::kInvalidRestParameter); 1601 } 1602 if (peek() == Token::COMMA) { 1603 ReportMessageAt(scanner()->peek_location(), 1604 MessageTemplate::kParamAfterRest); 1605 *ok = false; 1606 return this->EmptyExpression(); 1607 } 1608 Expect(Token::RPAREN, CHECK_OK); 1609 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); 1610 } 1611 // Heuristically try to detect immediately called functions before 1612 // seeing the call parentheses. 1613 function_state_->next_function_is_parenthesized(peek() == 1614 Token::FUNCTION); 1615 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); 1616 Expect(Token::RPAREN, CHECK_OK); 1617 return expr; 1618 } 1619 1620 case Token::CLASS: { 1621 BindingPatternUnexpectedToken(classifier); 1622 Consume(Token::CLASS); 1623 int class_token_position = position(); 1624 IdentifierT name = this->EmptyIdentifier(); 1625 bool is_strict_reserved_name = false; 1626 Scanner::Location class_name_location = Scanner::Location::invalid(); 1627 if (peek_any_identifier()) { 1628 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 1629 CHECK_OK); 1630 class_name_location = scanner()->location(); 1631 } 1632 return this->ParseClassLiteral(classifier, name, class_name_location, 1633 is_strict_reserved_name, 1634 class_token_position, ok); 1635 } 1636 1637 case Token::TEMPLATE_SPAN: 1638 case Token::TEMPLATE_TAIL: 1639 BindingPatternUnexpectedToken(classifier); 1640 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, 1641 classifier, ok); 1642 1643 case Token::MOD: 1644 if (allow_natives() || extension_ != NULL) { 1645 BindingPatternUnexpectedToken(classifier); 1646 return this->ParseV8Intrinsic(ok); 1647 } 1648 break; 1649 1650 case Token::DO: 1651 if (allow_harmony_do_expressions()) { 1652 BindingPatternUnexpectedToken(classifier); 1653 return Traits::ParseDoExpression(ok); 1654 } 1655 break; 1656 1657 default: 1658 break; 1659 } 1660 1661 ReportUnexpectedToken(Next()); 1662 *ok = false; 1663 return this->EmptyExpression(); 1664} 1665 1666 1667template <class Traits> 1668typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1669 bool accept_IN, bool* ok) { 1670 ExpressionClassifier classifier(this); 1671 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); 1672 Traits::RewriteNonPattern(&classifier, CHECK_OK); 1673 return result; 1674} 1675 1676template <class Traits> 1677typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1678 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 1679 // Expression :: 1680 // AssignmentExpression 1681 // Expression ',' AssignmentExpression 1682 1683 ExpressionT result = this->EmptyExpression(); 1684 { 1685 ExpressionClassifier binding_classifier(this); 1686 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier, 1687 CHECK_OK); 1688 classifier->Accumulate(&binding_classifier, 1689 ExpressionClassifier::AllProductions); 1690 } 1691 bool is_simple_parameter_list = this->IsIdentifier(result); 1692 bool seen_rest = false; 1693 while (peek() == Token::COMMA) { 1694 CheckNoTailCallExpressions(classifier, CHECK_OK); 1695 if (seen_rest) { 1696 // At this point the production can't possibly be valid, but we don't know 1697 // which error to signal. 1698 classifier->RecordArrowFormalParametersError( 1699 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 1700 } 1701 Consume(Token::COMMA); 1702 bool is_rest = false; 1703 if (peek() == Token::ELLIPSIS) { 1704 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 1705 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 1706 // valid expression or binding pattern. 1707 ExpressionUnexpectedToken(classifier); 1708 BindingPatternUnexpectedToken(classifier); 1709 Consume(Token::ELLIPSIS); 1710 seen_rest = is_rest = true; 1711 } 1712 int pos = position(), expr_pos = peek_position(); 1713 ExpressionClassifier binding_classifier(this); 1714 ExpressionT right = this->ParseAssignmentExpression( 1715 accept_IN, &binding_classifier, CHECK_OK); 1716 classifier->Accumulate(&binding_classifier, 1717 ExpressionClassifier::AllProductions); 1718 if (is_rest) { 1719 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { 1720 classifier->RecordArrowFormalParametersError( 1721 Scanner::Location(pos, scanner()->location().end_pos), 1722 MessageTemplate::kInvalidRestParameter); 1723 } 1724 right = factory()->NewSpread(right, pos, expr_pos); 1725 } 1726 is_simple_parameter_list = 1727 is_simple_parameter_list && this->IsIdentifier(right); 1728 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 1729 } 1730 if (!is_simple_parameter_list || seen_rest) { 1731 classifier->RecordNonSimpleParameter(); 1732 } 1733 1734 return result; 1735} 1736 1737 1738template <class Traits> 1739typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 1740 ExpressionClassifier* classifier, bool* ok) { 1741 // ArrayLiteral :: 1742 // '[' Expression? (',' Expression?)* ']' 1743 1744 int pos = peek_position(); 1745 typename Traits::Type::ExpressionList values = 1746 this->NewExpressionList(4, zone_); 1747 int first_spread_index = -1; 1748 Expect(Token::LBRACK, CHECK_OK); 1749 while (peek() != Token::RBRACK) { 1750 ExpressionT elem = this->EmptyExpression(); 1751 if (peek() == Token::COMMA) { 1752 elem = this->GetLiteralTheHole(peek_position(), factory()); 1753 } else if (peek() == Token::ELLIPSIS) { 1754 int start_pos = peek_position(); 1755 Consume(Token::ELLIPSIS); 1756 int expr_pos = peek_position(); 1757 ExpressionT argument = 1758 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 1759 CheckNoTailCallExpressions(classifier, CHECK_OK); 1760 elem = factory()->NewSpread(argument, start_pos, expr_pos); 1761 1762 if (first_spread_index < 0) { 1763 first_spread_index = values->length(); 1764 } 1765 1766 if (argument->IsAssignment()) { 1767 classifier->RecordPatternError( 1768 Scanner::Location(start_pos, scanner()->location().end_pos), 1769 MessageTemplate::kInvalidDestructuringTarget); 1770 } else { 1771 CheckDestructuringElement(argument, classifier, start_pos, 1772 scanner()->location().end_pos); 1773 } 1774 1775 if (peek() == Token::COMMA) { 1776 classifier->RecordPatternError( 1777 Scanner::Location(start_pos, scanner()->location().end_pos), 1778 MessageTemplate::kElementAfterRest); 1779 } 1780 } else { 1781 int beg_pos = peek_position(); 1782 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); 1783 CheckNoTailCallExpressions(classifier, CHECK_OK); 1784 CheckDestructuringElement(elem, classifier, beg_pos, 1785 scanner()->location().end_pos); 1786 } 1787 values->Add(elem, zone_); 1788 if (peek() != Token::RBRACK) { 1789 Expect(Token::COMMA, CHECK_OK); 1790 } 1791 } 1792 Expect(Token::RBRACK, CHECK_OK); 1793 1794 // Update the scope information before the pre-parsing bailout. 1795 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1796 1797 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, 1798 literal_index, pos); 1799 if (first_spread_index >= 0) { 1800 result = factory()->NewRewritableExpression(result); 1801 Traits::QueueNonPatternForRewriting(result, ok); 1802 if (!*ok) { 1803 // If the non-pattern rewriting mechanism is used in the future for 1804 // rewriting other things than spreads, this error message will have 1805 // to change. Also, this error message will never appear while pre- 1806 // parsing (this is OK, as it is an implementation limitation). 1807 ReportMessage(MessageTemplate::kTooManySpreads); 1808 return this->EmptyExpression(); 1809 } 1810 } 1811 return result; 1812} 1813 1814template <class Traits> 1815typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( 1816 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await, 1817 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { 1818 Token::Value token = peek(); 1819 int pos = peek_position(); 1820 1821 // For non computed property names we normalize the name a bit: 1822 // 1823 // "12" -> 12 1824 // 12.3 -> "12.3" 1825 // 12.30 -> "12.3" 1826 // identifier -> "identifier" 1827 // 1828 // This is important because we use the property name as a key in a hash 1829 // table when we compute constant properties. 1830 switch (token) { 1831 case Token::STRING: 1832 Consume(Token::STRING); 1833 *name = this->GetSymbol(scanner()); 1834 break; 1835 1836 case Token::SMI: 1837 Consume(Token::SMI); 1838 *name = this->GetNumberAsSymbol(scanner()); 1839 break; 1840 1841 case Token::NUMBER: 1842 Consume(Token::NUMBER); 1843 *name = this->GetNumberAsSymbol(scanner()); 1844 break; 1845 1846 case Token::LBRACK: { 1847 *is_computed_name = true; 1848 Consume(Token::LBRACK); 1849 ExpressionClassifier computed_name_classifier(this); 1850 ExpressionT expression = 1851 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); 1852 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); 1853 classifier->Accumulate(&computed_name_classifier, 1854 ExpressionClassifier::ExpressionProductions); 1855 Expect(Token::RBRACK, CHECK_OK); 1856 return expression; 1857 } 1858 1859 default: 1860 *name = ParseIdentifierName(CHECK_OK); 1861 scanner()->IsGetOrSet(is_get, is_set); 1862 if (this->IsAwait(*name)) { 1863 *is_await = true; 1864 } 1865 break; 1866 } 1867 1868 uint32_t index; 1869 return this->IsArrayIndex(*name, &index) 1870 ? factory()->NewNumberLiteral(index, pos) 1871 : factory()->NewStringLiteral(*name, pos); 1872} 1873 1874template <class Traits> 1875typename ParserBase<Traits>::ObjectLiteralPropertyT 1876ParserBase<Traits>::ParsePropertyDefinition( 1877 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 1878 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, 1879 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { 1880 DCHECK(!in_class || IsStaticMethod(method_kind) || 1881 has_seen_constructor != nullptr); 1882 ExpressionT value = this->EmptyExpression(); 1883 bool is_get = false; 1884 bool is_set = false; 1885 bool is_await = false; 1886 bool is_generator = Check(Token::MUL); 1887 bool is_async = false; 1888 const bool is_static = IsStaticMethod(method_kind); 1889 1890 Token::Value name_token = peek(); 1891 1892 if (is_generator) { 1893 method_kind |= MethodKind::Generator; 1894 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && 1895 !scanner()->HasAnyLineTerminatorAfterNext() && 1896 PeekAhead() != Token::LPAREN && PeekAhead()) { 1897 is_async = true; 1898 } 1899 1900 int next_beg_pos = scanner()->peek_location().beg_pos; 1901 int next_end_pos = scanner()->peek_location().end_pos; 1902 ExpressionT name_expression = ParsePropertyName( 1903 name, &is_get, &is_set, &is_await, is_computed_name, classifier, 1904 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1905 1906 if (fni_ != nullptr && !*is_computed_name) { 1907 this->PushLiteralName(fni_, *name); 1908 } 1909 1910 if (!in_class && !is_generator) { 1911 DCHECK(!IsStaticMethod(method_kind)); 1912 1913 if (peek() == Token::COLON) { 1914 // PropertyDefinition 1915 // PropertyName ':' AssignmentExpression 1916 if (!*is_computed_name) { 1917 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal, 1918 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1919 } 1920 Consume(Token::COLON); 1921 int beg_pos = peek_position(); 1922 value = this->ParseAssignmentExpression( 1923 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1924 CheckDestructuringElement(value, classifier, beg_pos, 1925 scanner()->location().end_pos); 1926 1927 return factory()->NewObjectLiteralProperty(name_expression, value, 1928 is_static, *is_computed_name); 1929 } 1930 1931 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), 1932 parsing_module_) && 1933 (peek() == Token::COMMA || peek() == Token::RBRACE || 1934 peek() == Token::ASSIGN)) { 1935 // PropertyDefinition 1936 // IdentifierReference 1937 // CoverInitializedName 1938 // 1939 // CoverInitializedName 1940 // IdentifierReference Initializer? 1941 if (classifier->duplicate_finder() != nullptr && 1942 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1943 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1944 } 1945 if (name_token == Token::LET) { 1946 classifier->RecordLetPatternError( 1947 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 1948 } 1949 if (is_await) { 1950 if (is_async_function()) { 1951 classifier->RecordPatternError( 1952 Scanner::Location(next_beg_pos, next_end_pos), 1953 MessageTemplate::kAwaitBindingIdentifier); 1954 } else { 1955 classifier->RecordAsyncArrowFormalParametersError( 1956 Scanner::Location(next_beg_pos, next_end_pos), 1957 MessageTemplate::kAwaitBindingIdentifier); 1958 } 1959 } 1960 ExpressionT lhs = this->ExpressionFromIdentifier( 1961 *name, next_beg_pos, next_end_pos, scope_, factory()); 1962 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); 1963 1964 if (peek() == Token::ASSIGN) { 1965 Consume(Token::ASSIGN); 1966 ExpressionClassifier rhs_classifier(this); 1967 ExpressionT rhs = this->ParseAssignmentExpression( 1968 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1969 Traits::RewriteNonPattern(&rhs_classifier, 1970 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1971 classifier->Accumulate(&rhs_classifier, 1972 ExpressionClassifier::ExpressionProductions); 1973 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, 1974 RelocInfo::kNoPosition); 1975 classifier->RecordCoverInitializedNameError( 1976 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 1977 MessageTemplate::kInvalidCoverInitializedName); 1978 1979 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); 1980 } else { 1981 value = lhs; 1982 } 1983 1984 return factory()->NewObjectLiteralProperty( 1985 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, 1986 false); 1987 } 1988 } 1989 1990 // Method definitions are never valid in patterns. 1991 classifier->RecordPatternError( 1992 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 1993 MessageTemplate::kInvalidDestructuringTarget); 1994 1995 if (is_async && !IsSpecialMethod(method_kind)) { 1996 DCHECK(!is_get); 1997 DCHECK(!is_set); 1998 bool dont_care; 1999 name_expression = ParsePropertyName( 2000 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2001 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2002 method_kind |= MethodKind::Async; 2003 } 2004 2005 if (is_generator || peek() == Token::LPAREN) { 2006 // MethodDefinition 2007 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2008 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2009 if (!*is_computed_name) { 2010 checker->CheckProperty(name_token, kMethodProperty, method_kind, 2011 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2012 } 2013 2014 FunctionKind kind = is_generator 2015 ? FunctionKind::kConciseGeneratorMethod 2016 : is_async ? FunctionKind::kAsyncConciseMethod 2017 : FunctionKind::kConciseMethod; 2018 2019 if (in_class && !IsStaticMethod(method_kind) && 2020 this->IsConstructor(*name)) { 2021 *has_seen_constructor = true; 2022 kind = has_extends ? FunctionKind::kSubclassConstructor 2023 : FunctionKind::kBaseConstructor; 2024 } 2025 2026 value = this->ParseFunctionLiteral( 2027 *name, scanner()->location(), kSkipFunctionNameCheck, kind, 2028 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, 2029 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2030 2031 return factory()->NewObjectLiteralProperty(name_expression, value, 2032 ObjectLiteralProperty::COMPUTED, 2033 is_static, *is_computed_name); 2034 } 2035 2036 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { 2037 // ClassElement (static) 2038 // 'static' MethodDefinition 2039 *name = this->EmptyIdentifier(); 2040 ObjectLiteralPropertyT property = ParsePropertyDefinition( 2041 checker, true, has_extends, MethodKind::Static, is_computed_name, 2042 nullptr, classifier, name, ok); 2043 Traits::RewriteNonPattern(classifier, ok); 2044 return property; 2045 } 2046 2047 if (is_get || is_set) { 2048 // MethodDefinition (Accessors) 2049 // get PropertyName '(' ')' '{' FunctionBody '}' 2050 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' 2051 *name = this->EmptyIdentifier(); 2052 bool dont_care = false; 2053 name_token = peek(); 2054 2055 name_expression = ParsePropertyName( 2056 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2057 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2058 2059 if (!*is_computed_name) { 2060 checker->CheckProperty(name_token, kAccessorProperty, method_kind, 2061 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2062 } 2063 2064 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2065 *name, scanner()->location(), kSkipFunctionNameCheck, 2066 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, 2067 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, 2068 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2069 2070 // Make sure the name expression is a string since we need a Name for 2071 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this 2072 // statically we can skip the extra runtime check. 2073 if (!*is_computed_name) { 2074 name_expression = 2075 factory()->NewStringLiteral(*name, name_expression->position()); 2076 } 2077 2078 return factory()->NewObjectLiteralProperty( 2079 name_expression, value, 2080 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, 2081 is_static, *is_computed_name); 2082 } 2083 2084 Token::Value next = Next(); 2085 ReportUnexpectedToken(next); 2086 *ok = false; 2087 return this->EmptyObjectLiteralProperty(); 2088} 2089 2090 2091template <class Traits> 2092typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2093 ExpressionClassifier* classifier, bool* ok) { 2094 // ObjectLiteral :: 2095 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2096 2097 int pos = peek_position(); 2098 typename Traits::Type::PropertyList properties = 2099 this->NewPropertyList(4, zone_); 2100 int number_of_boilerplate_properties = 0; 2101 bool has_computed_names = false; 2102 ObjectLiteralChecker checker(this); 2103 2104 Expect(Token::LBRACE, CHECK_OK); 2105 2106 while (peek() != Token::RBRACE) { 2107 FuncNameInferrer::State fni_state(fni_); 2108 2109 const bool in_class = false; 2110 const bool has_extends = false; 2111 bool is_computed_name = false; 2112 IdentifierT name = this->EmptyIdentifier(); 2113 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( 2114 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, 2115 NULL, classifier, &name, CHECK_OK); 2116 2117 if (is_computed_name) { 2118 has_computed_names = true; 2119 } 2120 2121 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2122 if (!has_computed_names && this->IsBoilerplateProperty(property)) { 2123 number_of_boilerplate_properties++; 2124 } 2125 properties->Add(property, zone()); 2126 2127 if (peek() != Token::RBRACE) { 2128 // Need {} because of the CHECK_OK macro. 2129 Expect(Token::COMMA, CHECK_OK); 2130 } 2131 2132 if (fni_ != nullptr) fni_->Infer(); 2133 2134 Traits::SetFunctionNameFromPropertyName(property, name); 2135 } 2136 Expect(Token::RBRACE, CHECK_OK); 2137 2138 // Computation of literal_index must happen before pre parse bailout. 2139 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2140 2141 return factory()->NewObjectLiteral(properties, 2142 literal_index, 2143 number_of_boilerplate_properties, 2144 pos); 2145} 2146 2147template <class Traits> 2148typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( 2149 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, 2150 ExpressionClassifier* classifier, bool* ok) { 2151 // Arguments :: 2152 // '(' (AssignmentExpression)*[','] ')' 2153 2154 Scanner::Location spread_arg = Scanner::Location::invalid(); 2155 typename Traits::Type::ExpressionList result = 2156 this->NewExpressionList(4, zone_); 2157 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2158 bool done = (peek() == Token::RPAREN); 2159 bool was_unspread = false; 2160 int unspread_sequences_count = 0; 2161 while (!done) { 2162 int start_pos = peek_position(); 2163 bool is_spread = Check(Token::ELLIPSIS); 2164 int expr_pos = peek_position(); 2165 2166 ExpressionT argument = this->ParseAssignmentExpression( 2167 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); 2168 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); 2169 if (!maybe_arrow) { 2170 Traits::RewriteNonPattern(classifier, 2171 CHECK_OK_CUSTOM(NullExpressionList)); 2172 } 2173 if (is_spread) { 2174 if (!spread_arg.IsValid()) { 2175 spread_arg.beg_pos = start_pos; 2176 spread_arg.end_pos = peek_position(); 2177 } 2178 argument = factory()->NewSpread(argument, start_pos, expr_pos); 2179 } 2180 result->Add(argument, zone_); 2181 2182 // unspread_sequences_count is the number of sequences of parameters which 2183 // are not prefixed with a spread '...' operator. 2184 if (is_spread) { 2185 was_unspread = false; 2186 } else if (!was_unspread) { 2187 was_unspread = true; 2188 unspread_sequences_count++; 2189 } 2190 2191 if (result->length() > Code::kMaxArguments) { 2192 ReportMessage(MessageTemplate::kTooManyArguments); 2193 *ok = false; 2194 return this->NullExpressionList(); 2195 } 2196 done = (peek() != Token::COMMA); 2197 if (!done) { 2198 Next(); 2199 } 2200 } 2201 Scanner::Location location = scanner_->location(); 2202 if (Token::RPAREN != Next()) { 2203 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); 2204 *ok = false; 2205 return this->NullExpressionList(); 2206 } 2207 *first_spread_arg_loc = spread_arg; 2208 2209 if (!maybe_arrow || peek() != Token::ARROW) { 2210 if (maybe_arrow) { 2211 Traits::RewriteNonPattern(classifier, 2212 CHECK_OK_CUSTOM(NullExpressionList)); 2213 } 2214 if (spread_arg.IsValid()) { 2215 // Unspread parameter sequences are translated into array literals in the 2216 // parser. Ensure that the number of materialized literals matches between 2217 // the parser and preparser 2218 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); 2219 } 2220 } 2221 2222 return result; 2223} 2224 2225// Precedence = 2 2226template <class Traits> 2227typename ParserBase<Traits>::ExpressionT 2228ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, 2229 ExpressionClassifier* classifier, 2230 bool* ok) { 2231 // AssignmentExpression :: 2232 // ConditionalExpression 2233 // ArrowFunction 2234 // YieldExpression 2235 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2236 bool is_destructuring_assignment = false; 2237 int lhs_beg_pos = peek_position(); 2238 2239 if (peek() == Token::YIELD && is_generator()) { 2240 return this->ParseYieldExpression(accept_IN, classifier, ok); 2241 } 2242 2243 FuncNameInferrer::State fni_state(fni_); 2244 ParserBase<Traits>::Checkpoint checkpoint(this); 2245 ExpressionClassifier arrow_formals_classifier(this, 2246 classifier->duplicate_finder()); 2247 2248 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && 2249 !scanner()->HasAnyLineTerminatorAfterNext() && 2250 IsValidArrowFormalParametersStart(PeekAhead()); 2251 2252 bool parenthesized_formals = peek() == Token::LPAREN; 2253 if (!is_async && !parenthesized_formals) { 2254 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); 2255 } 2256 ExpressionT expression = this->ParseConditionalExpression( 2257 accept_IN, &arrow_formals_classifier, CHECK_OK); 2258 2259 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { 2260 // async Identifier => AsyncConciseBody 2261 IdentifierT name = 2262 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); 2263 expression = this->ExpressionFromIdentifier( 2264 name, position(), scanner()->location().end_pos, scope_, factory()); 2265 } 2266 2267 if (peek() == Token::ARROW) { 2268 Scanner::Location arrow_loc = scanner()->peek_location(); 2269 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2270 parenthesized_formals, is_async, CHECK_OK); 2271 // This reads strangely, but is correct: it checks whether any 2272 // sub-expression of the parameter list failed to be a valid formal 2273 // parameter initializer. Since YieldExpressions are banned anywhere 2274 // in an arrow parameter list, this is correct. 2275 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to 2276 // "YieldExpression", which is its only use. 2277 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); 2278 2279 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); 2280 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, 2281 is_async ? FunctionKind::kAsyncArrowFunction 2282 : FunctionKind::kArrowFunction); 2283 // Because the arrow's parameters were parsed in the outer scope, any 2284 // usage flags that might have been triggered there need to be copied 2285 // to the arrow scope. 2286 scope_->PropagateUsageFlagsToScope(scope); 2287 FormalParametersT parameters(scope); 2288 if (!arrow_formals_classifier.is_simple_parameter_list()) { 2289 scope->SetHasNonSimpleParameters(); 2290 parameters.is_simple = false; 2291 } 2292 2293 checkpoint.Restore(¶meters.materialized_literals_count); 2294 2295 scope->set_start_position(lhs_beg_pos); 2296 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2297 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, 2298 &duplicate_loc, CHECK_OK); 2299 if (duplicate_loc.IsValid()) { 2300 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2301 duplicate_loc); 2302 } 2303 expression = this->ParseArrowFunctionLiteral( 2304 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); 2305 arrow_formals_classifier.Discard(); 2306 classifier->RecordPatternError(arrow_loc, 2307 MessageTemplate::kUnexpectedToken, 2308 Token::String(Token::ARROW)); 2309 2310 if (fni_ != nullptr) fni_->Infer(); 2311 2312 return expression; 2313 } 2314 2315 if (this->IsValidReferenceExpression(expression)) { 2316 arrow_formals_classifier.ForgiveAssignmentPatternError(); 2317 } 2318 2319 // "expression" was not itself an arrow function parameter list, but it might 2320 // form part of one. Propagate speculative formal parameter error locations. 2321 // Do not merge pending non-pattern expressions yet! 2322 classifier->Accumulate( 2323 &arrow_formals_classifier, 2324 ExpressionClassifier::StandardProductions | 2325 ExpressionClassifier::FormalParametersProductions | 2326 ExpressionClassifier::CoverInitializedNameProduction | 2327 ExpressionClassifier::AsyncArrowFormalParametersProduction | 2328 ExpressionClassifier::AsyncBindingPatternProduction, 2329 false); 2330 2331 if (!Token::IsAssignmentOp(peek())) { 2332 // Parsed conditional expression only (no assignment). 2333 // Now pending non-pattern expressions must be merged. 2334 classifier->MergeNonPatterns(&arrow_formals_classifier); 2335 return expression; 2336 } 2337 2338 // Now pending non-pattern expressions must be discarded. 2339 arrow_formals_classifier.Discard(); 2340 2341 CheckNoTailCallExpressions(classifier, CHECK_OK); 2342 2343 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { 2344 classifier->ForgiveCoverInitializedNameError(); 2345 ValidateAssignmentPattern(classifier, CHECK_OK); 2346 is_destructuring_assignment = true; 2347 } else { 2348 expression = this->CheckAndRewriteReferenceExpression( 2349 expression, lhs_beg_pos, scanner()->location().end_pos, 2350 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); 2351 } 2352 2353 expression = this->MarkExpressionAsAssigned(expression); 2354 2355 Token::Value op = Next(); // Get assignment operator. 2356 if (op != Token::ASSIGN) { 2357 classifier->RecordPatternError(scanner()->location(), 2358 MessageTemplate::kUnexpectedToken, 2359 Token::String(op)); 2360 } 2361 int pos = position(); 2362 2363 ExpressionClassifier rhs_classifier(this); 2364 2365 ExpressionT right = 2366 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); 2367 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); 2368 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); 2369 classifier->Accumulate( 2370 &rhs_classifier, 2371 ExpressionClassifier::ExpressionProductions | 2372 ExpressionClassifier::CoverInitializedNameProduction | 2373 ExpressionClassifier::AsyncArrowFormalParametersProduction); 2374 2375 // TODO(1231235): We try to estimate the set of properties set by 2376 // constructors. We define a new property whenever there is an 2377 // assignment to a property of 'this'. We should probably only add 2378 // properties if we haven't seen them before. Otherwise we'll 2379 // probably overestimate the number of properties. 2380 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 2381 function_state_->AddProperty(); 2382 } 2383 2384 this->CheckAssigningFunctionLiteralToProperty(expression, right); 2385 2386 if (fni_ != NULL) { 2387 // Check if the right hand side is a call to avoid inferring a 2388 // name if we're dealing with "a = function(){...}();"-like 2389 // expression. 2390 if ((op == Token::INIT || op == Token::ASSIGN) && 2391 (!right->IsCall() && !right->IsCallNew())) { 2392 fni_->Infer(); 2393 } else { 2394 fni_->RemoveLastFunction(); 2395 } 2396 } 2397 2398 if (op == Token::ASSIGN) { 2399 Traits::SetFunctionNameFromIdentifierRef(right, expression); 2400 } 2401 2402 if (op == Token::ASSIGN_EXP) { 2403 DCHECK(!is_destructuring_assignment); 2404 return Traits::RewriteAssignExponentiation(expression, right, pos); 2405 } 2406 2407 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); 2408 2409 if (is_destructuring_assignment) { 2410 result = factory()->NewRewritableExpression(result); 2411 Traits::QueueDestructuringAssignmentForRewriting(result); 2412 } 2413 2414 return result; 2415} 2416 2417template <class Traits> 2418typename ParserBase<Traits>::ExpressionT 2419ParserBase<Traits>::ParseYieldExpression(bool accept_IN, 2420 ExpressionClassifier* classifier, 2421 bool* ok) { 2422 // YieldExpression :: 2423 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 2424 int pos = peek_position(); 2425 classifier->RecordPatternError(scanner()->peek_location(), 2426 MessageTemplate::kInvalidDestructuringTarget); 2427 classifier->RecordFormalParameterInitializerError( 2428 scanner()->peek_location(), MessageTemplate::kYieldInParameter); 2429 Expect(Token::YIELD, CHECK_OK); 2430 ExpressionT generator_object = 2431 factory()->NewVariableProxy(function_state_->generator_object_variable()); 2432 ExpressionT expression = Traits::EmptyExpression(); 2433 bool delegating = false; // yield* 2434 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { 2435 if (Check(Token::MUL)) delegating = true; 2436 switch (peek()) { 2437 case Token::EOS: 2438 case Token::SEMICOLON: 2439 case Token::RBRACE: 2440 case Token::RBRACK: 2441 case Token::RPAREN: 2442 case Token::COLON: 2443 case Token::COMMA: 2444 // The above set of tokens is the complete set of tokens that can appear 2445 // after an AssignmentExpression, and none of them can start an 2446 // AssignmentExpression. This allows us to avoid looking for an RHS for 2447 // a regular yield, given only one look-ahead token. 2448 if (!delegating) break; 2449 // Delegating yields require an RHS; fall through. 2450 default: 2451 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); 2452 Traits::RewriteNonPattern(classifier, CHECK_OK); 2453 break; 2454 } 2455 } 2456 2457 if (delegating) { 2458 return Traits::RewriteYieldStar(generator_object, expression, pos); 2459 } 2460 2461 expression = Traits::BuildIteratorResult(expression, false); 2462 // Hackily disambiguate o from o.next and o [Symbol.iterator](). 2463 // TODO(verwaest): Come up with a better solution. 2464 typename Traits::Type::YieldExpression yield = 2465 factory()->NewYield(generator_object, expression, pos); 2466 return yield; 2467} 2468 2469template <class Traits> 2470typename ParserBase<Traits>::ExpressionT 2471ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, 2472 bool* ok) { 2473 // TailCallExpression:: 2474 // 'continue' MemberExpression Arguments 2475 // 'continue' CallExpression Arguments 2476 // 'continue' MemberExpression TemplateLiteral 2477 // 'continue' CallExpression TemplateLiteral 2478 Expect(Token::CONTINUE, CHECK_OK); 2479 int pos = position(); 2480 int sub_expression_pos = peek_position(); 2481 ExpressionT expression = 2482 this->ParseLeftHandSideExpression(classifier, CHECK_OK); 2483 CheckNoTailCallExpressions(classifier, CHECK_OK); 2484 2485 Scanner::Location loc(pos, scanner()->location().end_pos); 2486 if (!expression->IsCall()) { 2487 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); 2488 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall); 2489 *ok = false; 2490 return Traits::EmptyExpression(); 2491 } 2492 if (Traits::IsDirectEvalCall(expression)) { 2493 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); 2494 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval); 2495 *ok = false; 2496 return Traits::EmptyExpression(); 2497 } 2498 if (!is_strict(language_mode())) { 2499 ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall); 2500 *ok = false; 2501 return Traits::EmptyExpression(); 2502 } 2503 if (is_resumable()) { 2504 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); 2505 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCall); 2506 *ok = false; 2507 return Traits::EmptyExpression(); 2508 } 2509 ReturnExprContext return_expr_context = 2510 function_state_->return_expr_context(); 2511 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { 2512 MessageTemplate::Template msg = MessageTemplate::kNone; 2513 switch (return_expr_context) { 2514 case ReturnExprContext::kInsideValidReturnStatement: 2515 UNREACHABLE(); 2516 return Traits::EmptyExpression(); 2517 case ReturnExprContext::kInsideValidBlock: 2518 msg = MessageTemplate::kUnexpectedTailCall; 2519 break; 2520 case ReturnExprContext::kInsideTryBlock: 2521 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; 2522 break; 2523 case ReturnExprContext::kInsideForInOfBody: 2524 msg = MessageTemplate::kUnexpectedTailCallInForInOf; 2525 break; 2526 } 2527 ReportMessageAt(loc, msg); 2528 *ok = false; 2529 return Traits::EmptyExpression(); 2530 } 2531 classifier->RecordTailCallExpressionError( 2532 loc, MessageTemplate::kUnexpectedTailCall); 2533 function_state_->AddExplicitTailCallExpression(expression, loc); 2534 return expression; 2535} 2536 2537// Precedence = 3 2538template <class Traits> 2539typename ParserBase<Traits>::ExpressionT 2540ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, 2541 ExpressionClassifier* classifier, 2542 bool* ok) { 2543 // ConditionalExpression :: 2544 // LogicalOrExpression 2545 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 2546 2547 int pos = peek_position(); 2548 // We start using the binary expression parser for prec >= 4 only! 2549 ExpressionT expression = 2550 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); 2551 if (peek() != Token::CONDITIONAL) return expression; 2552 CheckNoTailCallExpressions(classifier, CHECK_OK); 2553 Traits::RewriteNonPattern(classifier, CHECK_OK); 2554 BindingPatternUnexpectedToken(classifier); 2555 ArrowFormalParametersUnexpectedToken(classifier); 2556 Consume(Token::CONDITIONAL); 2557 // In parsing the first assignment expression in conditional 2558 // expressions we always accept the 'in' keyword; see ECMA-262, 2559 // section 11.12, page 58. 2560 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); 2561 Traits::RewriteNonPattern(classifier, CHECK_OK); 2562 Expect(Token::COLON, CHECK_OK); 2563 ExpressionT right = 2564 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); 2565 Traits::RewriteNonPattern(classifier, CHECK_OK); 2566 return factory()->NewConditional(expression, left, right, pos); 2567} 2568 2569 2570// Precedence >= 4 2571template <class Traits> 2572typename ParserBase<Traits>::ExpressionT 2573ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, 2574 ExpressionClassifier* classifier, 2575 bool* ok) { 2576 DCHECK(prec >= 4); 2577 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); 2578 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 2579 // prec1 >= 4 2580 while (Precedence(peek(), accept_IN) == prec1) { 2581 CheckNoTailCallExpressions(classifier, CHECK_OK); 2582 Traits::RewriteNonPattern(classifier, CHECK_OK); 2583 BindingPatternUnexpectedToken(classifier); 2584 ArrowFormalParametersUnexpectedToken(classifier); 2585 Token::Value op = Next(); 2586 int pos = position(); 2587 2588 const bool is_right_associative = op == Token::EXP; 2589 const int next_prec = is_right_associative ? prec1 : prec1 + 1; 2590 ExpressionT y = 2591 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); 2592 if (op != Token::OR && op != Token::AND) { 2593 CheckNoTailCallExpressions(classifier, CHECK_OK); 2594 } 2595 Traits::RewriteNonPattern(classifier, CHECK_OK); 2596 2597 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 2598 factory())) { 2599 continue; 2600 } 2601 2602 // For now we distinguish between comparisons and other binary 2603 // operations. (We could combine the two and get rid of this 2604 // code and AST node eventually.) 2605 if (Token::IsCompareOp(op)) { 2606 // We have a comparison. 2607 Token::Value cmp = op; 2608 switch (op) { 2609 case Token::NE: cmp = Token::EQ; break; 2610 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2611 default: break; 2612 } 2613 x = factory()->NewCompareOperation(cmp, x, y, pos); 2614 if (cmp != op) { 2615 // The comparison was negated - add a NOT. 2616 x = factory()->NewUnaryOperation(Token::NOT, x, pos); 2617 } 2618 } else if (op == Token::EXP) { 2619 x = Traits::RewriteExponentiation(x, y, pos); 2620 } else { 2621 // We have a "normal" binary operation. 2622 x = factory()->NewBinaryOperation(op, x, y, pos); 2623 } 2624 } 2625 } 2626 return x; 2627} 2628 2629 2630template <class Traits> 2631typename ParserBase<Traits>::ExpressionT 2632ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, 2633 bool* ok) { 2634 // UnaryExpression :: 2635 // PostfixExpression 2636 // 'delete' UnaryExpression 2637 // 'void' UnaryExpression 2638 // 'typeof' UnaryExpression 2639 // '++' UnaryExpression 2640 // '--' UnaryExpression 2641 // '+' UnaryExpression 2642 // '-' UnaryExpression 2643 // '~' UnaryExpression 2644 // '!' UnaryExpression 2645 // [+Await] AwaitExpression[?Yield] 2646 2647 Token::Value op = peek(); 2648 if (Token::IsUnaryOp(op)) { 2649 BindingPatternUnexpectedToken(classifier); 2650 ArrowFormalParametersUnexpectedToken(classifier); 2651 2652 op = Next(); 2653 int pos = position(); 2654 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); 2655 CheckNoTailCallExpressions(classifier, CHECK_OK); 2656 Traits::RewriteNonPattern(classifier, CHECK_OK); 2657 2658 if (op == Token::DELETE && is_strict(language_mode())) { 2659 if (this->IsIdentifier(expression)) { 2660 // "delete identifier" is a syntax error in strict mode. 2661 ReportMessage(MessageTemplate::kStrictDelete); 2662 *ok = false; 2663 return this->EmptyExpression(); 2664 } 2665 } 2666 2667 if (peek() == Token::EXP) { 2668 ReportUnexpectedToken(Next()); 2669 *ok = false; 2670 return this->EmptyExpression(); 2671 } 2672 2673 // Allow Traits do rewrite the expression. 2674 return this->BuildUnaryExpression(expression, op, pos, factory()); 2675 } else if (Token::IsCountOp(op)) { 2676 BindingPatternUnexpectedToken(classifier); 2677 ArrowFormalParametersUnexpectedToken(classifier); 2678 op = Next(); 2679 int beg_pos = peek_position(); 2680 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); 2681 CheckNoTailCallExpressions(classifier, CHECK_OK); 2682 expression = this->CheckAndRewriteReferenceExpression( 2683 expression, beg_pos, scanner()->location().end_pos, 2684 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); 2685 this->MarkExpressionAsAssigned(expression); 2686 Traits::RewriteNonPattern(classifier, CHECK_OK); 2687 2688 return factory()->NewCountOperation(op, 2689 true /* prefix */, 2690 expression, 2691 position()); 2692 2693 } else if (is_async_function() && peek() == Token::AWAIT) { 2694 int beg_pos = peek_position(); 2695 switch (PeekAhead()) { 2696 case Token::RPAREN: 2697 case Token::RBRACK: 2698 case Token::RBRACE: 2699 case Token::ASSIGN: 2700 case Token::COMMA: { 2701 Next(); 2702 IdentifierT name = this->GetSymbol(scanner()); 2703 2704 // Possibly async arrow formals --- record ExpressionError just in case. 2705 ExpressionUnexpectedToken(classifier); 2706 classifier->RecordAsyncBindingPatternError( 2707 Scanner::Location(beg_pos, scanner()->location().end_pos), 2708 MessageTemplate::kAwaitBindingIdentifier); 2709 classifier->RecordAsyncArrowFormalParametersError( 2710 Scanner::Location(beg_pos, scanner()->location().end_pos), 2711 MessageTemplate::kAwaitBindingIdentifier); 2712 2713 return this->ExpressionFromIdentifier( 2714 name, beg_pos, scanner()->location().end_pos, scope_, factory()); 2715 } 2716 default: 2717 break; 2718 } 2719 2720 int await_pos = peek_position(); 2721 Consume(Token::AWAIT); 2722 2723 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); 2724 2725 classifier->RecordFormalParameterInitializerError( 2726 Scanner::Location(beg_pos, scanner()->location().end_pos), 2727 MessageTemplate::kAwaitExpressionFormalParameter); 2728 return Traits::RewriteAwaitExpression(value, await_pos); 2729 } else { 2730 return this->ParsePostfixExpression(classifier, ok); 2731 } 2732} 2733 2734 2735template <class Traits> 2736typename ParserBase<Traits>::ExpressionT 2737ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, 2738 bool* ok) { 2739 // PostfixExpression :: 2740 // LeftHandSideExpression ('++' | '--')? 2741 2742 int lhs_beg_pos = peek_position(); 2743 ExpressionT expression = 2744 this->ParseLeftHandSideExpression(classifier, CHECK_OK); 2745 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2746 Token::IsCountOp(peek())) { 2747 CheckNoTailCallExpressions(classifier, CHECK_OK); 2748 BindingPatternUnexpectedToken(classifier); 2749 ArrowFormalParametersUnexpectedToken(classifier); 2750 2751 expression = this->CheckAndRewriteReferenceExpression( 2752 expression, lhs_beg_pos, scanner()->location().end_pos, 2753 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); 2754 expression = this->MarkExpressionAsAssigned(expression); 2755 Traits::RewriteNonPattern(classifier, CHECK_OK); 2756 2757 Token::Value next = Next(); 2758 expression = 2759 factory()->NewCountOperation(next, 2760 false /* postfix */, 2761 expression, 2762 position()); 2763 } 2764 return expression; 2765} 2766 2767template <class Traits> 2768typename ParserBase<Traits>::ExpressionT 2769ParserBase<Traits>::ParseLeftHandSideExpression( 2770 ExpressionClassifier* classifier, bool* ok) { 2771 // LeftHandSideExpression :: 2772 // (NewExpression | MemberExpression) ... 2773 2774 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { 2775 return this->ParseTailCallExpression(classifier, ok); 2776 } 2777 2778 bool is_async = false; 2779 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( 2780 classifier, &is_async, CHECK_OK); 2781 2782 while (true) { 2783 switch (peek()) { 2784 case Token::LBRACK: { 2785 CheckNoTailCallExpressions(classifier, CHECK_OK); 2786 Traits::RewriteNonPattern(classifier, CHECK_OK); 2787 BindingPatternUnexpectedToken(classifier); 2788 ArrowFormalParametersUnexpectedToken(classifier); 2789 Consume(Token::LBRACK); 2790 int pos = position(); 2791 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); 2792 Traits::RewriteNonPattern(classifier, CHECK_OK); 2793 result = factory()->NewProperty(result, index, pos); 2794 Expect(Token::RBRACK, CHECK_OK); 2795 break; 2796 } 2797 2798 case Token::LPAREN: { 2799 CheckNoTailCallExpressions(classifier, CHECK_OK); 2800 int pos; 2801 Traits::RewriteNonPattern(classifier, CHECK_OK); 2802 BindingPatternUnexpectedToken(classifier); 2803 if (scanner()->current_token() == Token::IDENTIFIER || 2804 scanner()->current_token() == Token::SUPER || 2805 scanner()->current_token() == Token::ASYNC) { 2806 // For call of an identifier we want to report position of 2807 // the identifier as position of the call in the stack trace. 2808 pos = position(); 2809 } else { 2810 // For other kinds of calls we record position of the parenthesis as 2811 // position of the call. Note that this is extremely important for 2812 // expressions of the form function(){...}() for which call position 2813 // should not point to the closing brace otherwise it will intersect 2814 // with positions recorded for function literal and confuse debugger. 2815 pos = peek_position(); 2816 // Also the trailing parenthesis are a hint that the function will 2817 // be called immediately. If we happen to have parsed a preceding 2818 // function literal eagerly, we can also compile it eagerly. 2819 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 2820 result->AsFunctionLiteral()->set_should_eager_compile(); 2821 } 2822 } 2823 Scanner::Location spread_pos; 2824 typename Traits::Type::ExpressionList args = 2825 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); 2826 2827 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { 2828 if (args->length()) { 2829 // async ( Arguments ) => ... 2830 return Traits::ExpressionListToExpression(args); 2831 } 2832 // async () => ... 2833 return factory()->NewEmptyParentheses(pos); 2834 } 2835 2836 ArrowFormalParametersUnexpectedToken(classifier); 2837 2838 // Keep track of eval() calls since they disable all local variable 2839 // optimizations. 2840 // The calls that need special treatment are the 2841 // direct eval calls. These calls are all of the form eval(...), with 2842 // no explicit receiver. 2843 // These calls are marked as potentially direct eval calls. Whether 2844 // they are actually direct calls to eval is determined at run time. 2845 this->CheckPossibleEvalCall(result, scope_); 2846 2847 bool is_super_call = result->IsSuperCallReference(); 2848 if (spread_pos.IsValid()) { 2849 args = Traits::PrepareSpreadArguments(args); 2850 result = Traits::SpreadCall(result, args, pos); 2851 } else { 2852 result = factory()->NewCall(result, args, pos); 2853 } 2854 2855 // Explicit calls to the super constructor using super() perform an 2856 // implicit binding assignment to the 'this' variable. 2857 if (is_super_call) { 2858 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); 2859 result = 2860 factory()->NewAssignment(Token::INIT, this_expr, result, pos); 2861 } 2862 2863 if (fni_ != NULL) fni_->RemoveLastFunction(); 2864 break; 2865 } 2866 2867 case Token::PERIOD: { 2868 CheckNoTailCallExpressions(classifier, CHECK_OK); 2869 Traits::RewriteNonPattern(classifier, CHECK_OK); 2870 BindingPatternUnexpectedToken(classifier); 2871 ArrowFormalParametersUnexpectedToken(classifier); 2872 Consume(Token::PERIOD); 2873 int pos = position(); 2874 IdentifierT name = ParseIdentifierName(CHECK_OK); 2875 result = factory()->NewProperty( 2876 result, factory()->NewStringLiteral(name, pos), pos); 2877 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2878 break; 2879 } 2880 2881 case Token::TEMPLATE_SPAN: 2882 case Token::TEMPLATE_TAIL: { 2883 CheckNoTailCallExpressions(classifier, CHECK_OK); 2884 Traits::RewriteNonPattern(classifier, CHECK_OK); 2885 BindingPatternUnexpectedToken(classifier); 2886 ArrowFormalParametersUnexpectedToken(classifier); 2887 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); 2888 break; 2889 } 2890 2891 default: 2892 return result; 2893 } 2894 } 2895} 2896 2897template <class Traits> 2898typename ParserBase<Traits>::ExpressionT 2899ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( 2900 ExpressionClassifier* classifier, bool* is_async, bool* ok) { 2901 // NewExpression :: 2902 // ('new')+ MemberExpression 2903 // 2904 // NewTarget :: 2905 // 'new' '.' 'target' 2906 2907 // The grammar for new expressions is pretty warped. We can have several 'new' 2908 // keywords following each other, and then a MemberExpression. When we see '(' 2909 // after the MemberExpression, it's associated with the rightmost unassociated 2910 // 'new' to create a NewExpression with arguments. However, a NewExpression 2911 // can also occur without arguments. 2912 2913 // Examples of new expression: 2914 // new foo.bar().baz means (new (foo.bar)()).baz 2915 // new foo()() means (new foo())() 2916 // new new foo()() means (new (new foo())()) 2917 // new new foo means new (new foo) 2918 // new new foo() means new (new foo()) 2919 // new new foo().bar().baz means (new (new foo()).bar()).baz 2920 2921 if (peek() == Token::NEW) { 2922 BindingPatternUnexpectedToken(classifier); 2923 ArrowFormalParametersUnexpectedToken(classifier); 2924 Consume(Token::NEW); 2925 int new_pos = position(); 2926 ExpressionT result = this->EmptyExpression(); 2927 if (peek() == Token::SUPER) { 2928 const bool is_new = true; 2929 result = ParseSuperExpression(is_new, classifier, CHECK_OK); 2930 } else if (peek() == Token::PERIOD) { 2931 return ParseNewTargetExpression(CHECK_OK); 2932 } else { 2933 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, 2934 CHECK_OK); 2935 } 2936 Traits::RewriteNonPattern(classifier, CHECK_OK); 2937 if (peek() == Token::LPAREN) { 2938 // NewExpression with arguments. 2939 Scanner::Location spread_pos; 2940 typename Traits::Type::ExpressionList args = 2941 this->ParseArguments(&spread_pos, classifier, CHECK_OK); 2942 2943 if (spread_pos.IsValid()) { 2944 args = Traits::PrepareSpreadArguments(args); 2945 result = Traits::SpreadCallNew(result, args, new_pos); 2946 } else { 2947 result = factory()->NewCallNew(result, args, new_pos); 2948 } 2949 // The expression can still continue with . or [ after the arguments. 2950 result = this->ParseMemberExpressionContinuation(result, is_async, 2951 classifier, CHECK_OK); 2952 return result; 2953 } 2954 // NewExpression without arguments. 2955 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), 2956 new_pos); 2957 } 2958 // No 'new' or 'super' keyword. 2959 return this->ParseMemberExpression(classifier, is_async, ok); 2960} 2961 2962template <class Traits> 2963typename ParserBase<Traits>::ExpressionT 2964ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, 2965 bool* is_async, bool* ok) { 2966 // MemberExpression :: 2967 // (PrimaryExpression | FunctionLiteral | ClassLiteral) 2968 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* 2969 2970 // The '[' Expression ']' and '.' Identifier parts are parsed by 2971 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 2972 // caller. 2973 2974 // Parse the initial primary or function expression. 2975 ExpressionT result = this->EmptyExpression(); 2976 if (peek() == Token::FUNCTION) { 2977 BindingPatternUnexpectedToken(classifier); 2978 ArrowFormalParametersUnexpectedToken(classifier); 2979 2980 Consume(Token::FUNCTION); 2981 int function_token_position = position(); 2982 2983 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { 2984 // function.sent 2985 int pos = position(); 2986 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); 2987 2988 if (!is_generator()) { 2989 // TODO(neis): allow escaping into closures? 2990 ReportMessageAt(scanner()->location(), 2991 MessageTemplate::kUnexpectedFunctionSent); 2992 *ok = false; 2993 return this->EmptyExpression(); 2994 } 2995 2996 return this->FunctionSentExpression(scope_, factory(), pos); 2997 } 2998 2999 bool is_generator = Check(Token::MUL); 3000 IdentifierT name = this->EmptyIdentifier(); 3001 bool is_strict_reserved_name = false; 3002 Scanner::Location function_name_location = Scanner::Location::invalid(); 3003 FunctionLiteral::FunctionType function_type = 3004 FunctionLiteral::kAnonymousExpression; 3005 if (peek_any_identifier()) { 3006 name = ParseIdentifierOrStrictReservedWord( 3007 is_generator, &is_strict_reserved_name, CHECK_OK); 3008 function_name_location = scanner()->location(); 3009 function_type = FunctionLiteral::kNamedExpression; 3010 } 3011 result = this->ParseFunctionLiteral( 3012 name, function_name_location, 3013 is_strict_reserved_name ? kFunctionNameIsStrictReserved 3014 : kFunctionNameValidityUnknown, 3015 is_generator ? FunctionKind::kGeneratorFunction 3016 : FunctionKind::kNormalFunction, 3017 function_token_position, function_type, language_mode(), CHECK_OK); 3018 } else if (peek() == Token::SUPER) { 3019 const bool is_new = false; 3020 result = ParseSuperExpression(is_new, classifier, CHECK_OK); 3021 } else { 3022 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); 3023 } 3024 3025 result = 3026 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); 3027 return result; 3028} 3029 3030 3031template <class Traits> 3032typename ParserBase<Traits>::ExpressionT 3033ParserBase<Traits>::ParseSuperExpression(bool is_new, 3034 ExpressionClassifier* classifier, 3035 bool* ok) { 3036 Expect(Token::SUPER, CHECK_OK); 3037 int pos = position(); 3038 3039 Scope* scope = scope_->ReceiverScope(); 3040 FunctionKind kind = scope->function_kind(); 3041 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || 3042 IsClassConstructor(kind)) { 3043 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { 3044 scope->RecordSuperPropertyUsage(); 3045 return this->SuperPropertyReference(scope_, factory(), pos); 3046 } 3047 // new super() is never allowed. 3048 // super() is only allowed in derived constructor 3049 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { 3050 // TODO(rossberg): This might not be the correct FunctionState for the 3051 // method here. 3052 function_state_->set_super_location(scanner()->location()); 3053 return this->SuperCallReference(scope_, factory(), pos); 3054 } 3055 } 3056 3057 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); 3058 *ok = false; 3059 return this->EmptyExpression(); 3060} 3061 3062template <class Traits> 3063void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, 3064 const char* full_name, int pos, 3065 bool* ok) { 3066 Consume(Token::PERIOD); 3067 ExpectContextualKeyword(property_name, ok); 3068 if (!*ok) return; 3069 if (scanner()->literal_contains_escapes()) { 3070 Traits::ReportMessageAt( 3071 Scanner::Location(pos, scanner()->location().end_pos), 3072 MessageTemplate::kInvalidEscapedMetaProperty, full_name); 3073 *ok = false; 3074 } 3075} 3076 3077template <class Traits> 3078typename ParserBase<Traits>::ExpressionT 3079ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { 3080 int pos = position(); 3081 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); 3082 3083 if (!scope_->ReceiverScope()->is_function_scope()) { 3084 ReportMessageAt(scanner()->location(), 3085 MessageTemplate::kUnexpectedNewTarget); 3086 *ok = false; 3087 return this->EmptyExpression(); 3088 } 3089 3090 return this->NewTargetExpression(scope_, factory(), pos); 3091} 3092 3093template <class Traits> 3094typename ParserBase<Traits>::ExpressionT 3095ParserBase<Traits>::ParseMemberExpressionContinuation( 3096 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, 3097 bool* ok) { 3098 // Parses this part of MemberExpression: 3099 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* 3100 while (true) { 3101 switch (peek()) { 3102 case Token::LBRACK: { 3103 *is_async = false; 3104 Traits::RewriteNonPattern(classifier, CHECK_OK); 3105 BindingPatternUnexpectedToken(classifier); 3106 ArrowFormalParametersUnexpectedToken(classifier); 3107 3108 Consume(Token::LBRACK); 3109 int pos = position(); 3110 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); 3111 Traits::RewriteNonPattern(classifier, CHECK_OK); 3112 expression = factory()->NewProperty(expression, index, pos); 3113 if (fni_ != NULL) { 3114 this->PushPropertyName(fni_, index); 3115 } 3116 Expect(Token::RBRACK, CHECK_OK); 3117 break; 3118 } 3119 case Token::PERIOD: { 3120 *is_async = false; 3121 Traits::RewriteNonPattern(classifier, CHECK_OK); 3122 BindingPatternUnexpectedToken(classifier); 3123 ArrowFormalParametersUnexpectedToken(classifier); 3124 3125 Consume(Token::PERIOD); 3126 int pos = position(); 3127 IdentifierT name = ParseIdentifierName(CHECK_OK); 3128 expression = factory()->NewProperty( 3129 expression, factory()->NewStringLiteral(name, pos), pos); 3130 if (fni_ != NULL) { 3131 this->PushLiteralName(fni_, name); 3132 } 3133 break; 3134 } 3135 case Token::TEMPLATE_SPAN: 3136 case Token::TEMPLATE_TAIL: { 3137 *is_async = false; 3138 Traits::RewriteNonPattern(classifier, CHECK_OK); 3139 BindingPatternUnexpectedToken(classifier); 3140 ArrowFormalParametersUnexpectedToken(classifier); 3141 int pos; 3142 if (scanner()->current_token() == Token::IDENTIFIER) { 3143 pos = position(); 3144 } else { 3145 pos = peek_position(); 3146 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 3147 // If the tag function looks like an IIFE, set_parenthesized() to 3148 // force eager compilation. 3149 expression->AsFunctionLiteral()->set_should_eager_compile(); 3150 } 3151 } 3152 expression = 3153 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); 3154 break; 3155 } 3156 case Token::ILLEGAL: { 3157 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); 3158 *ok = false; 3159 return this->EmptyExpression(); 3160 } 3161 default: 3162 return expression; 3163 } 3164 } 3165 DCHECK(false); 3166 return this->EmptyExpression(); 3167} 3168 3169 3170template <class Traits> 3171void ParserBase<Traits>::ParseFormalParameter( 3172 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3173 // FormalParameter[Yield,GeneratorParameter] : 3174 // BindingElement[?Yield, ?GeneratorParameter] 3175 bool is_rest = parameters->has_rest; 3176 3177 ExpressionT pattern = ParsePrimaryExpression(classifier, ok); 3178 if (!*ok) return; 3179 3180 ValidateBindingPattern(classifier, ok); 3181 if (!*ok) return; 3182 3183 if (!Traits::IsIdentifier(pattern)) { 3184 parameters->is_simple = false; 3185 ValidateFormalParameterInitializer(classifier, ok); 3186 if (!*ok) return; 3187 classifier->RecordNonSimpleParameter(); 3188 } 3189 3190 ExpressionT initializer = Traits::EmptyExpression(); 3191 if (!is_rest && Check(Token::ASSIGN)) { 3192 ExpressionClassifier init_classifier(this); 3193 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3194 if (!*ok) return; 3195 Traits::RewriteNonPattern(&init_classifier, ok); 3196 ValidateFormalParameterInitializer(&init_classifier, ok); 3197 if (!*ok) return; 3198 parameters->is_simple = false; 3199 init_classifier.Discard(); 3200 classifier->RecordNonSimpleParameter(); 3201 3202 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); 3203 } 3204 3205 Traits::AddFormalParameter(parameters, pattern, initializer, 3206 scanner()->location().end_pos, is_rest); 3207} 3208 3209 3210template <class Traits> 3211void ParserBase<Traits>::ParseFormalParameterList( 3212 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3213 // FormalParameters[Yield,GeneratorParameter] : 3214 // [empty] 3215 // FormalParameterList[?Yield, ?GeneratorParameter] 3216 // 3217 // FormalParameterList[Yield,GeneratorParameter] : 3218 // FunctionRestParameter[?Yield] 3219 // FormalsList[?Yield, ?GeneratorParameter] 3220 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] 3221 // 3222 // FormalsList[Yield,GeneratorParameter] : 3223 // FormalParameter[?Yield, ?GeneratorParameter] 3224 // FormalsList[?Yield, ?GeneratorParameter] , 3225 // FormalParameter[?Yield,?GeneratorParameter] 3226 3227 DCHECK_EQ(0, parameters->Arity()); 3228 3229 if (peek() != Token::RPAREN) { 3230 do { 3231 if (parameters->Arity() > Code::kMaxArguments) { 3232 ReportMessage(MessageTemplate::kTooManyParameters); 3233 *ok = false; 3234 return; 3235 } 3236 parameters->has_rest = Check(Token::ELLIPSIS); 3237 ParseFormalParameter(parameters, classifier, ok); 3238 if (!*ok) return; 3239 } while (!parameters->has_rest && Check(Token::COMMA)); 3240 3241 if (parameters->has_rest) { 3242 parameters->is_simple = false; 3243 classifier->RecordNonSimpleParameter(); 3244 if (peek() == Token::COMMA) { 3245 ReportMessageAt(scanner()->peek_location(), 3246 MessageTemplate::kParamAfterRest); 3247 *ok = false; 3248 return; 3249 } 3250 } 3251 } 3252 3253 for (int i = 0; i < parameters->Arity(); ++i) { 3254 auto parameter = parameters->at(i); 3255 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); 3256 } 3257} 3258 3259template <class Traits> 3260void ParserBase<Traits>::CheckArityRestrictions(int param_count, 3261 FunctionKind function_kind, 3262 bool has_rest, 3263 int formals_start_pos, 3264 int formals_end_pos, bool* ok) { 3265 if (IsGetterFunction(function_kind)) { 3266 if (param_count != 0) { 3267 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), 3268 MessageTemplate::kBadGetterArity); 3269 *ok = false; 3270 } 3271 } else if (IsSetterFunction(function_kind)) { 3272 if (param_count != 1) { 3273 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), 3274 MessageTemplate::kBadSetterArity); 3275 *ok = false; 3276 } 3277 if (has_rest) { 3278 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), 3279 MessageTemplate::kBadSetterRestParameter); 3280 *ok = false; 3281 } 3282 } 3283} 3284 3285 3286template <class Traits> 3287bool ParserBase<Traits>::IsNextLetKeyword() { 3288 DCHECK(peek() == Token::LET); 3289 Token::Value next_next = PeekAhead(); 3290 switch (next_next) { 3291 case Token::LBRACE: 3292 case Token::LBRACK: 3293 case Token::IDENTIFIER: 3294 case Token::STATIC: 3295 case Token::LET: // `let let;` is disallowed by static semantics, but the 3296 // token must be first interpreted as a keyword in order 3297 // for those semantics to apply. This ensures that ASI is 3298 // not honored when a LineTerminator separates the 3299 // tokens. 3300 case Token::YIELD: 3301 case Token::AWAIT: 3302 case Token::ASYNC: 3303 return true; 3304 case Token::FUTURE_STRICT_RESERVED_WORD: 3305 return is_sloppy(language_mode()); 3306 default: 3307 return false; 3308 } 3309} 3310 3311template <class Traits> 3312typename ParserBase<Traits>::ExpressionT 3313ParserBase<Traits>::ParseArrowFunctionLiteral( 3314 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, 3315 const ExpressionClassifier& formals_classifier, bool* ok) { 3316 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { 3317 // ASI inserts `;` after arrow parameters if a line terminator is found. 3318 // `=> ...` is never a valid expression, so report as syntax error. 3319 // If next token is not `=>`, it's a syntax error anyways. 3320 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); 3321 *ok = false; 3322 return this->EmptyExpression(); 3323 } 3324 3325 typename Traits::Type::StatementList body; 3326 int num_parameters = formal_parameters.scope->num_parameters(); 3327 int materialized_literal_count = -1; 3328 int expected_property_count = -1; 3329 Scanner::Location super_loc; 3330 3331 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; 3332 { 3333 typename Traits::Type::Factory function_factory(ast_value_factory()); 3334 FunctionState function_state(&function_state_, &scope_, 3335 formal_parameters.scope, arrow_kind, 3336 &function_factory); 3337 3338 function_state.SkipMaterializedLiterals( 3339 formal_parameters.materialized_literals_count); 3340 3341 this->ReindexLiterals(formal_parameters); 3342 3343 Expect(Token::ARROW, CHECK_OK); 3344 3345 if (peek() == Token::LBRACE) { 3346 // Multiple statement body 3347 Consume(Token::LBRACE); 3348 bool is_lazily_parsed = 3349 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); 3350 if (is_lazily_parsed) { 3351 body = this->NewStatementList(0, zone()); 3352 this->SkipLazyFunctionBody(&materialized_literal_count, 3353 &expected_property_count, CHECK_OK); 3354 if (formal_parameters.materialized_literals_count > 0) { 3355 materialized_literal_count += 3356 formal_parameters.materialized_literals_count; 3357 } 3358 } else { 3359 body = this->ParseEagerFunctionBody( 3360 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, 3361 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); 3362 materialized_literal_count = 3363 function_state.materialized_literal_count(); 3364 expected_property_count = function_state.expected_property_count(); 3365 } 3366 } else { 3367 // Single-expression body 3368 int pos = position(); 3369 DCHECK(ReturnExprContext::kInsideValidBlock == 3370 function_state_->return_expr_context()); 3371 ReturnExprScope allow_tail_calls( 3372 function_state_, ReturnExprContext::kInsideValidReturnStatement); 3373 body = this->NewStatementList(1, zone()); 3374 this->AddParameterInitializationBlock(formal_parameters, body, is_async, 3375 CHECK_OK); 3376 ExpressionClassifier classifier(this); 3377 if (is_async) { 3378 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, 3379 pos, CHECK_OK); 3380 Traits::RewriteNonPattern(&classifier, CHECK_OK); 3381 } else { 3382 ExpressionT expression = 3383 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); 3384 Traits::RewriteNonPattern(&classifier, CHECK_OK); 3385 body->Add(factory()->NewReturnStatement(expression, pos), zone()); 3386 if (allow_tailcalls() && !is_sloppy(language_mode())) { 3387 // ES6 14.6.1 Static Semantics: IsInTailPosition 3388 this->MarkTailPosition(expression); 3389 } 3390 } 3391 materialized_literal_count = function_state.materialized_literal_count(); 3392 expected_property_count = function_state.expected_property_count(); 3393 this->MarkCollectedTailCallExpressions(); 3394 } 3395 super_loc = function_state.super_location(); 3396 3397 formal_parameters.scope->set_end_position(scanner()->location().end_pos); 3398 3399 // Arrow function formal parameters are parsed as StrictFormalParameterList, 3400 // which is not the same as "parameters of a strict function"; it only means 3401 // that duplicates are not allowed. Of course, the arrow function may 3402 // itself be strict as well. 3403 const bool allow_duplicate_parameters = false; 3404 this->ValidateFormalParameters(&formals_classifier, language_mode(), 3405 allow_duplicate_parameters, CHECK_OK); 3406 3407 // Validate strict mode. 3408 if (is_strict(language_mode())) { 3409 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), 3410 scanner()->location().end_pos, CHECK_OK); 3411 } 3412 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); 3413 3414 Traits::RewriteDestructuringAssignments(); 3415 } 3416 3417 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 3418 this->EmptyIdentifierString(), formal_parameters.scope, body, 3419 materialized_literal_count, expected_property_count, num_parameters, 3420 FunctionLiteral::kNoDuplicateParameters, 3421 FunctionLiteral::kAnonymousExpression, 3422 FunctionLiteral::kShouldLazyCompile, arrow_kind, 3423 formal_parameters.scope->start_position()); 3424 3425 function_literal->set_function_token_position( 3426 formal_parameters.scope->start_position()); 3427 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); 3428 3429 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); 3430 3431 return function_literal; 3432} 3433 3434 3435template <typename Traits> 3436typename ParserBase<Traits>::ExpressionT 3437ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, 3438 ExpressionClassifier* classifier, 3439 bool* ok) { 3440 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal 3441 // text followed by a substitution expression), finalized by a single 3442 // TEMPLATE_TAIL. 3443 // 3444 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or 3445 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or 3446 // NoSubstitutionTemplate. 3447 // 3448 // When parsing a TemplateLiteral, we must have scanned either an initial 3449 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. 3450 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); 3451 3452 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. 3453 // In this case we may simply consume the token and build a template with a 3454 // single TEMPLATE_SPAN and no expressions. 3455 if (peek() == Token::TEMPLATE_TAIL) { 3456 Consume(Token::TEMPLATE_TAIL); 3457 int pos = position(); 3458 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); 3459 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); 3460 Traits::AddTemplateSpan(&ts, true); 3461 return Traits::CloseTemplateLiteral(&ts, start, tag); 3462 } 3463 3464 Consume(Token::TEMPLATE_SPAN); 3465 int pos = position(); 3466 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); 3467 Traits::AddTemplateSpan(&ts, false); 3468 Token::Value next; 3469 3470 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, 3471 // and repeat if the following token is a TEMPLATE_SPAN as well (in this 3472 // case, representing a TemplateMiddle). 3473 3474 do { 3475 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); 3476 next = peek(); 3477 if (next == Token::EOS) { 3478 ReportMessageAt(Scanner::Location(start, peek_position()), 3479 MessageTemplate::kUnterminatedTemplate); 3480 *ok = false; 3481 return Traits::EmptyExpression(); 3482 } else if (next == Token::ILLEGAL) { 3483 Traits::ReportMessageAt( 3484 Scanner::Location(position() + 1, peek_position()), 3485 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); 3486 *ok = false; 3487 return Traits::EmptyExpression(); 3488 } 3489 3490 int expr_pos = peek_position(); 3491 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); 3492 CheckNoTailCallExpressions(classifier, CHECK_OK); 3493 Traits::RewriteNonPattern(classifier, CHECK_OK); 3494 Traits::AddTemplateExpression(&ts, expression); 3495 3496 if (peek() != Token::RBRACE) { 3497 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), 3498 MessageTemplate::kUnterminatedTemplateExpr); 3499 *ok = false; 3500 return Traits::EmptyExpression(); 3501 } 3502 3503 // If we didn't die parsing that expression, our next token should be a 3504 // TEMPLATE_SPAN or TEMPLATE_TAIL. 3505 next = scanner()->ScanTemplateContinuation(); 3506 Next(); 3507 pos = position(); 3508 3509 if (next == Token::EOS) { 3510 ReportMessageAt(Scanner::Location(start, pos), 3511 MessageTemplate::kUnterminatedTemplate); 3512 *ok = false; 3513 return Traits::EmptyExpression(); 3514 } else if (next == Token::ILLEGAL) { 3515 Traits::ReportMessageAt( 3516 Scanner::Location(position() + 1, peek_position()), 3517 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); 3518 *ok = false; 3519 return Traits::EmptyExpression(); 3520 } 3521 3522 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); 3523 } while (next == Token::TEMPLATE_SPAN); 3524 3525 DCHECK_EQ(next, Token::TEMPLATE_TAIL); 3526 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); 3527 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. 3528 return Traits::CloseTemplateLiteral(&ts, start, tag); 3529} 3530 3531 3532template <typename Traits> 3533typename ParserBase<Traits>::ExpressionT 3534ParserBase<Traits>::CheckAndRewriteReferenceExpression( 3535 ExpressionT expression, int beg_pos, int end_pos, 3536 MessageTemplate::Template message, bool* ok) { 3537 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, 3538 message, kReferenceError, ok); 3539} 3540 3541 3542template <typename Traits> 3543typename ParserBase<Traits>::ExpressionT 3544ParserBase<Traits>::CheckAndRewriteReferenceExpression( 3545 ExpressionT expression, int beg_pos, int end_pos, 3546 MessageTemplate::Template message, ParseErrorType type, bool* ok) { 3547 if (this->IsIdentifier(expression) && is_strict(language_mode()) && 3548 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 3549 ReportMessageAt(Scanner::Location(beg_pos, end_pos), 3550 MessageTemplate::kStrictEvalArguments, kSyntaxError); 3551 *ok = false; 3552 return this->EmptyExpression(); 3553 } 3554 if (expression->IsValidReferenceExpression()) { 3555 return expression; 3556 } 3557 if (expression->IsCall()) { 3558 // If it is a call, make it a runtime error for legacy web compatibility. 3559 // Rewrite `expr' to `expr[throw ReferenceError]'. 3560 ExpressionT error = this->NewThrowReferenceError(message, beg_pos); 3561 return factory()->NewProperty(expression, error, beg_pos); 3562 } 3563 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); 3564 *ok = false; 3565 return this->EmptyExpression(); 3566} 3567 3568 3569template <typename Traits> 3570bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { 3571 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); 3572} 3573 3574 3575template <typename Traits> 3576void ParserBase<Traits>::CheckDestructuringElement( 3577 ExpressionT expression, ExpressionClassifier* classifier, int begin, 3578 int end) { 3579 if (!IsValidPattern(expression) && !expression->IsAssignment() && 3580 !IsValidReferenceExpression(expression)) { 3581 classifier->RecordAssignmentPatternError( 3582 Scanner::Location(begin, end), 3583 MessageTemplate::kInvalidDestructuringTarget); 3584 } 3585} 3586 3587 3588#undef CHECK_OK 3589#undef CHECK_OK_CUSTOM 3590 3591template <typename Traits> 3592void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 3593 Token::Value property, PropertyKind type, MethodKind method_type, 3594 bool* ok) { 3595 DCHECK(!IsStaticMethod(method_type)); 3596 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); 3597 3598 if (property == Token::SMI || property == Token::NUMBER) return; 3599 3600 if (type == kValueProperty && IsProto()) { 3601 if (has_seen_proto_) { 3602 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); 3603 *ok = false; 3604 return; 3605 } 3606 has_seen_proto_ = true; 3607 return; 3608 } 3609} 3610 3611template <typename Traits> 3612void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( 3613 Token::Value property, PropertyKind type, MethodKind method_type, 3614 bool* ok) { 3615 DCHECK(type == kMethodProperty || type == kAccessorProperty); 3616 3617 if (property == Token::SMI || property == Token::NUMBER) return; 3618 3619 if (IsStaticMethod(method_type)) { 3620 if (IsPrototype()) { 3621 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); 3622 *ok = false; 3623 return; 3624 } 3625 } else if (IsConstructor()) { 3626 const bool is_generator = IsGeneratorMethod(method_type); 3627 const bool is_async = IsAsyncMethod(method_type); 3628 if (is_generator || is_async || type == kAccessorProperty) { 3629 MessageTemplate::Template msg = 3630 is_generator ? MessageTemplate::kConstructorIsGenerator 3631 : is_async ? MessageTemplate::kConstructorIsAsync 3632 : MessageTemplate::kConstructorIsAccessor; 3633 this->parser()->ReportMessage(msg); 3634 *ok = false; 3635 return; 3636 } 3637 if (has_seen_constructor_) { 3638 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); 3639 *ok = false; 3640 return; 3641 } 3642 has_seen_constructor_ = true; 3643 return; 3644 } 3645} 3646 3647 3648} // namespace internal 3649} // namespace v8 3650 3651#endif // V8_PARSING_PARSER_BASE_H 3652