| 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 |