OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
| 13 #include "src/messages.h" |
13 #include "src/scanner.h" | 14 #include "src/scanner.h" |
14 #include "src/scopes.h" | 15 #include "src/scopes.h" |
15 #include "src/token.h" | 16 #include "src/token.h" |
16 | 17 |
17 namespace v8 { | 18 namespace v8 { |
18 namespace internal { | 19 namespace internal { |
19 | 20 |
20 | 21 |
21 // Common base class shared between parser and pre-parser. Traits encapsulate | 22 // Common base class shared between parser and pre-parser. Traits encapsulate |
22 // the differences between Parser and PreParser: | 23 // the differences between Parser and PreParser: |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 439 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
439 ReportUnexpectedToken(scanner()->current_token()); | 440 ReportUnexpectedToken(scanner()->current_token()); |
440 *ok = false; | 441 *ok = false; |
441 } | 442 } |
442 } | 443 } |
443 | 444 |
444 bool CheckInOrOf( | 445 bool CheckInOrOf( |
445 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { | 446 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { |
446 if (Check(Token::IN)) { | 447 if (Check(Token::IN)) { |
447 if (is_strong(language_mode())) { | 448 if (is_strong(language_mode())) { |
448 ReportMessageAt(scanner()->location(), "strong_for_in"); | 449 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn); |
449 *ok = false; | 450 *ok = false; |
450 } else { | 451 } else { |
451 *visit_mode = ForEachStatement::ENUMERATE; | 452 *visit_mode = ForEachStatement::ENUMERATE; |
452 } | 453 } |
453 return true; | 454 return true; |
454 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { | 455 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { |
455 *visit_mode = ForEachStatement::ITERATE; | 456 *visit_mode = ForEachStatement::ITERATE; |
456 return true; | 457 return true; |
457 } | 458 } |
458 return false; | 459 return false; |
459 } | 460 } |
460 | 461 |
461 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 462 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
462 // If so, reports an error. Only called for strict mode and template strings. | 463 // If so, reports an error. Only called for strict mode and template strings. |
463 void CheckOctalLiteral(int beg_pos, int end_pos, const char* error, | 464 void CheckOctalLiteral(int beg_pos, int end_pos, |
464 bool* ok) { | 465 MessageTemplate::Template message, bool* ok) { |
465 Scanner::Location octal = scanner()->octal_position(); | 466 Scanner::Location octal = scanner()->octal_position(); |
466 if (octal.IsValid() && beg_pos <= octal.beg_pos && | 467 if (octal.IsValid() && beg_pos <= octal.beg_pos && |
467 octal.end_pos <= end_pos) { | 468 octal.end_pos <= end_pos) { |
468 ReportMessageAt(octal, error); | 469 ReportMessageAt(octal, message); |
469 scanner()->clear_octal_position(); | 470 scanner()->clear_octal_position(); |
470 *ok = false; | 471 *ok = false; |
471 } | 472 } |
472 } | 473 } |
473 | 474 |
474 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 475 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
475 CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok); | 476 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
| 477 ok); |
476 } | 478 } |
477 | 479 |
478 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 480 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
479 CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", ok); | 481 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
| 482 ok); |
480 } | 483 } |
481 | 484 |
482 // Checking the name of a function literal. This has to be done after parsing | 485 // Checking the name of a function literal. This has to be done after parsing |
483 // the function, since the function can declare itself strict. | 486 // the function, since the function can declare itself strict. |
484 void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, | 487 void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, |
485 IdentifierT function_name, | 488 IdentifierT function_name, |
486 bool function_name_is_strict_reserved, | 489 bool function_name_is_strict_reserved, |
487 const Scanner::Location& function_name_loc, | 490 const Scanner::Location& function_name_loc, |
488 bool* ok) { | 491 bool* ok) { |
489 // Property names are never checked. | 492 // Property names are never checked. |
490 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return; | 493 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return; |
491 // The function name needs to be checked in strict mode. | 494 // The function name needs to be checked in strict mode. |
492 if (is_sloppy(language_mode)) return; | 495 if (is_sloppy(language_mode)) return; |
493 | 496 |
494 if (this->IsEvalOrArguments(function_name)) { | 497 if (this->IsEvalOrArguments(function_name)) { |
495 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); | 498 Traits::ReportMessageAt(function_name_loc, |
| 499 MessageTemplate::kStrictEvalArguments); |
496 *ok = false; | 500 *ok = false; |
497 return; | 501 return; |
498 } | 502 } |
499 if (function_name_is_strict_reserved) { | 503 if (function_name_is_strict_reserved) { |
500 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); | 504 Traits::ReportMessageAt(function_name_loc, |
| 505 MessageTemplate::kUnexpectedStrictReserved); |
501 *ok = false; | 506 *ok = false; |
502 return; | 507 return; |
503 } | 508 } |
504 if (is_strong(language_mode) && this->IsUndefined(function_name)) { | 509 if (is_strong(language_mode) && this->IsUndefined(function_name)) { |
505 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 510 Traits::ReportMessageAt(function_name_loc, |
| 511 MessageTemplate::kStrongUndefined); |
506 *ok = false; | 512 *ok = false; |
507 return; | 513 return; |
508 } | 514 } |
509 } | 515 } |
510 | 516 |
511 // Determine precedence of given token. | 517 // Determine precedence of given token. |
512 static int Precedence(Token::Value token, bool accept_IN) { | 518 static int Precedence(Token::Value token, bool accept_IN) { |
513 if (token == Token::IN && !accept_IN) | 519 if (token == Token::IN && !accept_IN) |
514 return 0; // 0 precedence will terminate binary expression parsing | 520 return 0; // 0 precedence will terminate binary expression parsing |
515 return Token::Precedence(token); | 521 return Token::Precedence(token); |
516 } | 522 } |
517 | 523 |
518 typename Traits::Type::Factory* factory() { | 524 typename Traits::Type::Factory* factory() { |
519 return function_state_->factory(); | 525 return function_state_->factory(); |
520 } | 526 } |
521 | 527 |
522 LanguageMode language_mode() { return scope_->language_mode(); } | 528 LanguageMode language_mode() { return scope_->language_mode(); } |
523 bool is_generator() const { return function_state_->is_generator(); } | 529 bool is_generator() const { return function_state_->is_generator(); } |
524 | 530 |
525 // Report syntax errors. | 531 // Report syntax errors. |
526 void ReportMessage(const char* message, const char* arg = NULL, | 532 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
527 ParseErrorType error_type = kSyntaxError) { | 533 ParseErrorType error_type = kSyntaxError) { |
528 Scanner::Location source_location = scanner()->location(); | 534 Scanner::Location source_location = scanner()->location(); |
529 Traits::ReportMessageAt(source_location, message, arg, error_type); | 535 Traits::ReportMessageAt(source_location, message, arg, error_type); |
530 } | 536 } |
531 | 537 |
532 void ReportMessageAt(Scanner::Location location, const char* message, | 538 void ReportMessageAt(Scanner::Location location, |
| 539 MessageTemplate::Template message, |
533 ParseErrorType error_type = kSyntaxError) { | 540 ParseErrorType error_type = kSyntaxError) { |
534 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 541 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
535 error_type); | 542 error_type); |
536 } | 543 } |
537 | 544 |
538 void ReportUnexpectedToken(Token::Value token); | 545 void ReportUnexpectedToken(Token::Value token); |
539 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); | 546 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); |
540 | 547 |
541 class ExpressionClassifier { | 548 class ExpressionClassifier { |
542 public: | 549 public: |
543 struct Error { | 550 struct Error { |
544 Error() | 551 Error() |
545 : location(Scanner::Location::invalid()), | 552 : location(Scanner::Location::invalid()), |
546 message(nullptr), | 553 message(MessageTemplate::kNone), |
547 arg(nullptr) {} | 554 arg(nullptr) {} |
548 | 555 |
549 Scanner::Location location; | 556 Scanner::Location location; |
550 const char* message; | 557 MessageTemplate::Template message; |
551 const char* arg; | 558 const char* arg; |
552 | 559 |
553 bool HasError() const { return location.IsValid(); } | 560 bool HasError() const { return location.IsValid(); } |
554 }; | 561 }; |
555 | 562 |
556 ExpressionClassifier() {} | 563 ExpressionClassifier() {} |
557 | 564 |
558 bool is_valid_expression() const { return !expression_error_.HasError(); } | 565 bool is_valid_expression() const { return !expression_error_.HasError(); } |
559 | 566 |
560 bool is_valid_binding_pattern() const { | 567 bool is_valid_binding_pattern() const { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 | 612 |
606 const Error& strict_mode_formal_parameter_error() const { | 613 const Error& strict_mode_formal_parameter_error() const { |
607 return strict_mode_formal_parameter_error_; | 614 return strict_mode_formal_parameter_error_; |
608 } | 615 } |
609 | 616 |
610 const Error& strong_mode_formal_parameter_error() const { | 617 const Error& strong_mode_formal_parameter_error() const { |
611 return strong_mode_formal_parameter_error_; | 618 return strong_mode_formal_parameter_error_; |
612 } | 619 } |
613 | 620 |
614 void RecordExpressionError(const Scanner::Location& loc, | 621 void RecordExpressionError(const Scanner::Location& loc, |
615 const char* message, const char* arg = nullptr) { | 622 MessageTemplate::Template message, |
| 623 const char* arg = nullptr) { |
616 if (!is_valid_expression()) return; | 624 if (!is_valid_expression()) return; |
617 expression_error_.location = loc; | 625 expression_error_.location = loc; |
618 expression_error_.message = message; | 626 expression_error_.message = message; |
619 expression_error_.arg = arg; | 627 expression_error_.arg = arg; |
620 } | 628 } |
621 | 629 |
622 void RecordBindingPatternError(const Scanner::Location& loc, | 630 void RecordBindingPatternError(const Scanner::Location& loc, |
623 const char* message, | 631 MessageTemplate::Template message, |
624 const char* arg = nullptr) { | 632 const char* arg = nullptr) { |
625 if (!is_valid_binding_pattern()) return; | 633 if (!is_valid_binding_pattern()) return; |
626 binding_pattern_error_.location = loc; | 634 binding_pattern_error_.location = loc; |
627 binding_pattern_error_.message = message; | 635 binding_pattern_error_.message = message; |
628 binding_pattern_error_.arg = arg; | 636 binding_pattern_error_.arg = arg; |
629 } | 637 } |
630 | 638 |
631 void RecordAssignmentPatternError(const Scanner::Location& loc, | 639 void RecordAssignmentPatternError(const Scanner::Location& loc, |
632 const char* message, | 640 MessageTemplate::Template message, |
633 const char* arg = nullptr) { | 641 const char* arg = nullptr) { |
634 if (!is_valid_assignment_pattern()) return; | 642 if (!is_valid_assignment_pattern()) return; |
635 assignment_pattern_error_.location = loc; | 643 assignment_pattern_error_.location = loc; |
636 assignment_pattern_error_.message = message; | 644 assignment_pattern_error_.message = message; |
637 assignment_pattern_error_.arg = arg; | 645 assignment_pattern_error_.arg = arg; |
638 } | 646 } |
639 | 647 |
640 void RecordArrowFormalParametersError(const Scanner::Location& loc, | 648 void RecordArrowFormalParametersError(const Scanner::Location& loc, |
641 const char* message, | 649 MessageTemplate::Template message, |
642 const char* arg = nullptr) { | 650 const char* arg = nullptr) { |
643 if (!is_valid_arrow_formal_parameters()) return; | 651 if (!is_valid_arrow_formal_parameters()) return; |
644 arrow_formal_parameters_error_.location = loc; | 652 arrow_formal_parameters_error_.location = loc; |
645 arrow_formal_parameters_error_.message = message; | 653 arrow_formal_parameters_error_.message = message; |
646 arrow_formal_parameters_error_.arg = arg; | 654 arrow_formal_parameters_error_.arg = arg; |
647 } | 655 } |
648 | 656 |
649 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | 657 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
650 if (!is_valid_formal_parameter_list_without_duplicates()) return; | 658 if (!is_valid_formal_parameter_list_without_duplicates()) return; |
651 duplicate_formal_parameter_error_.location = loc; | 659 duplicate_formal_parameter_error_.location = loc; |
652 duplicate_formal_parameter_error_.message = "strict_param_dupe"; | 660 duplicate_formal_parameter_error_.message = |
| 661 MessageTemplate::kStrictParamDupe; |
653 duplicate_formal_parameter_error_.arg = nullptr; | 662 duplicate_formal_parameter_error_.arg = nullptr; |
654 } | 663 } |
655 | 664 |
656 // Record a binding that would be invalid in strict mode. Confusingly this | 665 // Record a binding that would be invalid in strict mode. Confusingly this |
657 // is not the same as StrictFormalParameterList, which simply forbids | 666 // is not the same as StrictFormalParameterList, which simply forbids |
658 // duplicate bindings. | 667 // duplicate bindings. |
659 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, | 668 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
660 const char* message, | 669 MessageTemplate::Template message, |
661 const char* arg = nullptr) { | 670 const char* arg = nullptr) { |
662 if (!is_valid_strict_mode_formal_parameters()) return; | 671 if (!is_valid_strict_mode_formal_parameters()) return; |
663 strict_mode_formal_parameter_error_.location = loc; | 672 strict_mode_formal_parameter_error_.location = loc; |
664 strict_mode_formal_parameter_error_.message = message; | 673 strict_mode_formal_parameter_error_.message = message; |
665 strict_mode_formal_parameter_error_.arg = arg; | 674 strict_mode_formal_parameter_error_.arg = arg; |
666 } | 675 } |
667 | 676 |
668 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, | 677 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
669 const char* message, | 678 MessageTemplate::Template message, |
670 const char* arg = nullptr) { | 679 const char* arg = nullptr) { |
671 if (!is_valid_strong_mode_formal_parameters()) return; | 680 if (!is_valid_strong_mode_formal_parameters()) return; |
672 strong_mode_formal_parameter_error_.location = loc; | 681 strong_mode_formal_parameter_error_.location = loc; |
673 strong_mode_formal_parameter_error_.message = message; | 682 strong_mode_formal_parameter_error_.message = message; |
674 strong_mode_formal_parameter_error_.arg = arg; | 683 strong_mode_formal_parameter_error_.arg = arg; |
675 } | 684 } |
676 | 685 |
677 enum TargetProduction { | 686 enum TargetProduction { |
678 ExpressionProduction = 1 << 0, | 687 ExpressionProduction = 1 << 0, |
679 BindingPatternProduction = 1 << 1, | 688 BindingPatternProduction = 1 << 1, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 ReportClassifierError(classifier->strong_mode_formal_parameter_error()); | 785 ReportClassifierError(classifier->strong_mode_formal_parameter_error()); |
777 *ok = false; | 786 *ok = false; |
778 } | 787 } |
779 } | 788 } |
780 | 789 |
781 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 790 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
782 ExpressionT expr, bool* ok) { | 791 ExpressionT expr, bool* ok) { |
783 if (classifier->is_valid_binding_pattern()) { | 792 if (classifier->is_valid_binding_pattern()) { |
784 // A simple arrow formal parameter: IDENTIFIER => BODY. | 793 // A simple arrow formal parameter: IDENTIFIER => BODY. |
785 if (!this->IsIdentifier(expr)) { | 794 if (!this->IsIdentifier(expr)) { |
786 Traits::ReportMessageAt(scanner()->location(), "unexpected_token", | 795 Traits::ReportMessageAt(scanner()->location(), |
| 796 MessageTemplate::kUnexpectedToken, |
787 Token::String(scanner()->current_token())); | 797 Token::String(scanner()->current_token())); |
788 *ok = false; | 798 *ok = false; |
789 } | 799 } |
790 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 800 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
791 ReportClassifierError(classifier->arrow_formal_parameters_error()); | 801 ReportClassifierError(classifier->arrow_formal_parameters_error()); |
792 *ok = false; | 802 *ok = false; |
793 } | 803 } |
794 } | 804 } |
795 | 805 |
796 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 806 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
797 classifier->RecordBindingPatternError( | 807 classifier->RecordBindingPatternError(scanner()->peek_location(), |
798 scanner()->peek_location(), "unexpected_token", Token::String(peek())); | 808 MessageTemplate::kUnexpectedToken, |
| 809 Token::String(peek())); |
799 } | 810 } |
800 | 811 |
801 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { | 812 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { |
802 classifier->RecordArrowFormalParametersError( | 813 classifier->RecordArrowFormalParametersError( |
803 scanner()->peek_location(), "unexpected_token", Token::String(peek())); | 814 scanner()->peek_location(), MessageTemplate::kUnexpectedToken, |
| 815 Token::String(peek())); |
804 } | 816 } |
805 | 817 |
806 // Recursive descent functions: | 818 // Recursive descent functions: |
807 | 819 |
808 // Parses an identifier that is valid for the current scope, in particular it | 820 // Parses an identifier that is valid for the current scope, in particular it |
809 // fails on strict mode future reserved keywords in a strict scope. If | 821 // fails on strict mode future reserved keywords in a strict scope. If |
810 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 822 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
811 // "arguments" as identifier even in strict mode (this is needed in cases like | 823 // "arguments" as identifier even in strict mode (this is needed in cases like |
812 // "var foo = eval;"). | 824 // "var foo = eval;"). |
813 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 825 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest, | 892 int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest, |
881 ExpressionClassifier* classifier, bool* ok); | 893 ExpressionClassifier* classifier, bool* ok); |
882 void CheckArityRestrictions( | 894 void CheckArityRestrictions( |
883 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 895 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
884 int formals_start_pos, int formals_end_pos, bool* ok); | 896 int formals_start_pos, int formals_end_pos, bool* ok); |
885 | 897 |
886 // Checks if the expression is a valid reference expression (e.g., on the | 898 // Checks if the expression is a valid reference expression (e.g., on the |
887 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 899 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
888 // we allow calls for web compatibility and rewrite them to a runtime throw. | 900 // we allow calls for web compatibility and rewrite them to a runtime throw. |
889 ExpressionT CheckAndRewriteReferenceExpression( | 901 ExpressionT CheckAndRewriteReferenceExpression( |
890 ExpressionT expression, | 902 ExpressionT expression, Scanner::Location location, |
891 Scanner::Location location, const char* message, bool* ok); | 903 MessageTemplate::Template message, bool* ok); |
892 | 904 |
893 // Used to validate property names in object literals and class literals | 905 // Used to validate property names in object literals and class literals |
894 enum PropertyKind { | 906 enum PropertyKind { |
895 kAccessorProperty, | 907 kAccessorProperty, |
896 kValueProperty, | 908 kValueProperty, |
897 kMethodProperty | 909 kMethodProperty |
898 }; | 910 }; |
899 | 911 |
900 class ObjectLiteralCheckerBase { | 912 class ObjectLiteralCheckerBase { |
901 public: | 913 public: |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 PreParserFactory* factory) { | 1608 PreParserFactory* factory) { |
1597 return false; | 1609 return false; |
1598 } | 1610 } |
1599 | 1611 |
1600 PreParserExpression BuildUnaryExpression(PreParserExpression expression, | 1612 PreParserExpression BuildUnaryExpression(PreParserExpression expression, |
1601 Token::Value op, int pos, | 1613 Token::Value op, int pos, |
1602 PreParserFactory* factory) { | 1614 PreParserFactory* factory) { |
1603 return PreParserExpression::Default(); | 1615 return PreParserExpression::Default(); |
1604 } | 1616 } |
1605 | 1617 |
1606 PreParserExpression NewThrowReferenceError(const char* type, int pos) { | 1618 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message, |
| 1619 int pos) { |
1607 return PreParserExpression::Default(); | 1620 return PreParserExpression::Default(); |
1608 } | 1621 } |
1609 PreParserExpression NewThrowSyntaxError( | 1622 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message, |
1610 const char* type, Handle<Object> arg, int pos) { | 1623 Handle<Object> arg, int pos) { |
1611 return PreParserExpression::Default(); | 1624 return PreParserExpression::Default(); |
1612 } | 1625 } |
1613 PreParserExpression NewThrowTypeError( | 1626 PreParserExpression NewThrowTypeError(MessageTemplate::Template message, |
1614 const char* type, Handle<Object> arg, int pos) { | 1627 Handle<Object> arg, int pos) { |
1615 return PreParserExpression::Default(); | 1628 return PreParserExpression::Default(); |
1616 } | 1629 } |
1617 | 1630 |
1618 // Reporting errors. | 1631 // Reporting errors. |
1619 void ReportMessageAt(Scanner::Location location, const char* message, | 1632 void ReportMessageAt(Scanner::Location location, |
| 1633 MessageTemplate::Template message, |
1620 const char* arg = NULL, | 1634 const char* arg = NULL, |
1621 ParseErrorType error_type = kSyntaxError); | 1635 ParseErrorType error_type = kSyntaxError); |
1622 void ReportMessageAt(int start_pos, int end_pos, const char* message, | 1636 void ReportMessageAt(int start_pos, int end_pos, |
| 1637 MessageTemplate::Template message, |
1623 const char* arg = NULL, | 1638 const char* arg = NULL, |
1624 ParseErrorType error_type = kSyntaxError); | 1639 ParseErrorType error_type = kSyntaxError); |
1625 | 1640 |
1626 // "null" return type creators. | 1641 // "null" return type creators. |
1627 static PreParserIdentifier EmptyIdentifier() { | 1642 static PreParserIdentifier EmptyIdentifier() { |
1628 return PreParserIdentifier::Default(); | 1643 return PreParserIdentifier::Default(); |
1629 } | 1644 } |
1630 static PreParserIdentifier EmptyIdentifierString() { | 1645 static PreParserIdentifier EmptyIdentifierString() { |
1631 return PreParserIdentifier::Default(); | 1646 return PreParserIdentifier::Default(); |
1632 } | 1647 } |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 } | 2031 } |
2017 | 2032 |
2018 | 2033 |
2019 template<class Traits> | 2034 template<class Traits> |
2020 void ParserBase<Traits>::ReportUnexpectedTokenAt( | 2035 void ParserBase<Traits>::ReportUnexpectedTokenAt( |
2021 Scanner::Location source_location, Token::Value token) { | 2036 Scanner::Location source_location, Token::Value token) { |
2022 | 2037 |
2023 // Four of the tokens are treated specially | 2038 // Four of the tokens are treated specially |
2024 switch (token) { | 2039 switch (token) { |
2025 case Token::EOS: | 2040 case Token::EOS: |
2026 return ReportMessageAt(source_location, "unexpected_eos"); | 2041 return ReportMessageAt(source_location, MessageTemplate::kUnexpectedEOS); |
2027 case Token::SMI: | 2042 case Token::SMI: |
2028 case Token::NUMBER: | 2043 case Token::NUMBER: |
2029 return ReportMessageAt(source_location, "unexpected_token_number"); | 2044 return ReportMessageAt(source_location, |
| 2045 MessageTemplate::kUnexpectedTokenNumber); |
2030 case Token::STRING: | 2046 case Token::STRING: |
2031 return ReportMessageAt(source_location, "unexpected_token_string"); | 2047 return ReportMessageAt(source_location, |
| 2048 MessageTemplate::kUnexpectedTokenString); |
2032 case Token::IDENTIFIER: | 2049 case Token::IDENTIFIER: |
2033 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 2050 return ReportMessageAt(source_location, |
| 2051 MessageTemplate::kUnexpectedTokenIdentifier); |
2034 case Token::FUTURE_RESERVED_WORD: | 2052 case Token::FUTURE_RESERVED_WORD: |
2035 return ReportMessageAt(source_location, "unexpected_reserved"); | 2053 return ReportMessageAt(source_location, |
| 2054 MessageTemplate::kUnexpectedReserved); |
2036 case Token::LET: | 2055 case Token::LET: |
2037 case Token::STATIC: | 2056 case Token::STATIC: |
2038 case Token::YIELD: | 2057 case Token::YIELD: |
2039 case Token::FUTURE_STRICT_RESERVED_WORD: | 2058 case Token::FUTURE_STRICT_RESERVED_WORD: |
2040 return ReportMessageAt(source_location, | 2059 return ReportMessageAt(source_location, |
2041 is_strict(language_mode()) | 2060 is_strict(language_mode()) |
2042 ? "unexpected_strict_reserved" | 2061 ? MessageTemplate::kUnexpectedStrictReserved |
2043 : "unexpected_token_identifier"); | 2062 : MessageTemplate::kUnexpectedTokenIdentifier); |
2044 case Token::TEMPLATE_SPAN: | 2063 case Token::TEMPLATE_SPAN: |
2045 case Token::TEMPLATE_TAIL: | 2064 case Token::TEMPLATE_TAIL: |
2046 return Traits::ReportMessageAt(source_location, | 2065 return Traits::ReportMessageAt( |
2047 "unexpected_template_string"); | 2066 source_location, MessageTemplate::kUnexpectedTemplateString); |
2048 default: | 2067 default: |
2049 const char* name = Token::String(token); | 2068 const char* name = Token::String(token); |
2050 DCHECK(name != NULL); | 2069 DCHECK(name != NULL); |
2051 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 2070 Traits::ReportMessageAt(source_location, |
| 2071 MessageTemplate::kUnexpectedToken, name); |
2052 } | 2072 } |
2053 } | 2073 } |
2054 | 2074 |
2055 | 2075 |
2056 template <class Traits> | 2076 template <class Traits> |
2057 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 2077 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
2058 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 2078 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
2059 ExpressionClassifier classifier; | 2079 ExpressionClassifier classifier; |
2060 auto result = ParseAndClassifyIdentifier(&classifier, ok); | 2080 auto result = ParseAndClassifyIdentifier(&classifier, ok); |
2061 if (!*ok) return Traits::EmptyIdentifier(); | 2081 if (!*ok) return Traits::EmptyIdentifier(); |
(...skipping 19 matching lines...) Expand all Loading... |
2081 Token::Value next = Next(); | 2101 Token::Value next = Next(); |
2082 if (next == Token::IDENTIFIER) { | 2102 if (next == Token::IDENTIFIER) { |
2083 IdentifierT name = this->GetSymbol(scanner()); | 2103 IdentifierT name = this->GetSymbol(scanner()); |
2084 // When this function is used to read a formal parameter, we don't always | 2104 // When this function is used to read a formal parameter, we don't always |
2085 // know whether the function is going to be strict or sloppy. Indeed for | 2105 // know whether the function is going to be strict or sloppy. Indeed for |
2086 // arrow functions we don't always know that the identifier we are reading | 2106 // arrow functions we don't always know that the identifier we are reading |
2087 // is actually a formal parameter. Therefore besides the errors that we | 2107 // is actually a formal parameter. Therefore besides the errors that we |
2088 // must detect because we know we're in strict mode, we also record any | 2108 // must detect because we know we're in strict mode, we also record any |
2089 // error that we might make in the future once we know the language mode. | 2109 // error that we might make in the future once we know the language mode. |
2090 if (this->IsEval(name)) { | 2110 if (this->IsEval(name)) { |
2091 classifier->RecordStrictModeFormalParameterError(scanner()->location(), | 2111 classifier->RecordStrictModeFormalParameterError( |
2092 "strict_eval_arguments"); | 2112 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
2093 if (is_strict(language_mode())) { | 2113 if (is_strict(language_mode())) { |
2094 classifier->RecordBindingPatternError(scanner()->location(), | 2114 classifier->RecordBindingPatternError( |
2095 "strict_eval_arguments"); | 2115 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
2096 } | 2116 } |
2097 } | 2117 } |
2098 if (this->IsArguments(name)) { | 2118 if (this->IsArguments(name)) { |
2099 scope_->RecordArgumentsUsage(); | 2119 scope_->RecordArgumentsUsage(); |
2100 classifier->RecordStrictModeFormalParameterError(scanner()->location(), | 2120 classifier->RecordStrictModeFormalParameterError( |
2101 "strict_eval_arguments"); | 2121 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
2102 if (is_strict(language_mode())) { | 2122 if (is_strict(language_mode())) { |
2103 classifier->RecordBindingPatternError(scanner()->location(), | 2123 classifier->RecordBindingPatternError( |
2104 "strict_eval_arguments"); | 2124 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
2105 } | 2125 } |
2106 if (is_strong(language_mode())) { | 2126 if (is_strong(language_mode())) { |
2107 classifier->RecordExpressionError(scanner()->location(), | 2127 classifier->RecordExpressionError(scanner()->location(), |
2108 "strong_arguments"); | 2128 MessageTemplate::kStrongArguments); |
2109 } | 2129 } |
2110 } | 2130 } |
2111 if (this->IsUndefined(name)) { | 2131 if (this->IsUndefined(name)) { |
2112 classifier->RecordStrongModeFormalParameterError(scanner()->location(), | 2132 classifier->RecordStrongModeFormalParameterError( |
2113 "strong_undefined"); | 2133 scanner()->location(), MessageTemplate::kStrongUndefined); |
2114 if (is_strong(language_mode())) { | 2134 if (is_strong(language_mode())) { |
2115 // TODO(dslomov): allow 'undefined' in nested patterns. | 2135 // TODO(dslomov): allow 'undefined' in nested patterns. |
2116 classifier->RecordBindingPatternError(scanner()->location(), | 2136 classifier->RecordBindingPatternError( |
2117 "strong_undefined"); | 2137 scanner()->location(), MessageTemplate::kStrongUndefined); |
2118 classifier->RecordAssignmentPatternError(scanner()->location(), | 2138 classifier->RecordAssignmentPatternError( |
2119 "strong_undefined"); | 2139 scanner()->location(), MessageTemplate::kStrongUndefined); |
2120 } | 2140 } |
2121 } | 2141 } |
2122 return name; | 2142 return name; |
2123 } else if (is_sloppy(language_mode()) && | 2143 } else if (is_sloppy(language_mode()) && |
2124 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 2144 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
2125 next == Token::LET || next == Token::STATIC || | 2145 next == Token::LET || next == Token::STATIC || |
2126 (next == Token::YIELD && !is_generator()))) { | 2146 (next == Token::YIELD && !is_generator()))) { |
2127 classifier->RecordStrictModeFormalParameterError( | 2147 classifier->RecordStrictModeFormalParameterError( |
2128 scanner()->location(), "unexpected_strict_reserved"); | 2148 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
2129 return this->GetSymbol(scanner()); | 2149 return this->GetSymbol(scanner()); |
2130 } else { | 2150 } else { |
2131 this->ReportUnexpectedToken(next); | 2151 this->ReportUnexpectedToken(next); |
2132 *ok = false; | 2152 *ok = false; |
2133 return Traits::EmptyIdentifier(); | 2153 return Traits::EmptyIdentifier(); |
2134 } | 2154 } |
2135 } | 2155 } |
2136 | 2156 |
2137 | 2157 |
2138 template <class Traits> | 2158 template <class Traits> |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2187 return result; | 2207 return result; |
2188 } | 2208 } |
2189 | 2209 |
2190 | 2210 |
2191 template <class Traits> | 2211 template <class Traits> |
2192 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 2212 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
2193 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { | 2213 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
2194 int pos = peek_position(); | 2214 int pos = peek_position(); |
2195 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 2215 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
2196 Next(); | 2216 Next(); |
2197 ReportMessage("unterminated_regexp"); | 2217 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
2198 *ok = false; | 2218 *ok = false; |
2199 return Traits::EmptyExpression(); | 2219 return Traits::EmptyExpression(); |
2200 } | 2220 } |
2201 | 2221 |
2202 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2222 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2203 | 2223 |
2204 IdentifierT js_pattern = this->GetNextSymbol(scanner()); | 2224 IdentifierT js_pattern = this->GetNextSymbol(scanner()); |
2205 if (!scanner()->ScanRegExpFlags()) { | 2225 if (!scanner()->ScanRegExpFlags()) { |
2206 Next(); | 2226 Next(); |
2207 ReportMessage("malformed_regexp_flags"); | 2227 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
2208 *ok = false; | 2228 *ok = false; |
2209 return Traits::EmptyExpression(); | 2229 return Traits::EmptyExpression(); |
2210 } | 2230 } |
2211 IdentifierT js_flags = this->GetNextSymbol(scanner()); | 2231 IdentifierT js_flags = this->GetNextSymbol(scanner()); |
2212 Next(); | 2232 Next(); |
2213 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 2233 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
2214 } | 2234 } |
2215 | 2235 |
2216 | 2236 |
2217 #define CHECK_OK ok); \ | 2237 #define CHECK_OK ok); \ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 ExpressionT result = this->EmptyExpression(); | 2272 ExpressionT result = this->EmptyExpression(); |
2253 Token::Value token = peek(); | 2273 Token::Value token = peek(); |
2254 switch (token) { | 2274 switch (token) { |
2255 case Token::THIS: { | 2275 case Token::THIS: { |
2256 BindingPatternUnexpectedToken(classifier); | 2276 BindingPatternUnexpectedToken(classifier); |
2257 Consume(Token::THIS); | 2277 Consume(Token::THIS); |
2258 if (is_strong(language_mode())) { | 2278 if (is_strong(language_mode())) { |
2259 // Constructors' usages of 'this' in strong mode are parsed separately. | 2279 // Constructors' usages of 'this' in strong mode are parsed separately. |
2260 // TODO(rossberg): this does not work with arrow functions yet. | 2280 // TODO(rossberg): this does not work with arrow functions yet. |
2261 if (i::IsConstructor(function_state_->kind())) { | 2281 if (i::IsConstructor(function_state_->kind())) { |
2262 ReportMessage("strong_constructor_this"); | 2282 ReportMessage(MessageTemplate::kStrongConstructorThis); |
2263 *ok = false; | 2283 *ok = false; |
2264 break; | 2284 break; |
2265 } | 2285 } |
2266 } | 2286 } |
2267 scope_->RecordThisUsage(); | 2287 scope_->RecordThisUsage(); |
2268 result = this->ThisExpression(scope_, factory(), beg_pos); | 2288 result = this->ThisExpression(scope_, factory(), beg_pos); |
2269 break; | 2289 break; |
2270 } | 2290 } |
2271 | 2291 |
2272 case Token::NULL_LITERAL: | 2292 case Token::NULL_LITERAL: |
2273 case Token::TRUE_LITERAL: | 2293 case Token::TRUE_LITERAL: |
2274 case Token::FALSE_LITERAL: | 2294 case Token::FALSE_LITERAL: |
2275 BindingPatternUnexpectedToken(classifier); | 2295 BindingPatternUnexpectedToken(classifier); |
2276 Next(); | 2296 Next(); |
2277 result = | 2297 result = |
2278 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2298 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
2279 break; | 2299 break; |
2280 case Token::SMI: | 2300 case Token::SMI: |
2281 case Token::NUMBER: | 2301 case Token::NUMBER: |
2282 classifier->RecordBindingPatternError(scanner()->location(), | 2302 classifier->RecordBindingPatternError( |
2283 "unexpected_token_number"); | 2303 scanner()->location(), MessageTemplate::kUnexpectedTokenNumber); |
2284 Next(); | 2304 Next(); |
2285 result = | 2305 result = |
2286 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2306 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
2287 break; | 2307 break; |
2288 | 2308 |
2289 case Token::IDENTIFIER: | 2309 case Token::IDENTIFIER: |
2290 case Token::LET: | 2310 case Token::LET: |
2291 case Token::STATIC: | 2311 case Token::STATIC: |
2292 case Token::YIELD: | 2312 case Token::YIELD: |
2293 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2313 case Token::FUTURE_STRICT_RESERVED_WORD: { |
2294 // Using eval or arguments in this context is OK even in strict mode. | 2314 // Using eval or arguments in this context is OK even in strict mode. |
2295 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2315 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
2296 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2316 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
2297 factory()); | 2317 factory()); |
2298 break; | 2318 break; |
2299 } | 2319 } |
2300 | 2320 |
2301 case Token::STRING: { | 2321 case Token::STRING: { |
2302 classifier->RecordBindingPatternError(scanner()->location(), | 2322 classifier->RecordBindingPatternError( |
2303 "unexpected_token_string"); | 2323 scanner()->location(), MessageTemplate::kUnexpectedTokenString); |
2304 Consume(Token::STRING); | 2324 Consume(Token::STRING); |
2305 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2325 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
2306 break; | 2326 break; |
2307 } | 2327 } |
2308 | 2328 |
2309 case Token::ASSIGN_DIV: | 2329 case Token::ASSIGN_DIV: |
2310 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); | 2330 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); |
2311 break; | 2331 break; |
2312 | 2332 |
2313 case Token::DIV: | 2333 case Token::DIV: |
(...skipping 21 matching lines...) Expand all Loading... |
2335 // is_valid_binding_pattern() check to detect multiple levels of | 2355 // is_valid_binding_pattern() check to detect multiple levels of |
2336 // parenthesization. | 2356 // parenthesization. |
2337 if (!classifier->is_valid_binding_pattern()) { | 2357 if (!classifier->is_valid_binding_pattern()) { |
2338 ArrowFormalParametersUnexpectedToken(classifier); | 2358 ArrowFormalParametersUnexpectedToken(classifier); |
2339 } | 2359 } |
2340 BindingPatternUnexpectedToken(classifier); | 2360 BindingPatternUnexpectedToken(classifier); |
2341 Consume(Token::LPAREN); | 2361 Consume(Token::LPAREN); |
2342 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2362 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2343 // As a primary expression, the only thing that can follow "()" is "=>". | 2363 // As a primary expression, the only thing that can follow "()" is "=>". |
2344 classifier->RecordBindingPatternError(scanner()->location(), | 2364 classifier->RecordBindingPatternError(scanner()->location(), |
2345 "unexpected_token", | 2365 MessageTemplate::kUnexpectedToken, |
2346 Token::String(Token::RPAREN)); | 2366 Token::String(Token::RPAREN)); |
2347 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2367 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
2348 scope->set_start_position(beg_pos); | 2368 scope->set_start_position(beg_pos); |
2349 ExpressionClassifier args_classifier; | 2369 ExpressionClassifier args_classifier; |
2350 bool has_rest = false; | 2370 bool has_rest = false; |
2351 result = this->ParseArrowFunctionLiteral(scope, has_rest, | 2371 result = this->ParseArrowFunctionLiteral(scope, has_rest, |
2352 args_classifier, CHECK_OK); | 2372 args_classifier, CHECK_OK); |
2353 } else { | 2373 } else { |
2354 // Heuristically try to detect immediately called functions before | 2374 // Heuristically try to detect immediately called functions before |
2355 // seeing the call parentheses. | 2375 // seeing the call parentheses. |
2356 parenthesized_function_ = (peek() == Token::FUNCTION); | 2376 parenthesized_function_ = (peek() == Token::FUNCTION); |
2357 result = this->ParseExpression(true, classifier, CHECK_OK); | 2377 result = this->ParseExpression(true, classifier, CHECK_OK); |
2358 Expect(Token::RPAREN, CHECK_OK); | 2378 Expect(Token::RPAREN, CHECK_OK); |
2359 } | 2379 } |
2360 break; | 2380 break; |
2361 | 2381 |
2362 case Token::CLASS: { | 2382 case Token::CLASS: { |
2363 BindingPatternUnexpectedToken(classifier); | 2383 BindingPatternUnexpectedToken(classifier); |
2364 Consume(Token::CLASS); | 2384 Consume(Token::CLASS); |
2365 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2385 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2366 ReportMessage("sloppy_lexical"); | 2386 ReportMessage(MessageTemplate::kSloppyLexical); |
2367 *ok = false; | 2387 *ok = false; |
2368 break; | 2388 break; |
2369 } | 2389 } |
2370 int class_token_position = position(); | 2390 int class_token_position = position(); |
2371 IdentifierT name = this->EmptyIdentifier(); | 2391 IdentifierT name = this->EmptyIdentifier(); |
2372 bool is_strict_reserved_name = false; | 2392 bool is_strict_reserved_name = false; |
2373 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2393 Scanner::Location class_name_location = Scanner::Location::invalid(); |
2374 if (peek_any_identifier()) { | 2394 if (peek_any_identifier()) { |
2375 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2395 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
2376 CHECK_OK); | 2396 CHECK_OK); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2450 // '[' Expression? (',' Expression?)* ']' | 2470 // '[' Expression? (',' Expression?)* ']' |
2451 | 2471 |
2452 int pos = peek_position(); | 2472 int pos = peek_position(); |
2453 typename Traits::Type::ExpressionList values = | 2473 typename Traits::Type::ExpressionList values = |
2454 this->NewExpressionList(4, zone_); | 2474 this->NewExpressionList(4, zone_); |
2455 Expect(Token::LBRACK, CHECK_OK); | 2475 Expect(Token::LBRACK, CHECK_OK); |
2456 while (peek() != Token::RBRACK) { | 2476 while (peek() != Token::RBRACK) { |
2457 ExpressionT elem = this->EmptyExpression(); | 2477 ExpressionT elem = this->EmptyExpression(); |
2458 if (peek() == Token::COMMA) { | 2478 if (peek() == Token::COMMA) { |
2459 if (is_strong(language_mode())) { | 2479 if (is_strong(language_mode())) { |
2460 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); | 2480 ReportMessageAt(scanner()->peek_location(), |
| 2481 MessageTemplate::kStrongEllision); |
2461 *ok = false; | 2482 *ok = false; |
2462 return this->EmptyExpression(); | 2483 return this->EmptyExpression(); |
2463 } | 2484 } |
2464 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2485 elem = this->GetLiteralTheHole(peek_position(), factory()); |
2465 } else { | 2486 } else { |
2466 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2487 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2467 } | 2488 } |
2468 values->Add(elem, zone_); | 2489 values->Add(elem, zone_); |
2469 if (peek() != Token::RBRACK) { | 2490 if (peek() != Token::RBRACK) { |
2470 Expect(Token::COMMA, CHECK_OK); | 2491 Expect(Token::COMMA, CHECK_OK); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 // unspread_sequences_count is the number of sequences of parameters which | 2789 // unspread_sequences_count is the number of sequences of parameters which |
2769 // are not prefixed with a spread '...' operator. | 2790 // are not prefixed with a spread '...' operator. |
2770 if (is_spread) { | 2791 if (is_spread) { |
2771 was_unspread = false; | 2792 was_unspread = false; |
2772 } else if (!was_unspread) { | 2793 } else if (!was_unspread) { |
2773 was_unspread = true; | 2794 was_unspread = true; |
2774 unspread_sequences_count++; | 2795 unspread_sequences_count++; |
2775 } | 2796 } |
2776 | 2797 |
2777 if (result->length() > Code::kMaxArguments) { | 2798 if (result->length() > Code::kMaxArguments) { |
2778 ReportMessage("too_many_arguments"); | 2799 ReportMessage(MessageTemplate::kTooManyArguments); |
2779 *ok = false; | 2800 *ok = false; |
2780 return this->NullExpressionList(); | 2801 return this->NullExpressionList(); |
2781 } | 2802 } |
2782 done = (peek() != Token::COMMA); | 2803 done = (peek() != Token::COMMA); |
2783 if (!done) { | 2804 if (!done) { |
2784 Next(); | 2805 Next(); |
2785 } | 2806 } |
2786 } | 2807 } |
2787 Scanner::Location location = scanner_->location(); | 2808 Scanner::Location location = scanner_->location(); |
2788 if (Token::RPAREN != Next()) { | 2809 if (Token::RPAREN != Next()) { |
2789 ReportMessageAt(location, "unterminated_arg_list"); | 2810 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
2790 *ok = false; | 2811 *ok = false; |
2791 return this->NullExpressionList(); | 2812 return this->NullExpressionList(); |
2792 } | 2813 } |
2793 *first_spread_arg_loc = spread_arg; | 2814 *first_spread_arg_loc = spread_arg; |
2794 | 2815 |
2795 if (spread_arg.IsValid()) { | 2816 if (spread_arg.IsValid()) { |
2796 // Unspread parameter sequences are translated into array literals in the | 2817 // Unspread parameter sequences are translated into array literals in the |
2797 // parser. Ensure that the number of materialized literals matches between | 2818 // parser. Ensure that the number of materialized literals matches between |
2798 // the parser and preparser | 2819 // the parser and preparser |
2799 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2820 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 if (fni_ != NULL) fni_->Leave(); | 2883 if (fni_ != NULL) fni_->Leave(); |
2863 // Parsed conditional expression only (no assignment). | 2884 // Parsed conditional expression only (no assignment). |
2864 return expression; | 2885 return expression; |
2865 } | 2886 } |
2866 | 2887 |
2867 if (!allow_harmony_destructuring()) { | 2888 if (!allow_harmony_destructuring()) { |
2868 BindingPatternUnexpectedToken(classifier); | 2889 BindingPatternUnexpectedToken(classifier); |
2869 } | 2890 } |
2870 | 2891 |
2871 expression = this->CheckAndRewriteReferenceExpression( | 2892 expression = this->CheckAndRewriteReferenceExpression( |
2872 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2893 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, |
| 2894 CHECK_OK); |
2873 expression = this->MarkExpressionAsAssigned(expression); | 2895 expression = this->MarkExpressionAsAssigned(expression); |
2874 | 2896 |
2875 Token::Value op = Next(); // Get assignment operator. | 2897 Token::Value op = Next(); // Get assignment operator. |
2876 int pos = position(); | 2898 int pos = position(); |
2877 ExpressionT right = | 2899 ExpressionT right = |
2878 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2900 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2879 | 2901 |
2880 // TODO(1231235): We try to estimate the set of properties set by | 2902 // TODO(1231235): We try to estimate the set of properties set by |
2881 // constructors. We define a new property whenever there is an | 2903 // constructors. We define a new property whenever there is an |
2882 // assignment to a property of 'this'. We should probably only add | 2904 // assignment to a property of 'this'. We should probably only add |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 // code and AST node eventually.) | 3032 // code and AST node eventually.) |
3011 if (Token::IsCompareOp(op)) { | 3033 if (Token::IsCompareOp(op)) { |
3012 // We have a comparison. | 3034 // We have a comparison. |
3013 Token::Value cmp = op; | 3035 Token::Value cmp = op; |
3014 switch (op) { | 3036 switch (op) { |
3015 case Token::NE: cmp = Token::EQ; break; | 3037 case Token::NE: cmp = Token::EQ; break; |
3016 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 3038 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
3017 default: break; | 3039 default: break; |
3018 } | 3040 } |
3019 if (cmp == Token::EQ && is_strong(language_mode())) { | 3041 if (cmp == Token::EQ && is_strong(language_mode())) { |
3020 ReportMessageAt(op_location, "strong_equal"); | 3042 ReportMessageAt(op_location, MessageTemplate::kStrongEqual); |
3021 *ok = false; | 3043 *ok = false; |
3022 return this->EmptyExpression(); | 3044 return this->EmptyExpression(); |
3023 } | 3045 } |
3024 x = factory()->NewCompareOperation(cmp, x, y, pos); | 3046 x = factory()->NewCompareOperation(cmp, x, y, pos); |
3025 if (cmp != op) { | 3047 if (cmp != op) { |
3026 // The comparison was negated - add a NOT. | 3048 // The comparison was negated - add a NOT. |
3027 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | 3049 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
3028 } | 3050 } |
3029 | 3051 |
3030 } else { | 3052 } else { |
(...skipping 25 matching lines...) Expand all Loading... |
3056 Token::Value op = peek(); | 3078 Token::Value op = peek(); |
3057 if (Token::IsUnaryOp(op)) { | 3079 if (Token::IsUnaryOp(op)) { |
3058 BindingPatternUnexpectedToken(classifier); | 3080 BindingPatternUnexpectedToken(classifier); |
3059 | 3081 |
3060 op = Next(); | 3082 op = Next(); |
3061 int pos = position(); | 3083 int pos = position(); |
3062 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 3084 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
3063 | 3085 |
3064 if (op == Token::DELETE && is_strict(language_mode())) { | 3086 if (op == Token::DELETE && is_strict(language_mode())) { |
3065 if (is_strong(language_mode())) { | 3087 if (is_strong(language_mode())) { |
3066 ReportMessage("strong_delete"); | 3088 ReportMessage(MessageTemplate::kStrongDelete); |
3067 *ok = false; | 3089 *ok = false; |
3068 return this->EmptyExpression(); | 3090 return this->EmptyExpression(); |
3069 } else if (this->IsIdentifier(expression)) { | 3091 } else if (this->IsIdentifier(expression)) { |
3070 // "delete identifier" is a syntax error in strict mode. | 3092 // "delete identifier" is a syntax error in strict mode. |
3071 ReportMessage("strict_delete"); | 3093 ReportMessage(MessageTemplate::kStrictDelete); |
3072 *ok = false; | 3094 *ok = false; |
3073 return this->EmptyExpression(); | 3095 return this->EmptyExpression(); |
3074 } | 3096 } |
3075 } | 3097 } |
3076 | 3098 |
3077 // Allow Traits do rewrite the expression. | 3099 // Allow Traits do rewrite the expression. |
3078 return this->BuildUnaryExpression(expression, op, pos, factory()); | 3100 return this->BuildUnaryExpression(expression, op, pos, factory()); |
3079 } else if (Token::IsCountOp(op)) { | 3101 } else if (Token::IsCountOp(op)) { |
3080 BindingPatternUnexpectedToken(classifier); | 3102 BindingPatternUnexpectedToken(classifier); |
3081 op = Next(); | 3103 op = Next(); |
3082 Scanner::Location lhs_location = scanner()->peek_location(); | 3104 Scanner::Location lhs_location = scanner()->peek_location(); |
3083 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 3105 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
3084 expression = this->CheckAndRewriteReferenceExpression( | 3106 expression = this->CheckAndRewriteReferenceExpression( |
3085 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 3107 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, |
| 3108 CHECK_OK); |
3086 this->MarkExpressionAsAssigned(expression); | 3109 this->MarkExpressionAsAssigned(expression); |
3087 | 3110 |
3088 return factory()->NewCountOperation(op, | 3111 return factory()->NewCountOperation(op, |
3089 true /* prefix */, | 3112 true /* prefix */, |
3090 expression, | 3113 expression, |
3091 position()); | 3114 position()); |
3092 | 3115 |
3093 } else { | 3116 } else { |
3094 return this->ParsePostfixExpression(classifier, ok); | 3117 return this->ParsePostfixExpression(classifier, ok); |
3095 } | 3118 } |
3096 } | 3119 } |
3097 | 3120 |
3098 | 3121 |
3099 template <class Traits> | 3122 template <class Traits> |
3100 typename ParserBase<Traits>::ExpressionT | 3123 typename ParserBase<Traits>::ExpressionT |
3101 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 3124 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
3102 bool* ok) { | 3125 bool* ok) { |
3103 // PostfixExpression :: | 3126 // PostfixExpression :: |
3104 // LeftHandSideExpression ('++' | '--')? | 3127 // LeftHandSideExpression ('++' | '--')? |
3105 | 3128 |
3106 Scanner::Location lhs_location = scanner()->peek_location(); | 3129 Scanner::Location lhs_location = scanner()->peek_location(); |
3107 ExpressionT expression = | 3130 ExpressionT expression = |
3108 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3131 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
3109 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3132 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
3110 Token::IsCountOp(peek())) { | 3133 Token::IsCountOp(peek())) { |
3111 BindingPatternUnexpectedToken(classifier); | 3134 BindingPatternUnexpectedToken(classifier); |
3112 | 3135 |
3113 expression = this->CheckAndRewriteReferenceExpression( | 3136 expression = this->CheckAndRewriteReferenceExpression( |
3114 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 3137 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, |
| 3138 CHECK_OK); |
3115 expression = this->MarkExpressionAsAssigned(expression); | 3139 expression = this->MarkExpressionAsAssigned(expression); |
3116 | 3140 |
3117 Token::Value next = Next(); | 3141 Token::Value next = Next(); |
3118 expression = | 3142 expression = |
3119 factory()->NewCountOperation(next, | 3143 factory()->NewCountOperation(next, |
3120 false /* postfix */, | 3144 false /* postfix */, |
3121 expression, | 3145 expression, |
3122 position()); | 3146 position()); |
3123 } | 3147 } |
3124 return expression; | 3148 return expression; |
(...skipping 20 matching lines...) Expand all Loading... |
3145 result = factory()->NewProperty(result, index, pos); | 3169 result = factory()->NewProperty(result, index, pos); |
3146 Expect(Token::RBRACK, CHECK_OK); | 3170 Expect(Token::RBRACK, CHECK_OK); |
3147 break; | 3171 break; |
3148 } | 3172 } |
3149 | 3173 |
3150 case Token::LPAREN: { | 3174 case Token::LPAREN: { |
3151 BindingPatternUnexpectedToken(classifier); | 3175 BindingPatternUnexpectedToken(classifier); |
3152 | 3176 |
3153 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3177 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
3154 this->IsEval(this->AsIdentifier(result))) { | 3178 this->IsEval(this->AsIdentifier(result))) { |
3155 ReportMessage("strong_direct_eval"); | 3179 ReportMessage(MessageTemplate::kStrongDirectEval); |
3156 *ok = false; | 3180 *ok = false; |
3157 return this->EmptyExpression(); | 3181 return this->EmptyExpression(); |
3158 } | 3182 } |
3159 int pos; | 3183 int pos; |
3160 if (scanner()->current_token() == Token::IDENTIFIER) { | 3184 if (scanner()->current_token() == Token::IDENTIFIER) { |
3161 // For call of an identifier we want to report position of | 3185 // For call of an identifier we want to report position of |
3162 // the identifier as position of the call in the stack trace. | 3186 // the identifier as position of the call in the stack trace. |
3163 pos = position(); | 3187 pos = position(); |
3164 } else { | 3188 } else { |
3165 // For other kinds of calls we record position of the parenthesis as | 3189 // For other kinds of calls we record position of the parenthesis as |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3357 int pos = position(); | 3381 int pos = position(); |
3358 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3382 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3359 left = factory()->NewProperty( | 3383 left = factory()->NewProperty( |
3360 this_expr, factory()->NewStringLiteral(name, pos), pos); | 3384 this_expr, factory()->NewStringLiteral(name, pos), pos); |
3361 if (fni_ != NULL) { | 3385 if (fni_ != NULL) { |
3362 this->PushLiteralName(fni_, name); | 3386 this->PushLiteralName(fni_, name); |
3363 } | 3387 } |
3364 break; | 3388 break; |
3365 } | 3389 } |
3366 default: | 3390 default: |
3367 ReportMessage("strong_constructor_this"); | 3391 ReportMessage(MessageTemplate::kStrongConstructorThis); |
3368 *ok = false; | 3392 *ok = false; |
3369 return this->EmptyExpression(); | 3393 return this->EmptyExpression(); |
3370 } | 3394 } |
3371 | 3395 |
3372 if (peek() != Token::ASSIGN) { | 3396 if (peek() != Token::ASSIGN) { |
3373 ReportMessageAt(function_state_->this_location(), | 3397 ReportMessageAt(function_state_->this_location(), |
3374 "strong_constructor_this"); | 3398 MessageTemplate::kStrongConstructorThis); |
3375 *ok = false; | 3399 *ok = false; |
3376 return this->EmptyExpression(); | 3400 return this->EmptyExpression(); |
3377 } | 3401 } |
3378 Consume(Token::ASSIGN); | 3402 Consume(Token::ASSIGN); |
3379 left = this->MarkExpressionAsAssigned(left); | 3403 left = this->MarkExpressionAsAssigned(left); |
3380 | 3404 |
3381 ExpressionT right = | 3405 ExpressionT right = |
3382 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 3406 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
3383 this->CheckAssigningFunctionLiteralToProperty(left, right); | 3407 this->CheckAssigningFunctionLiteralToProperty(left, right); |
3384 function_state_->AddProperty(); | 3408 function_state_->AddProperty(); |
3385 if (fni_ != NULL) { | 3409 if (fni_ != NULL) { |
3386 // Check if the right hand side is a call to avoid inferring a | 3410 // Check if the right hand side is a call to avoid inferring a |
3387 // name if we're dealing with "this.a = function(){...}();"-like | 3411 // name if we're dealing with "this.a = function(){...}();"-like |
3388 // expression. | 3412 // expression. |
3389 if (!right->IsCall() && !right->IsCallNew()) { | 3413 if (!right->IsCall() && !right->IsCallNew()) { |
3390 fni_->Infer(); | 3414 fni_->Infer(); |
3391 } else { | 3415 } else { |
3392 fni_->RemoveLastFunction(); | 3416 fni_->RemoveLastFunction(); |
3393 } | 3417 } |
3394 fni_->Leave(); | 3418 fni_->Leave(); |
3395 } | 3419 } |
3396 | 3420 |
3397 if (function_state_->return_location().IsValid()) { | 3421 if (function_state_->return_location().IsValid()) { |
3398 ReportMessageAt(function_state_->return_location(), | 3422 ReportMessageAt(function_state_->return_location(), |
3399 "strong_constructor_return_misplaced"); | 3423 MessageTemplate::kStrongConstructorReturnMisplaced); |
3400 *ok = false; | 3424 *ok = false; |
3401 return this->EmptyExpression(); | 3425 return this->EmptyExpression(); |
3402 } | 3426 } |
3403 | 3427 |
3404 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | 3428 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); |
3405 } | 3429 } |
3406 | 3430 |
3407 | 3431 |
3408 template <class Traits> | 3432 template <class Traits> |
3409 typename ParserBase<Traits>::ExpressionT | 3433 typename ParserBase<Traits>::ExpressionT |
3410 ParserBase<Traits>::ParseStrongSuperCallExpression( | 3434 ParserBase<Traits>::ParseStrongSuperCallExpression( |
3411 ExpressionClassifier* classifier, bool* ok) { | 3435 ExpressionClassifier* classifier, bool* ok) { |
3412 // SuperCallExpression :: (strong mode) | 3436 // SuperCallExpression :: (strong mode) |
3413 // 'super' '(' ExpressionList ')' | 3437 // 'super' '(' ExpressionList ')' |
3414 BindingPatternUnexpectedToken(classifier); | 3438 BindingPatternUnexpectedToken(classifier); |
3415 | 3439 |
3416 Consume(Token::SUPER); | 3440 Consume(Token::SUPER); |
3417 int pos = position(); | 3441 int pos = position(); |
3418 Scanner::Location super_loc = scanner()->location(); | 3442 Scanner::Location super_loc = scanner()->location(); |
3419 ExpressionT expr = this->SuperReference(scope_, factory()); | 3443 ExpressionT expr = this->SuperReference(scope_, factory()); |
3420 | 3444 |
3421 if (peek() != Token::LPAREN) { | 3445 if (peek() != Token::LPAREN) { |
3422 ReportMessage("strong_constructor_super"); | 3446 ReportMessage(MessageTemplate::kStrongConstructorSuper); |
3423 *ok = false; | 3447 *ok = false; |
3424 return this->EmptyExpression(); | 3448 return this->EmptyExpression(); |
3425 } | 3449 } |
3426 | 3450 |
3427 Scanner::Location spread_pos; | 3451 Scanner::Location spread_pos; |
3428 typename Traits::Type::ExpressionList args = | 3452 typename Traits::Type::ExpressionList args = |
3429 ParseArguments(&spread_pos, classifier, CHECK_OK); | 3453 ParseArguments(&spread_pos, classifier, CHECK_OK); |
3430 | 3454 |
3431 // TODO(rossberg): This doesn't work with arrow functions yet. | 3455 // TODO(rossberg): This doesn't work with arrow functions yet. |
3432 if (!IsSubclassConstructor(function_state_->kind())) { | 3456 if (!IsSubclassConstructor(function_state_->kind())) { |
3433 ReportMessage("unexpected_super"); | 3457 ReportMessage(MessageTemplate::kUnexpectedSuper); |
3434 *ok = false; | 3458 *ok = false; |
3435 return this->EmptyExpression(); | 3459 return this->EmptyExpression(); |
3436 } else if (function_state_->super_location().IsValid()) { | 3460 } else if (function_state_->super_location().IsValid()) { |
3437 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | 3461 ReportMessageAt(scanner()->location(), |
| 3462 MessageTemplate::kStrongSuperCallDuplicate); |
3438 *ok = false; | 3463 *ok = false; |
3439 return this->EmptyExpression(); | 3464 return this->EmptyExpression(); |
3440 } else if (function_state_->this_location().IsValid()) { | 3465 } else if (function_state_->this_location().IsValid()) { |
3441 ReportMessageAt(scanner()->location(), "strong_super_call_misplaced"); | 3466 ReportMessageAt(scanner()->location(), |
| 3467 MessageTemplate::kStrongSuperCallMisplaced); |
3442 *ok = false; | 3468 *ok = false; |
3443 return this->EmptyExpression(); | 3469 return this->EmptyExpression(); |
3444 } else if (function_state_->return_location().IsValid()) { | 3470 } else if (function_state_->return_location().IsValid()) { |
3445 ReportMessageAt(function_state_->return_location(), | 3471 ReportMessageAt(function_state_->return_location(), |
3446 "strong_constructor_return_misplaced"); | 3472 MessageTemplate::kStrongConstructorReturnMisplaced); |
3447 *ok = false; | 3473 *ok = false; |
3448 return this->EmptyExpression(); | 3474 return this->EmptyExpression(); |
3449 } | 3475 } |
3450 | 3476 |
3451 function_state_->set_super_location(super_loc); | 3477 function_state_->set_super_location(super_loc); |
3452 if (spread_pos.IsValid()) { | 3478 if (spread_pos.IsValid()) { |
3453 args = Traits::PrepareSpreadArguments(args); | 3479 args = Traits::PrepareSpreadArguments(args); |
3454 return Traits::SpreadCall(expr, args, pos); | 3480 return Traits::SpreadCall(expr, args, pos); |
3455 } else { | 3481 } else { |
3456 return factory()->NewCall(expr, args, pos); | 3482 return factory()->NewCall(expr, args, pos); |
(...skipping 20 matching lines...) Expand all Loading... |
3477 i::IsConstructor(kind)) { | 3503 i::IsConstructor(kind)) { |
3478 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3504 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
3479 scope_->RecordSuperPropertyUsage(); | 3505 scope_->RecordSuperPropertyUsage(); |
3480 return this->SuperReference(scope_, factory()); | 3506 return this->SuperReference(scope_, factory()); |
3481 } | 3507 } |
3482 // new super() is never allowed. | 3508 // new super() is never allowed. |
3483 // super() is only allowed in derived constructor | 3509 // super() is only allowed in derived constructor |
3484 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3510 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
3485 if (is_strong(language_mode())) { | 3511 if (is_strong(language_mode())) { |
3486 // Super calls in strong mode are parsed separately. | 3512 // Super calls in strong mode are parsed separately. |
3487 ReportMessageAt(scanner()->location(), "strong_constructor_super"); | 3513 ReportMessageAt(scanner()->location(), |
| 3514 MessageTemplate::kStrongConstructorSuper); |
3488 *ok = false; | 3515 *ok = false; |
3489 return this->EmptyExpression(); | 3516 return this->EmptyExpression(); |
3490 } | 3517 } |
3491 function_state->set_super_location(scanner()->location()); | 3518 function_state->set_super_location(scanner()->location()); |
3492 return this->SuperReference(scope_, factory()); | 3519 return this->SuperReference(scope_, factory()); |
3493 } | 3520 } |
3494 } | 3521 } |
3495 | 3522 |
3496 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3523 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); |
3497 *ok = false; | 3524 *ok = false; |
3498 return this->EmptyExpression(); | 3525 return this->EmptyExpression(); |
3499 } | 3526 } |
3500 | 3527 |
3501 | 3528 |
3502 template <class Traits> | 3529 template <class Traits> |
3503 typename ParserBase<Traits>::ExpressionT | 3530 typename ParserBase<Traits>::ExpressionT |
3504 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3531 ParserBase<Traits>::ParseMemberExpressionContinuation( |
3505 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3532 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
3506 // Parses this part of MemberExpression: | 3533 // Parses this part of MemberExpression: |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3593 // FormalsList[Yield,GeneratorParameter] : | 3620 // FormalsList[Yield,GeneratorParameter] : |
3594 // FormalParameter[?Yield, ?GeneratorParameter] | 3621 // FormalParameter[?Yield, ?GeneratorParameter] |
3595 // FormalsList[?Yield, ?GeneratorParameter] , | 3622 // FormalsList[?Yield, ?GeneratorParameter] , |
3596 // FormalParameter[?Yield,?GeneratorParameter] | 3623 // FormalParameter[?Yield,?GeneratorParameter] |
3597 | 3624 |
3598 int parameter_count = 0; | 3625 int parameter_count = 0; |
3599 | 3626 |
3600 if (peek() != Token::RPAREN) { | 3627 if (peek() != Token::RPAREN) { |
3601 do { | 3628 do { |
3602 if (++parameter_count > Code::kMaxArguments) { | 3629 if (++parameter_count > Code::kMaxArguments) { |
3603 ReportMessage("too_many_parameters"); | 3630 ReportMessage(MessageTemplate::kTooManyParameters); |
3604 *ok = false; | 3631 *ok = false; |
3605 return -1; | 3632 return -1; |
3606 } | 3633 } |
3607 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); | 3634 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); |
3608 ParseFormalParameter(scope, *is_rest, classifier, ok); | 3635 ParseFormalParameter(scope, *is_rest, classifier, ok); |
3609 if (!*ok) return -1; | 3636 if (!*ok) return -1; |
3610 } while (!*is_rest && Check(Token::COMMA)); | 3637 } while (!*is_rest && Check(Token::COMMA)); |
3611 | 3638 |
3612 if (*is_rest && peek() == Token::COMMA) { | 3639 if (*is_rest && peek() == Token::COMMA) { |
3613 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); | 3640 ReportMessageAt(scanner()->peek_location(), |
| 3641 MessageTemplate::kParamAfterRest); |
3614 *ok = false; | 3642 *ok = false; |
3615 return -1; | 3643 return -1; |
3616 } | 3644 } |
3617 } | 3645 } |
3618 | 3646 |
3619 return parameter_count; | 3647 return parameter_count; |
3620 } | 3648 } |
3621 | 3649 |
3622 | 3650 |
3623 template <class Traits> | 3651 template <class Traits> |
3624 void ParserBase<Traits>::CheckArityRestrictions( | 3652 void ParserBase<Traits>::CheckArityRestrictions( |
3625 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 3653 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
3626 int formals_start_pos, int formals_end_pos, bool* ok) { | 3654 int formals_start_pos, int formals_end_pos, bool* ok) { |
3627 switch (arity_restriction) { | 3655 switch (arity_restriction) { |
3628 case FunctionLiteral::GETTER_ARITY: | 3656 case FunctionLiteral::GETTER_ARITY: |
3629 if (param_count != 0) { | 3657 if (param_count != 0) { |
3630 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3658 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3631 "bad_getter_arity"); | 3659 MessageTemplate::kBadGetterArity); |
3632 *ok = false; | 3660 *ok = false; |
3633 } | 3661 } |
3634 break; | 3662 break; |
3635 case FunctionLiteral::SETTER_ARITY: | 3663 case FunctionLiteral::SETTER_ARITY: |
3636 if (param_count != 1) { | 3664 if (param_count != 1) { |
3637 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3665 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3638 "bad_setter_arity"); | 3666 MessageTemplate::kBadSetterArity); |
3639 *ok = false; | 3667 *ok = false; |
3640 } | 3668 } |
3641 break; | 3669 break; |
3642 default: | 3670 default: |
3643 break; | 3671 break; |
3644 } | 3672 } |
3645 } | 3673 } |
3646 | 3674 |
3647 | 3675 |
3648 template <class Traits> | 3676 template <class Traits> |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3779 | 3807 |
3780 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, | 3808 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, |
3781 // and repeat if the following token is a TEMPLATE_SPAN as well (in this | 3809 // and repeat if the following token is a TEMPLATE_SPAN as well (in this |
3782 // case, representing a TemplateMiddle). | 3810 // case, representing a TemplateMiddle). |
3783 | 3811 |
3784 do { | 3812 do { |
3785 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3813 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3786 next = peek(); | 3814 next = peek(); |
3787 if (next == Token::EOS) { | 3815 if (next == Token::EOS) { |
3788 ReportMessageAt(Scanner::Location(start, peek_position()), | 3816 ReportMessageAt(Scanner::Location(start, peek_position()), |
3789 "unterminated_template"); | 3817 MessageTemplate::kUnterminatedTemplate); |
3790 *ok = false; | 3818 *ok = false; |
3791 return Traits::EmptyExpression(); | 3819 return Traits::EmptyExpression(); |
3792 } else if (next == Token::ILLEGAL) { | 3820 } else if (next == Token::ILLEGAL) { |
3793 Traits::ReportMessageAt( | 3821 Traits::ReportMessageAt( |
3794 Scanner::Location(position() + 1, peek_position()), | 3822 Scanner::Location(position() + 1, peek_position()), |
3795 "unexpected_token", "ILLEGAL", kSyntaxError); | 3823 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3796 *ok = false; | 3824 *ok = false; |
3797 return Traits::EmptyExpression(); | 3825 return Traits::EmptyExpression(); |
3798 } | 3826 } |
3799 | 3827 |
3800 int expr_pos = peek_position(); | 3828 int expr_pos = peek_position(); |
3801 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3829 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
3802 Traits::AddTemplateExpression(&ts, expression); | 3830 Traits::AddTemplateExpression(&ts, expression); |
3803 | 3831 |
3804 if (peek() != Token::RBRACE) { | 3832 if (peek() != Token::RBRACE) { |
3805 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3833 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3806 "unterminated_template_expr"); | 3834 MessageTemplate::kUnterminatedTemplateExpr); |
3807 *ok = false; | 3835 *ok = false; |
3808 return Traits::EmptyExpression(); | 3836 return Traits::EmptyExpression(); |
3809 } | 3837 } |
3810 | 3838 |
3811 // If we didn't die parsing that expression, our next token should be a | 3839 // If we didn't die parsing that expression, our next token should be a |
3812 // TEMPLATE_SPAN or TEMPLATE_TAIL. | 3840 // TEMPLATE_SPAN or TEMPLATE_TAIL. |
3813 next = scanner()->ScanTemplateContinuation(); | 3841 next = scanner()->ScanTemplateContinuation(); |
3814 Next(); | 3842 Next(); |
3815 pos = position(); | 3843 pos = position(); |
3816 | 3844 |
3817 if (next == Token::EOS) { | 3845 if (next == Token::EOS) { |
3818 ReportMessageAt(Scanner::Location(start, pos), "unterminated_template"); | 3846 ReportMessageAt(Scanner::Location(start, pos), |
| 3847 MessageTemplate::kUnterminatedTemplate); |
3819 *ok = false; | 3848 *ok = false; |
3820 return Traits::EmptyExpression(); | 3849 return Traits::EmptyExpression(); |
3821 } else if (next == Token::ILLEGAL) { | 3850 } else if (next == Token::ILLEGAL) { |
3822 Traits::ReportMessageAt( | 3851 Traits::ReportMessageAt( |
3823 Scanner::Location(position() + 1, peek_position()), | 3852 Scanner::Location(position() + 1, peek_position()), |
3824 "unexpected_token", "ILLEGAL", kSyntaxError); | 3853 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3825 *ok = false; | 3854 *ok = false; |
3826 return Traits::EmptyExpression(); | 3855 return Traits::EmptyExpression(); |
3827 } | 3856 } |
3828 | 3857 |
3829 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3858 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
3830 } while (next == Token::TEMPLATE_SPAN); | 3859 } while (next == Token::TEMPLATE_SPAN); |
3831 | 3860 |
3832 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3861 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
3833 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3862 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3834 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3863 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
3835 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3864 return Traits::CloseTemplateLiteral(&ts, start, tag); |
3836 } | 3865 } |
3837 | 3866 |
3838 | 3867 |
3839 template <typename Traits> | 3868 template <typename Traits> |
3840 typename ParserBase<Traits>::ExpressionT ParserBase< | 3869 typename ParserBase<Traits>::ExpressionT |
3841 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, | 3870 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
3842 Scanner::Location location, | 3871 ExpressionT expression, Scanner::Location location, |
3843 const char* message, bool* ok) { | 3872 MessageTemplate::Template message, bool* ok) { |
3844 if (this->IsIdentifier(expression)) { | 3873 if (this->IsIdentifier(expression)) { |
3845 if (is_strict(language_mode()) && | 3874 if (is_strict(language_mode()) && |
3846 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3875 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3847 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); | 3876 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, |
| 3877 kSyntaxError); |
3848 *ok = false; | 3878 *ok = false; |
3849 return this->EmptyExpression(); | 3879 return this->EmptyExpression(); |
3850 } | 3880 } |
3851 if (is_strong(language_mode()) && | 3881 if (is_strong(language_mode()) && |
3852 this->IsUndefined(this->AsIdentifier(expression))) { | 3882 this->IsUndefined(this->AsIdentifier(expression))) { |
3853 this->ReportMessageAt(location, "strong_undefined", kSyntaxError); | 3883 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, |
| 3884 kSyntaxError); |
3854 *ok = false; | 3885 *ok = false; |
3855 return this->EmptyExpression(); | 3886 return this->EmptyExpression(); |
3856 } | 3887 } |
3857 } | 3888 } |
3858 if (expression->IsValidReferenceExpression()) { | 3889 if (expression->IsValidReferenceExpression()) { |
3859 return expression; | 3890 return expression; |
3860 } else if (expression->IsCall()) { | 3891 } else if (expression->IsCall()) { |
3861 // If it is a call, make it a runtime error for legacy web compatibility. | 3892 // If it is a call, make it a runtime error for legacy web compatibility. |
3862 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3893 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3863 int pos = location.beg_pos; | 3894 int pos = location.beg_pos; |
(...skipping 15 matching lines...) Expand all Loading... |
3879 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3910 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
3880 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3911 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
3881 bool* ok) { | 3912 bool* ok) { |
3882 DCHECK(!is_static); | 3913 DCHECK(!is_static); |
3883 DCHECK(!is_generator || type == kMethodProperty); | 3914 DCHECK(!is_generator || type == kMethodProperty); |
3884 | 3915 |
3885 if (property == Token::SMI || property == Token::NUMBER) return; | 3916 if (property == Token::SMI || property == Token::NUMBER) return; |
3886 | 3917 |
3887 if (type == kValueProperty && IsProto()) { | 3918 if (type == kValueProperty && IsProto()) { |
3888 if (has_seen_proto_) { | 3919 if (has_seen_proto_) { |
3889 this->parser()->ReportMessage("duplicate_proto"); | 3920 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); |
3890 *ok = false; | 3921 *ok = false; |
3891 return; | 3922 return; |
3892 } | 3923 } |
3893 has_seen_proto_ = true; | 3924 has_seen_proto_ = true; |
3894 return; | 3925 return; |
3895 } | 3926 } |
3896 } | 3927 } |
3897 | 3928 |
3898 | 3929 |
3899 template <typename Traits> | 3930 template <typename Traits> |
3900 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( | 3931 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( |
3901 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3932 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
3902 bool* ok) { | 3933 bool* ok) { |
3903 DCHECK(type == kMethodProperty || type == kAccessorProperty); | 3934 DCHECK(type == kMethodProperty || type == kAccessorProperty); |
3904 | 3935 |
3905 if (property == Token::SMI || property == Token::NUMBER) return; | 3936 if (property == Token::SMI || property == Token::NUMBER) return; |
3906 | 3937 |
3907 if (is_static) { | 3938 if (is_static) { |
3908 if (IsPrototype()) { | 3939 if (IsPrototype()) { |
3909 this->parser()->ReportMessage("static_prototype"); | 3940 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
3910 *ok = false; | 3941 *ok = false; |
3911 return; | 3942 return; |
3912 } | 3943 } |
3913 } else if (IsConstructor()) { | 3944 } else if (IsConstructor()) { |
3914 if (is_generator || type == kAccessorProperty) { | 3945 if (is_generator || type == kAccessorProperty) { |
3915 const char* msg = | 3946 MessageTemplate::Template msg = |
3916 is_generator ? "constructor_is_generator" : "constructor_is_accessor"; | 3947 is_generator ? MessageTemplate::kConstructorIsGenerator |
| 3948 : MessageTemplate::kConstructorIsAccessor; |
3917 this->parser()->ReportMessage(msg); | 3949 this->parser()->ReportMessage(msg); |
3918 *ok = false; | 3950 *ok = false; |
3919 return; | 3951 return; |
3920 } | 3952 } |
3921 if (has_seen_constructor_) { | 3953 if (has_seen_constructor_) { |
3922 this->parser()->ReportMessage("duplicate_constructor"); | 3954 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); |
3923 *ok = false; | 3955 *ok = false; |
3924 return; | 3956 return; |
3925 } | 3957 } |
3926 has_seen_constructor_ = true; | 3958 has_seen_constructor_ = true; |
3927 return; | 3959 return; |
3928 } | 3960 } |
3929 } | 3961 } |
3930 } } // v8::internal | 3962 } } // v8::internal |
3931 | 3963 |
3932 #endif // V8_PREPARSER_H | 3964 #endif // V8_PREPARSER_H |
OLD | NEW |