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