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" |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 public: | 549 public: |
550 struct Error { | 550 struct Error { |
551 Error() | 551 Error() |
552 : location(Scanner::Location::invalid()), | 552 : location(Scanner::Location::invalid()), |
553 message(MessageTemplate::kNone), | 553 message(MessageTemplate::kNone), |
554 arg(nullptr) {} | 554 arg(nullptr) {} |
555 | 555 |
556 Scanner::Location location; | 556 Scanner::Location location; |
557 MessageTemplate::Template message; | 557 MessageTemplate::Template message; |
558 const char* arg; | 558 const char* arg; |
559 | |
560 bool HasError() const { return location.IsValid(); } | |
561 }; | 559 }; |
562 | 560 |
563 ExpressionClassifier() {} | 561 enum TargetProduction { |
| 562 ExpressionProduction = 1 << 0, |
| 563 BindingPatternProduction = 1 << 1, |
| 564 AssignmentPatternProduction = 1 << 2, |
| 565 DistinctFormalParametersProduction = 1 << 3, |
| 566 StrictModeFormalParametersProduction = 1 << 4, |
| 567 StrongModeFormalParametersProduction = 1 << 5, |
| 568 ArrowFormalParametersProduction = 1 << 6, |
564 | 569 |
565 bool is_valid_expression() const { return !expression_error_.HasError(); } | 570 PatternProductions = |
| 571 (BindingPatternProduction | AssignmentPatternProduction), |
| 572 FormalParametersProductions = (DistinctFormalParametersProduction | |
| 573 StrictModeFormalParametersProduction | |
| 574 StrongModeFormalParametersProduction), |
| 575 StandardProductions = ExpressionProduction | PatternProductions, |
| 576 AllProductions = (StandardProductions | FormalParametersProductions | |
| 577 ArrowFormalParametersProduction) |
| 578 }; |
| 579 |
| 580 ExpressionClassifier() : invalid_productions_(0) {} |
| 581 |
| 582 bool is_valid(unsigned productions) const { |
| 583 return (invalid_productions_ & productions) == 0; |
| 584 } |
| 585 |
| 586 bool is_valid_expression() const { return is_valid(ExpressionProduction); } |
566 | 587 |
567 bool is_valid_binding_pattern() const { | 588 bool is_valid_binding_pattern() const { |
568 return !binding_pattern_error_.HasError(); | 589 return is_valid(BindingPatternProduction); |
569 } | 590 } |
570 | 591 |
571 bool is_valid_assignment_pattern() const { | 592 bool is_valid_assignment_pattern() const { |
572 return !assignment_pattern_error_.HasError(); | 593 return is_valid(AssignmentPatternProduction); |
573 } | 594 } |
574 | 595 |
575 bool is_valid_arrow_formal_parameters() const { | 596 bool is_valid_arrow_formal_parameters() const { |
576 return !arrow_formal_parameters_error_.HasError(); | 597 return is_valid(ArrowFormalParametersProduction); |
577 } | 598 } |
578 | 599 |
579 bool is_valid_formal_parameter_list_without_duplicates() const { | 600 bool is_valid_formal_parameter_list_without_duplicates() const { |
580 return !duplicate_formal_parameter_error_.HasError(); | 601 return is_valid(DistinctFormalParametersProduction); |
581 } | 602 } |
582 | 603 |
583 // Note: callers should also check | 604 // Note: callers should also check |
584 // is_valid_formal_parameter_list_without_duplicates(). | 605 // is_valid_formal_parameter_list_without_duplicates(). |
585 bool is_valid_strict_mode_formal_parameters() const { | 606 bool is_valid_strict_mode_formal_parameters() const { |
586 return !strict_mode_formal_parameter_error_.HasError(); | 607 return is_valid(StrictModeFormalParametersProduction); |
587 } | 608 } |
588 | 609 |
589 // Note: callers should also check is_valid_strict_mode_formal_parameters() | 610 // Note: callers should also check is_valid_strict_mode_formal_parameters() |
590 // and is_valid_formal_parameter_list_without_duplicates(). | 611 // and is_valid_formal_parameter_list_without_duplicates(). |
591 bool is_valid_strong_mode_formal_parameters() const { | 612 bool is_valid_strong_mode_formal_parameters() const { |
592 return !strong_mode_formal_parameter_error_.HasError(); | 613 return is_valid(StrongModeFormalParametersProduction); |
593 } | 614 } |
594 | 615 |
595 const Error& expression_error() const { return expression_error_; } | 616 const Error& expression_error() const { return expression_error_; } |
596 | 617 |
597 const Error& binding_pattern_error() const { | 618 const Error& binding_pattern_error() const { |
598 return binding_pattern_error_; | 619 return binding_pattern_error_; |
599 } | 620 } |
600 | 621 |
601 const Error& assignment_pattern_error() const { | 622 const Error& assignment_pattern_error() const { |
602 return assignment_pattern_error_; | 623 return assignment_pattern_error_; |
(...skipping 12 matching lines...) Expand all Loading... |
615 } | 636 } |
616 | 637 |
617 const Error& strong_mode_formal_parameter_error() const { | 638 const Error& strong_mode_formal_parameter_error() const { |
618 return strong_mode_formal_parameter_error_; | 639 return strong_mode_formal_parameter_error_; |
619 } | 640 } |
620 | 641 |
621 void RecordExpressionError(const Scanner::Location& loc, | 642 void RecordExpressionError(const Scanner::Location& loc, |
622 MessageTemplate::Template message, | 643 MessageTemplate::Template message, |
623 const char* arg = nullptr) { | 644 const char* arg = nullptr) { |
624 if (!is_valid_expression()) return; | 645 if (!is_valid_expression()) return; |
| 646 invalid_productions_ |= ExpressionProduction; |
625 expression_error_.location = loc; | 647 expression_error_.location = loc; |
626 expression_error_.message = message; | 648 expression_error_.message = message; |
627 expression_error_.arg = arg; | 649 expression_error_.arg = arg; |
628 } | 650 } |
629 | 651 |
630 void RecordBindingPatternError(const Scanner::Location& loc, | 652 void RecordBindingPatternError(const Scanner::Location& loc, |
631 MessageTemplate::Template message, | 653 MessageTemplate::Template message, |
632 const char* arg = nullptr) { | 654 const char* arg = nullptr) { |
633 if (!is_valid_binding_pattern()) return; | 655 if (!is_valid_binding_pattern()) return; |
| 656 invalid_productions_ |= BindingPatternProduction; |
634 binding_pattern_error_.location = loc; | 657 binding_pattern_error_.location = loc; |
635 binding_pattern_error_.message = message; | 658 binding_pattern_error_.message = message; |
636 binding_pattern_error_.arg = arg; | 659 binding_pattern_error_.arg = arg; |
637 } | 660 } |
638 | 661 |
639 void RecordAssignmentPatternError(const Scanner::Location& loc, | 662 void RecordAssignmentPatternError(const Scanner::Location& loc, |
640 MessageTemplate::Template message, | 663 MessageTemplate::Template message, |
641 const char* arg = nullptr) { | 664 const char* arg = nullptr) { |
642 if (!is_valid_assignment_pattern()) return; | 665 if (!is_valid_assignment_pattern()) return; |
| 666 invalid_productions_ |= AssignmentPatternProduction; |
643 assignment_pattern_error_.location = loc; | 667 assignment_pattern_error_.location = loc; |
644 assignment_pattern_error_.message = message; | 668 assignment_pattern_error_.message = message; |
645 assignment_pattern_error_.arg = arg; | 669 assignment_pattern_error_.arg = arg; |
646 } | 670 } |
647 | 671 |
648 void RecordArrowFormalParametersError(const Scanner::Location& loc, | 672 void RecordArrowFormalParametersError(const Scanner::Location& loc, |
649 MessageTemplate::Template message, | 673 MessageTemplate::Template message, |
650 const char* arg = nullptr) { | 674 const char* arg = nullptr) { |
651 if (!is_valid_arrow_formal_parameters()) return; | 675 if (!is_valid_arrow_formal_parameters()) return; |
| 676 invalid_productions_ |= ArrowFormalParametersProduction; |
652 arrow_formal_parameters_error_.location = loc; | 677 arrow_formal_parameters_error_.location = loc; |
653 arrow_formal_parameters_error_.message = message; | 678 arrow_formal_parameters_error_.message = message; |
654 arrow_formal_parameters_error_.arg = arg; | 679 arrow_formal_parameters_error_.arg = arg; |
655 } | 680 } |
656 | 681 |
657 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | 682 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
658 if (!is_valid_formal_parameter_list_without_duplicates()) return; | 683 if (!is_valid_formal_parameter_list_without_duplicates()) return; |
| 684 invalid_productions_ |= DistinctFormalParametersProduction; |
659 duplicate_formal_parameter_error_.location = loc; | 685 duplicate_formal_parameter_error_.location = loc; |
660 duplicate_formal_parameter_error_.message = | 686 duplicate_formal_parameter_error_.message = |
661 MessageTemplate::kStrictParamDupe; | 687 MessageTemplate::kStrictParamDupe; |
662 duplicate_formal_parameter_error_.arg = nullptr; | 688 duplicate_formal_parameter_error_.arg = nullptr; |
663 } | 689 } |
664 | 690 |
665 // Record a binding that would be invalid in strict mode. Confusingly this | 691 // Record a binding that would be invalid in strict mode. Confusingly this |
666 // is not the same as StrictFormalParameterList, which simply forbids | 692 // is not the same as StrictFormalParameterList, which simply forbids |
667 // duplicate bindings. | 693 // duplicate bindings. |
668 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, | 694 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
669 MessageTemplate::Template message, | 695 MessageTemplate::Template message, |
670 const char* arg = nullptr) { | 696 const char* arg = nullptr) { |
671 if (!is_valid_strict_mode_formal_parameters()) return; | 697 if (!is_valid_strict_mode_formal_parameters()) return; |
| 698 invalid_productions_ |= StrictModeFormalParametersProduction; |
672 strict_mode_formal_parameter_error_.location = loc; | 699 strict_mode_formal_parameter_error_.location = loc; |
673 strict_mode_formal_parameter_error_.message = message; | 700 strict_mode_formal_parameter_error_.message = message; |
674 strict_mode_formal_parameter_error_.arg = arg; | 701 strict_mode_formal_parameter_error_.arg = arg; |
675 } | 702 } |
676 | 703 |
677 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, | 704 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
678 MessageTemplate::Template message, | 705 MessageTemplate::Template message, |
679 const char* arg = nullptr) { | 706 const char* arg = nullptr) { |
680 if (!is_valid_strong_mode_formal_parameters()) return; | 707 if (!is_valid_strong_mode_formal_parameters()) return; |
| 708 invalid_productions_ |= StrongModeFormalParametersProduction; |
681 strong_mode_formal_parameter_error_.location = loc; | 709 strong_mode_formal_parameter_error_.location = loc; |
682 strong_mode_formal_parameter_error_.message = message; | 710 strong_mode_formal_parameter_error_.message = message; |
683 strong_mode_formal_parameter_error_.arg = arg; | 711 strong_mode_formal_parameter_error_.arg = arg; |
684 } | 712 } |
685 | 713 |
686 enum TargetProduction { | |
687 ExpressionProduction = 1 << 0, | |
688 BindingPatternProduction = 1 << 1, | |
689 AssignmentPatternProduction = 1 << 2, | |
690 FormalParametersProduction = 1 << 3, | |
691 ArrowFormalParametersProduction = 1 << 4, | |
692 StandardProductions = (ExpressionProduction | BindingPatternProduction | | |
693 AssignmentPatternProduction), | |
694 AllProductions = (StandardProductions | FormalParametersProduction | | |
695 ArrowFormalParametersProduction) | |
696 }; | |
697 | |
698 void Accumulate(const ExpressionClassifier& inner, | 714 void Accumulate(const ExpressionClassifier& inner, |
699 unsigned productions = StandardProductions) { | 715 unsigned productions = StandardProductions) { |
700 if (productions & ExpressionProduction && is_valid_expression()) { | 716 // Propagate errors from inner, but don't overwrite already recorded |
701 expression_error_ = inner.expression_error_; | 717 // errors. |
702 } | 718 unsigned non_arrow_inner_invalid_productions = |
703 if (productions & BindingPatternProduction && | 719 inner.invalid_productions_ & ~ArrowFormalParametersProduction; |
704 is_valid_binding_pattern()) { | 720 if (non_arrow_inner_invalid_productions == 0) return; |
705 binding_pattern_error_ = inner.binding_pattern_error_; | 721 unsigned non_arrow_productions = |
706 } | 722 productions & ~ArrowFormalParametersProduction; |
707 if (productions & AssignmentPatternProduction && | 723 unsigned errors = |
708 is_valid_assignment_pattern()) { | 724 non_arrow_productions & non_arrow_inner_invalid_productions; |
709 assignment_pattern_error_ = inner.assignment_pattern_error_; | 725 errors &= ~invalid_productions_; |
710 } | 726 if (errors != 0) { |
711 if (productions & FormalParametersProduction) { | 727 invalid_productions_ |= errors; |
712 if (is_valid_formal_parameter_list_without_duplicates()) { | 728 if (errors & ExpressionProduction) |
| 729 expression_error_ = inner.expression_error_; |
| 730 if (errors & BindingPatternProduction) |
| 731 binding_pattern_error_ = inner.binding_pattern_error_; |
| 732 if (errors & AssignmentPatternProduction) |
| 733 assignment_pattern_error_ = inner.assignment_pattern_error_; |
| 734 if (errors & DistinctFormalParametersProduction) |
713 duplicate_formal_parameter_error_ = | 735 duplicate_formal_parameter_error_ = |
714 inner.duplicate_formal_parameter_error_; | 736 inner.duplicate_formal_parameter_error_; |
715 } | 737 if (errors & StrictModeFormalParametersProduction) |
716 if (is_valid_strict_mode_formal_parameters()) { | |
717 strict_mode_formal_parameter_error_ = | 738 strict_mode_formal_parameter_error_ = |
718 inner.strict_mode_formal_parameter_error_; | 739 inner.strict_mode_formal_parameter_error_; |
719 } | 740 if (errors & StrongModeFormalParametersProduction) |
720 if (is_valid_strong_mode_formal_parameters()) { | |
721 strong_mode_formal_parameter_error_ = | 741 strong_mode_formal_parameter_error_ = |
722 inner.strong_mode_formal_parameter_error_; | 742 inner.strong_mode_formal_parameter_error_; |
723 } | |
724 } | 743 } |
| 744 |
| 745 // As an exception to the above, the result continues to be a valid arrow |
| 746 // formal parameters if the inner expression is a valid binding pattern. |
725 if (productions & ArrowFormalParametersProduction && | 747 if (productions & ArrowFormalParametersProduction && |
726 is_valid_arrow_formal_parameters()) { | 748 is_valid_arrow_formal_parameters() && |
727 // The result continues to be a valid arrow formal parameters if the | 749 !inner.is_valid_binding_pattern()) { |
728 // inner expression is a valid binding pattern. | 750 invalid_productions_ |= ArrowFormalParametersProduction; |
729 arrow_formal_parameters_error_ = inner.binding_pattern_error_; | 751 arrow_formal_parameters_error_ = inner.binding_pattern_error_; |
730 } | 752 } |
731 } | 753 } |
732 | 754 |
733 private: | 755 private: |
| 756 unsigned invalid_productions_; |
734 Error expression_error_; | 757 Error expression_error_; |
735 Error binding_pattern_error_; | 758 Error binding_pattern_error_; |
736 Error assignment_pattern_error_; | 759 Error assignment_pattern_error_; |
737 Error arrow_formal_parameters_error_; | 760 Error arrow_formal_parameters_error_; |
738 Error duplicate_formal_parameter_error_; | 761 Error duplicate_formal_parameter_error_; |
739 Error strict_mode_formal_parameter_error_; | 762 Error strict_mode_formal_parameter_error_; |
740 Error strong_mode_formal_parameter_error_; | 763 Error strong_mode_formal_parameter_error_; |
741 }; | 764 }; |
742 | 765 |
743 void ReportClassifierError( | 766 void ReportClassifierError( |
(...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2870 duplicate_loc); | 2893 duplicate_loc); |
2871 } | 2894 } |
2872 expression = this->ParseArrowFunctionLiteral( | 2895 expression = this->ParseArrowFunctionLiteral( |
2873 scope, has_rest, arrow_formals_classifier, CHECK_OK); | 2896 scope, has_rest, arrow_formals_classifier, CHECK_OK); |
2874 return expression; | 2897 return expression; |
2875 } | 2898 } |
2876 | 2899 |
2877 // "expression" was not itself an arrow function parameter list, but it might | 2900 // "expression" was not itself an arrow function parameter list, but it might |
2878 // form part of one. Propagate speculative formal parameter error locations. | 2901 // form part of one. Propagate speculative formal parameter error locations. |
2879 classifier->Accumulate(arrow_formals_classifier, | 2902 classifier->Accumulate(arrow_formals_classifier, |
2880 ExpressionClassifier::FormalParametersProduction); | 2903 ExpressionClassifier::FormalParametersProductions); |
2881 | 2904 |
2882 if (!Token::IsAssignmentOp(peek())) { | 2905 if (!Token::IsAssignmentOp(peek())) { |
2883 if (fni_ != NULL) fni_->Leave(); | 2906 if (fni_ != NULL) fni_->Leave(); |
2884 // Parsed conditional expression only (no assignment). | 2907 // Parsed conditional expression only (no assignment). |
2885 return expression; | 2908 return expression; |
2886 } | 2909 } |
2887 | 2910 |
2888 if (!allow_harmony_destructuring()) { | 2911 if (!allow_harmony_destructuring()) { |
2889 BindingPatternUnexpectedToken(classifier); | 2912 BindingPatternUnexpectedToken(classifier); |
2890 } | 2913 } |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3960 *ok = false; | 3983 *ok = false; |
3961 return; | 3984 return; |
3962 } | 3985 } |
3963 has_seen_constructor_ = true; | 3986 has_seen_constructor_ = true; |
3964 return; | 3987 return; |
3965 } | 3988 } |
3966 } | 3989 } |
3967 } } // v8::internal | 3990 } } // v8::internal |
3968 | 3991 |
3969 #endif // V8_PREPARSER_H | 3992 #endif // V8_PREPARSER_H |
OLD | NEW |