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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 public: | 550 public: |
551 struct Error { | 551 struct Error { |
552 Error() | 552 Error() |
553 : location(Scanner::Location::invalid()), | 553 : location(Scanner::Location::invalid()), |
554 message(MessageTemplate::kNone), | 554 message(MessageTemplate::kNone), |
555 arg(nullptr) {} | 555 arg(nullptr) {} |
556 | 556 |
557 Scanner::Location location; | 557 Scanner::Location location; |
558 MessageTemplate::Template message; | 558 MessageTemplate::Template message; |
559 const char* arg; | 559 const char* arg; |
560 | |
561 bool HasError() const { return location.IsValid(); } | |
562 }; | 560 }; |
563 | 561 |
564 ExpressionClassifier() {} | 562 enum TargetProduction { |
| 563 ExpressionProduction = 1 << 0, |
| 564 BindingPatternProduction = 1 << 1, |
| 565 AssignmentPatternProduction = 1 << 2, |
| 566 DistinctFormalParametersProduction = 1 << 3, |
| 567 StrictModeFormalParametersProduction = 1 << 4, |
| 568 StrongModeFormalParametersProduction = 1 << 5, |
| 569 ArrowFormalParametersProduction = 1 << 6, |
565 | 570 |
566 bool is_valid_expression() const { return !expression_error_.HasError(); } | 571 PatternProductions = |
| 572 (BindingPatternProduction | AssignmentPatternProduction), |
| 573 FormalParametersProductions = (DistinctFormalParametersProduction | |
| 574 StrictModeFormalParametersProduction | |
| 575 StrongModeFormalParametersProduction), |
| 576 StandardProductions = ExpressionProduction | PatternProductions, |
| 577 AllProductions = (StandardProductions | FormalParametersProductions | |
| 578 ArrowFormalParametersProduction) |
| 579 }; |
| 580 |
| 581 ExpressionClassifier() : invalid_productions_(0) {} |
| 582 |
| 583 bool is_valid(unsigned productions) const { |
| 584 return (invalid_productions_ & productions) == 0; |
| 585 } |
| 586 |
| 587 bool is_valid_expression() const { return is_valid(ExpressionProduction); } |
567 | 588 |
568 bool is_valid_binding_pattern() const { | 589 bool is_valid_binding_pattern() const { |
569 return !binding_pattern_error_.HasError(); | 590 return is_valid(BindingPatternProduction); |
570 } | 591 } |
571 | 592 |
572 bool is_valid_assignment_pattern() const { | 593 bool is_valid_assignment_pattern() const { |
573 return !assignment_pattern_error_.HasError(); | 594 return is_valid(AssignmentPatternProduction); |
574 } | 595 } |
575 | 596 |
576 bool is_valid_arrow_formal_parameters() const { | 597 bool is_valid_arrow_formal_parameters() const { |
577 return !arrow_formal_parameters_error_.HasError(); | 598 return is_valid(ArrowFormalParametersProduction); |
578 } | 599 } |
579 | 600 |
580 bool is_valid_formal_parameter_list_without_duplicates() const { | 601 bool is_valid_formal_parameter_list_without_duplicates() const { |
581 return !duplicate_formal_parameter_error_.HasError(); | 602 return is_valid(DistinctFormalParametersProduction); |
582 } | 603 } |
583 | 604 |
584 // Note: callers should also check | 605 // Note: callers should also check |
585 // is_valid_formal_parameter_list_without_duplicates(). | 606 // is_valid_formal_parameter_list_without_duplicates(). |
586 bool is_valid_strict_mode_formal_parameters() const { | 607 bool is_valid_strict_mode_formal_parameters() const { |
587 return !strict_mode_formal_parameter_error_.HasError(); | 608 return is_valid(StrictModeFormalParametersProduction); |
588 } | 609 } |
589 | 610 |
590 // Note: callers should also check is_valid_strict_mode_formal_parameters() | 611 // Note: callers should also check is_valid_strict_mode_formal_parameters() |
591 // and is_valid_formal_parameter_list_without_duplicates(). | 612 // and is_valid_formal_parameter_list_without_duplicates(). |
592 bool is_valid_strong_mode_formal_parameters() const { | 613 bool is_valid_strong_mode_formal_parameters() const { |
593 return !strong_mode_formal_parameter_error_.HasError(); | 614 return is_valid(StrongModeFormalParametersProduction); |
594 } | 615 } |
595 | 616 |
596 const Error& expression_error() const { return expression_error_; } | 617 const Error& expression_error() const { return expression_error_; } |
597 | 618 |
598 const Error& binding_pattern_error() const { | 619 const Error& binding_pattern_error() const { |
599 return binding_pattern_error_; | 620 return binding_pattern_error_; |
600 } | 621 } |
601 | 622 |
602 const Error& assignment_pattern_error() const { | 623 const Error& assignment_pattern_error() const { |
603 return assignment_pattern_error_; | 624 return assignment_pattern_error_; |
(...skipping 12 matching lines...) Expand all Loading... |
616 } | 637 } |
617 | 638 |
618 const Error& strong_mode_formal_parameter_error() const { | 639 const Error& strong_mode_formal_parameter_error() const { |
619 return strong_mode_formal_parameter_error_; | 640 return strong_mode_formal_parameter_error_; |
620 } | 641 } |
621 | 642 |
622 void RecordExpressionError(const Scanner::Location& loc, | 643 void RecordExpressionError(const Scanner::Location& loc, |
623 MessageTemplate::Template message, | 644 MessageTemplate::Template message, |
624 const char* arg = nullptr) { | 645 const char* arg = nullptr) { |
625 if (!is_valid_expression()) return; | 646 if (!is_valid_expression()) return; |
| 647 invalid_productions_ |= ExpressionProduction; |
626 expression_error_.location = loc; | 648 expression_error_.location = loc; |
627 expression_error_.message = message; | 649 expression_error_.message = message; |
628 expression_error_.arg = arg; | 650 expression_error_.arg = arg; |
629 } | 651 } |
630 | 652 |
631 void RecordBindingPatternError(const Scanner::Location& loc, | 653 void RecordBindingPatternError(const Scanner::Location& loc, |
632 MessageTemplate::Template message, | 654 MessageTemplate::Template message, |
633 const char* arg = nullptr) { | 655 const char* arg = nullptr) { |
634 if (!is_valid_binding_pattern()) return; | 656 if (!is_valid_binding_pattern()) return; |
| 657 invalid_productions_ |= BindingPatternProduction; |
635 binding_pattern_error_.location = loc; | 658 binding_pattern_error_.location = loc; |
636 binding_pattern_error_.message = message; | 659 binding_pattern_error_.message = message; |
637 binding_pattern_error_.arg = arg; | 660 binding_pattern_error_.arg = arg; |
638 } | 661 } |
639 | 662 |
640 void RecordAssignmentPatternError(const Scanner::Location& loc, | 663 void RecordAssignmentPatternError(const Scanner::Location& loc, |
641 MessageTemplate::Template message, | 664 MessageTemplate::Template message, |
642 const char* arg = nullptr) { | 665 const char* arg = nullptr) { |
643 if (!is_valid_assignment_pattern()) return; | 666 if (!is_valid_assignment_pattern()) return; |
| 667 invalid_productions_ |= AssignmentPatternProduction; |
644 assignment_pattern_error_.location = loc; | 668 assignment_pattern_error_.location = loc; |
645 assignment_pattern_error_.message = message; | 669 assignment_pattern_error_.message = message; |
646 assignment_pattern_error_.arg = arg; | 670 assignment_pattern_error_.arg = arg; |
647 } | 671 } |
648 | 672 |
649 void RecordArrowFormalParametersError(const Scanner::Location& loc, | 673 void RecordArrowFormalParametersError(const Scanner::Location& loc, |
650 MessageTemplate::Template message, | 674 MessageTemplate::Template message, |
651 const char* arg = nullptr) { | 675 const char* arg = nullptr) { |
652 if (!is_valid_arrow_formal_parameters()) return; | 676 if (!is_valid_arrow_formal_parameters()) return; |
| 677 invalid_productions_ |= ArrowFormalParametersProduction; |
653 arrow_formal_parameters_error_.location = loc; | 678 arrow_formal_parameters_error_.location = loc; |
654 arrow_formal_parameters_error_.message = message; | 679 arrow_formal_parameters_error_.message = message; |
655 arrow_formal_parameters_error_.arg = arg; | 680 arrow_formal_parameters_error_.arg = arg; |
656 } | 681 } |
657 | 682 |
658 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | 683 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
659 if (!is_valid_formal_parameter_list_without_duplicates()) return; | 684 if (!is_valid_formal_parameter_list_without_duplicates()) return; |
| 685 invalid_productions_ |= DistinctFormalParametersProduction; |
660 duplicate_formal_parameter_error_.location = loc; | 686 duplicate_formal_parameter_error_.location = loc; |
661 duplicate_formal_parameter_error_.message = | 687 duplicate_formal_parameter_error_.message = |
662 MessageTemplate::kStrictParamDupe; | 688 MessageTemplate::kStrictParamDupe; |
663 duplicate_formal_parameter_error_.arg = nullptr; | 689 duplicate_formal_parameter_error_.arg = nullptr; |
664 } | 690 } |
665 | 691 |
666 // Record a binding that would be invalid in strict mode. Confusingly this | 692 // Record a binding that would be invalid in strict mode. Confusingly this |
667 // is not the same as StrictFormalParameterList, which simply forbids | 693 // is not the same as StrictFormalParameterList, which simply forbids |
668 // duplicate bindings. | 694 // duplicate bindings. |
669 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, | 695 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
670 MessageTemplate::Template message, | 696 MessageTemplate::Template message, |
671 const char* arg = nullptr) { | 697 const char* arg = nullptr) { |
672 if (!is_valid_strict_mode_formal_parameters()) return; | 698 if (!is_valid_strict_mode_formal_parameters()) return; |
| 699 invalid_productions_ |= StrictModeFormalParametersProduction; |
673 strict_mode_formal_parameter_error_.location = loc; | 700 strict_mode_formal_parameter_error_.location = loc; |
674 strict_mode_formal_parameter_error_.message = message; | 701 strict_mode_formal_parameter_error_.message = message; |
675 strict_mode_formal_parameter_error_.arg = arg; | 702 strict_mode_formal_parameter_error_.arg = arg; |
676 } | 703 } |
677 | 704 |
678 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, | 705 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
679 MessageTemplate::Template message, | 706 MessageTemplate::Template message, |
680 const char* arg = nullptr) { | 707 const char* arg = nullptr) { |
681 if (!is_valid_strong_mode_formal_parameters()) return; | 708 if (!is_valid_strong_mode_formal_parameters()) return; |
| 709 invalid_productions_ |= StrongModeFormalParametersProduction; |
682 strong_mode_formal_parameter_error_.location = loc; | 710 strong_mode_formal_parameter_error_.location = loc; |
683 strong_mode_formal_parameter_error_.message = message; | 711 strong_mode_formal_parameter_error_.message = message; |
684 strong_mode_formal_parameter_error_.arg = arg; | 712 strong_mode_formal_parameter_error_.arg = arg; |
685 } | 713 } |
686 | 714 |
687 enum TargetProduction { | |
688 ExpressionProduction = 1 << 0, | |
689 BindingPatternProduction = 1 << 1, | |
690 AssignmentPatternProduction = 1 << 2, | |
691 FormalParametersProduction = 1 << 3, | |
692 ArrowFormalParametersProduction = 1 << 4, | |
693 StandardProductions = (ExpressionProduction | BindingPatternProduction | | |
694 AssignmentPatternProduction), | |
695 PatternProductions = | |
696 BindingPatternProduction | AssignmentPatternProduction, | |
697 AllProductions = (StandardProductions | FormalParametersProduction | | |
698 ArrowFormalParametersProduction), | |
699 }; | |
700 | |
701 void Accumulate(const ExpressionClassifier& inner, | 715 void Accumulate(const ExpressionClassifier& inner, |
702 unsigned productions = StandardProductions) { | 716 unsigned productions = StandardProductions) { |
703 if (productions & ExpressionProduction && is_valid_expression()) { | 717 // Propagate errors from inner, but don't overwrite already recorded |
704 expression_error_ = inner.expression_error_; | 718 // errors. |
705 } | 719 unsigned non_arrow_inner_invalid_productions = |
706 if (productions & BindingPatternProduction && | 720 inner.invalid_productions_ & ~ArrowFormalParametersProduction; |
707 is_valid_binding_pattern()) { | 721 if (non_arrow_inner_invalid_productions == 0) return; |
708 binding_pattern_error_ = inner.binding_pattern_error_; | 722 unsigned non_arrow_productions = |
709 } | 723 productions & ~ArrowFormalParametersProduction; |
710 if (productions & AssignmentPatternProduction && | 724 unsigned errors = |
711 is_valid_assignment_pattern()) { | 725 non_arrow_productions & non_arrow_inner_invalid_productions; |
712 assignment_pattern_error_ = inner.assignment_pattern_error_; | 726 errors &= ~invalid_productions_; |
713 } | 727 if (errors != 0) { |
714 if (productions & FormalParametersProduction) { | 728 invalid_productions_ |= errors; |
715 if (is_valid_formal_parameter_list_without_duplicates()) { | 729 if (errors & ExpressionProduction) |
| 730 expression_error_ = inner.expression_error_; |
| 731 if (errors & BindingPatternProduction) |
| 732 binding_pattern_error_ = inner.binding_pattern_error_; |
| 733 if (errors & AssignmentPatternProduction) |
| 734 assignment_pattern_error_ = inner.assignment_pattern_error_; |
| 735 if (errors & DistinctFormalParametersProduction) |
716 duplicate_formal_parameter_error_ = | 736 duplicate_formal_parameter_error_ = |
717 inner.duplicate_formal_parameter_error_; | 737 inner.duplicate_formal_parameter_error_; |
718 } | 738 if (errors & StrictModeFormalParametersProduction) |
719 if (is_valid_strict_mode_formal_parameters()) { | |
720 strict_mode_formal_parameter_error_ = | 739 strict_mode_formal_parameter_error_ = |
721 inner.strict_mode_formal_parameter_error_; | 740 inner.strict_mode_formal_parameter_error_; |
722 } | 741 if (errors & StrongModeFormalParametersProduction) |
723 if (is_valid_strong_mode_formal_parameters()) { | |
724 strong_mode_formal_parameter_error_ = | 742 strong_mode_formal_parameter_error_ = |
725 inner.strong_mode_formal_parameter_error_; | 743 inner.strong_mode_formal_parameter_error_; |
726 } | |
727 } | 744 } |
| 745 |
| 746 // As an exception to the above, the result continues to be a valid arrow |
| 747 // formal parameters if the inner expression is a valid binding pattern. |
728 if (productions & ArrowFormalParametersProduction && | 748 if (productions & ArrowFormalParametersProduction && |
729 is_valid_arrow_formal_parameters()) { | 749 is_valid_arrow_formal_parameters() && |
730 // The result continues to be a valid arrow formal parameters if the | 750 !inner.is_valid_binding_pattern()) { |
731 // inner expression is a valid binding pattern. | 751 invalid_productions_ |= ArrowFormalParametersProduction; |
732 arrow_formal_parameters_error_ = inner.binding_pattern_error_; | 752 arrow_formal_parameters_error_ = inner.binding_pattern_error_; |
733 } | 753 } |
734 } | 754 } |
735 | 755 |
736 void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) { | 756 void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) { |
737 Accumulate(inner, AllProductions & ~PatternProductions); | 757 Accumulate(inner, AllProductions & ~PatternProductions); |
738 if (!inner.is_valid_expression()) { | 758 if (!inner.is_valid_expression()) { |
739 if (is_valid_binding_pattern()) { | 759 if (is_valid_binding_pattern()) { |
740 binding_pattern_error_ = inner.expression_error(); | 760 binding_pattern_error_ = inner.expression_error(); |
741 } | 761 } |
742 if (is_valid_assignment_pattern()) { | 762 if (is_valid_assignment_pattern()) { |
743 assignment_pattern_error_ = inner.expression_error(); | 763 assignment_pattern_error_ = inner.expression_error(); |
744 } | 764 } |
745 } | 765 } |
746 } | 766 } |
747 | 767 |
748 private: | 768 private: |
| 769 unsigned invalid_productions_; |
749 Error expression_error_; | 770 Error expression_error_; |
750 Error binding_pattern_error_; | 771 Error binding_pattern_error_; |
751 Error assignment_pattern_error_; | 772 Error assignment_pattern_error_; |
752 Error arrow_formal_parameters_error_; | 773 Error arrow_formal_parameters_error_; |
753 Error duplicate_formal_parameter_error_; | 774 Error duplicate_formal_parameter_error_; |
754 Error strict_mode_formal_parameter_error_; | 775 Error strict_mode_formal_parameter_error_; |
755 Error strong_mode_formal_parameter_error_; | 776 Error strong_mode_formal_parameter_error_; |
756 }; | 777 }; |
757 | 778 |
758 void ReportClassifierError( | 779 void ReportClassifierError( |
(...skipping 2179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 duplicate_loc); | 2959 duplicate_loc); |
2939 } | 2960 } |
2940 expression = this->ParseArrowFunctionLiteral( | 2961 expression = this->ParseArrowFunctionLiteral( |
2941 scope, has_rest, arrow_formals_classifier, CHECK_OK); | 2962 scope, has_rest, arrow_formals_classifier, CHECK_OK); |
2942 return expression; | 2963 return expression; |
2943 } | 2964 } |
2944 | 2965 |
2945 // "expression" was not itself an arrow function parameter list, but it might | 2966 // "expression" was not itself an arrow function parameter list, but it might |
2946 // form part of one. Propagate speculative formal parameter error locations. | 2967 // form part of one. Propagate speculative formal parameter error locations. |
2947 classifier->Accumulate(arrow_formals_classifier, | 2968 classifier->Accumulate(arrow_formals_classifier, |
2948 ExpressionClassifier::FormalParametersProduction); | 2969 ExpressionClassifier::FormalParametersProductions); |
2949 | 2970 |
2950 if (!Token::IsAssignmentOp(peek())) { | 2971 if (!Token::IsAssignmentOp(peek())) { |
2951 if (fni_ != NULL) fni_->Leave(); | 2972 if (fni_ != NULL) fni_->Leave(); |
2952 // Parsed conditional expression only (no assignment). | 2973 // Parsed conditional expression only (no assignment). |
2953 return expression; | 2974 return expression; |
2954 } | 2975 } |
2955 | 2976 |
2956 if (!allow_harmony_destructuring()) { | 2977 if (!allow_harmony_destructuring()) { |
2957 BindingPatternUnexpectedToken(classifier); | 2978 BindingPatternUnexpectedToken(classifier); |
2958 } | 2979 } |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4033 *ok = false; | 4054 *ok = false; |
4034 return; | 4055 return; |
4035 } | 4056 } |
4036 has_seen_constructor_ = true; | 4057 has_seen_constructor_ = true; |
4037 return; | 4058 return; |
4038 } | 4059 } |
4039 } | 4060 } |
4040 } } // v8::internal | 4061 } } // v8::internal |
4041 | 4062 |
4042 #endif // V8_PREPARSER_H | 4063 #endif // V8_PREPARSER_H |
OLD | NEW |