| 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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 kFunctionNameIsStrictReserved, | 22 kFunctionNameIsStrictReserved, |
| 23 kSkipFunctionNameCheck, | 23 kSkipFunctionNameCheck, |
| 24 kFunctionNameValidityUnknown | 24 kFunctionNameValidityUnknown |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 enum AllowLabelledFunctionStatement { | 27 enum AllowLabelledFunctionStatement { |
| 28 kAllowLabelledFunctionStatement, | 28 kAllowLabelledFunctionStatement, |
| 29 kDisallowLabelledFunctionStatement, | 29 kDisallowLabelledFunctionStatement, |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 enum class ParseFunctionFlags { |
| 33 kIsNormal = 0, |
| 34 kIsGenerator = 1, |
| 35 kIsAsync = 2, |
| 36 kIsDefault = 4 |
| 37 }; |
| 38 |
| 39 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
| 40 ParseFunctionFlags rhs) { |
| 41 typedef unsigned char T; |
| 42 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | |
| 43 static_cast<T>(rhs)); |
| 44 } |
| 45 |
| 46 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, |
| 47 const ParseFunctionFlags& rhs) { |
| 48 lhs = lhs | rhs; |
| 49 return lhs; |
| 50 } |
| 51 |
| 52 static inline bool operator&(ParseFunctionFlags bitfield, |
| 53 ParseFunctionFlags mask) { |
| 54 typedef unsigned char T; |
| 55 return static_cast<T>(bitfield) & static_cast<T>(mask); |
| 56 } |
| 57 |
| 32 struct FormalParametersBase { | 58 struct FormalParametersBase { |
| 33 explicit FormalParametersBase(Scope* scope) : scope(scope) {} | 59 explicit FormalParametersBase(Scope* scope) : scope(scope) {} |
| 34 Scope* scope; | 60 Scope* scope; |
| 35 bool has_rest = false; | 61 bool has_rest = false; |
| 36 bool is_simple = true; | 62 bool is_simple = true; |
| 37 int materialized_literals_count = 0; | 63 int materialized_literals_count = 0; |
| 38 }; | 64 }; |
| 39 | 65 |
| 40 | 66 |
| 41 // Common base class shared between parser and pre-parser. Traits encapsulate | 67 // Common base class shared between parser and pre-parser. Traits encapsulate |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 stack_limit_(stack_limit), | 135 stack_limit_(stack_limit), |
| 110 zone_(zone), | 136 zone_(zone), |
| 111 scanner_(scanner), | 137 scanner_(scanner), |
| 112 stack_overflow_(false), | 138 stack_overflow_(false), |
| 113 allow_lazy_(false), | 139 allow_lazy_(false), |
| 114 allow_natives_(false), | 140 allow_natives_(false), |
| 115 allow_tailcalls_(false), | 141 allow_tailcalls_(false), |
| 116 allow_harmony_restrictive_declarations_(false), | 142 allow_harmony_restrictive_declarations_(false), |
| 117 allow_harmony_do_expressions_(false), | 143 allow_harmony_do_expressions_(false), |
| 118 allow_harmony_function_name_(false), | 144 allow_harmony_function_name_(false), |
| 119 allow_harmony_function_sent_(false) {} | 145 allow_harmony_function_sent_(false), |
| 146 allow_harmony_async_await_(false) {} |
| 120 | 147 |
| 121 #define ALLOW_ACCESSORS(name) \ | 148 #define ALLOW_ACCESSORS(name) \ |
| 122 bool allow_##name() const { return allow_##name##_; } \ | 149 bool allow_##name() const { return allow_##name##_; } \ |
| 123 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 150 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
| 124 | 151 |
| 125 #define SCANNER_ACCESSORS(name) \ | 152 #define SCANNER_ACCESSORS(name) \ |
| 126 bool allow_##name() const { return scanner_->allow_##name(); } \ | 153 bool allow_##name() const { return scanner_->allow_##name(); } \ |
| 127 void set_allow_##name(bool allow) { \ | 154 void set_allow_##name(bool allow) { \ |
| 128 return scanner_->set_allow_##name(allow); \ | 155 return scanner_->set_allow_##name(allow); \ |
| 129 } | 156 } |
| 130 | 157 |
| 131 ALLOW_ACCESSORS(lazy); | 158 ALLOW_ACCESSORS(lazy); |
| 132 ALLOW_ACCESSORS(natives); | 159 ALLOW_ACCESSORS(natives); |
| 133 ALLOW_ACCESSORS(tailcalls); | 160 ALLOW_ACCESSORS(tailcalls); |
| 134 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 161 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
| 135 ALLOW_ACCESSORS(harmony_do_expressions); | 162 ALLOW_ACCESSORS(harmony_do_expressions); |
| 136 ALLOW_ACCESSORS(harmony_function_name); | 163 ALLOW_ACCESSORS(harmony_function_name); |
| 137 ALLOW_ACCESSORS(harmony_function_sent); | 164 ALLOW_ACCESSORS(harmony_function_sent); |
| 165 ALLOW_ACCESSORS(harmony_async_await); |
| 138 SCANNER_ACCESSORS(harmony_exponentiation_operator); | 166 SCANNER_ACCESSORS(harmony_exponentiation_operator); |
| 139 | 167 |
| 140 #undef SCANNER_ACCESSORS | 168 #undef SCANNER_ACCESSORS |
| 141 #undef ALLOW_ACCESSORS | 169 #undef ALLOW_ACCESSORS |
| 142 | 170 |
| 143 uintptr_t stack_limit() const { return stack_limit_; } | 171 uintptr_t stack_limit() const { return stack_limit_; } |
| 144 | 172 |
| 145 protected: | 173 protected: |
| 146 enum AllowRestrictedIdentifiers { | 174 enum AllowRestrictedIdentifiers { |
| 147 kAllowRestrictedIdentifiers, | 175 kAllowRestrictedIdentifiers, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 this_location_ = location; | 245 this_location_ = location; |
| 218 } | 246 } |
| 219 void set_super_location(Scanner::Location location) { | 247 void set_super_location(Scanner::Location location) { |
| 220 super_location_ = location; | 248 super_location_ = location; |
| 221 } | 249 } |
| 222 void set_return_location(Scanner::Location location) { | 250 void set_return_location(Scanner::Location location) { |
| 223 return_location_ = location; | 251 return_location_ = location; |
| 224 } | 252 } |
| 225 | 253 |
| 226 bool is_generator() const { return IsGeneratorFunction(kind_); } | 254 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 255 bool is_async_function() const { return IsAsyncFunction(kind_); } |
| 227 | 256 |
| 228 FunctionKind kind() const { return kind_; } | 257 FunctionKind kind() const { return kind_; } |
| 229 FunctionState* outer() const { return outer_function_state_; } | 258 FunctionState* outer() const { return outer_function_state_; } |
| 230 | 259 |
| 231 void set_generator_object_variable( | 260 void set_generator_object_variable( |
| 232 typename Traits::Type::GeneratorVariable* variable) { | 261 typename Traits::Type::GeneratorVariable* variable) { |
| 233 DCHECK(variable != NULL); | 262 DCHECK(variable != NULL); |
| 234 DCHECK(is_generator()); | 263 DCHECK(is_generator()); |
| 235 generator_object_variable_ = variable; | 264 generator_object_variable_ = variable; |
| 236 } | 265 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 return true; | 489 return true; |
| 461 } | 490 } |
| 462 return false; | 491 return false; |
| 463 } | 492 } |
| 464 | 493 |
| 465 bool PeekContextualKeyword(Vector<const char> keyword) { | 494 bool PeekContextualKeyword(Vector<const char> keyword) { |
| 466 return peek() == Token::IDENTIFIER && | 495 return peek() == Token::IDENTIFIER && |
| 467 scanner()->is_next_contextual_keyword(keyword); | 496 scanner()->is_next_contextual_keyword(keyword); |
| 468 } | 497 } |
| 469 | 498 |
| 499 bool PeekAheadContextualKeyword(Vector<const char> keyword) { |
| 500 return PeekAhead() == Token::IDENTIFIER && |
| 501 scanner()->is_next_next_contextual_keyword(keyword); |
| 502 } |
| 503 |
| 470 void ExpectMetaProperty(Vector<const char> property_name, | 504 void ExpectMetaProperty(Vector<const char> property_name, |
| 471 const char* full_name, int pos, bool* ok); | 505 const char* full_name, int pos, bool* ok); |
| 472 | 506 |
| 473 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 507 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 474 Expect(Token::IDENTIFIER, ok); | 508 Expect(Token::IDENTIFIER, ok); |
| 475 if (!*ok) return; | 509 if (!*ok) return; |
| 476 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 510 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 477 ReportUnexpectedToken(scanner()->current_token()); | 511 ReportUnexpectedToken(scanner()->current_token()); |
| 478 *ok = false; | 512 *ok = false; |
| 479 } | 513 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 return 0; // 0 precedence will terminate binary expression parsing | 584 return 0; // 0 precedence will terminate binary expression parsing |
| 551 return Token::Precedence(token); | 585 return Token::Precedence(token); |
| 552 } | 586 } |
| 553 | 587 |
| 554 typename Traits::Type::Factory* factory() { | 588 typename Traits::Type::Factory* factory() { |
| 555 return function_state_->factory(); | 589 return function_state_->factory(); |
| 556 } | 590 } |
| 557 | 591 |
| 558 LanguageMode language_mode() { return scope_->language_mode(); } | 592 LanguageMode language_mode() { return scope_->language_mode(); } |
| 559 bool is_generator() const { return function_state_->is_generator(); } | 593 bool is_generator() const { return function_state_->is_generator(); } |
| 594 bool is_async_function() const { |
| 595 return function_state_->is_async_function(); |
| 596 } |
| 560 | 597 |
| 561 // Report syntax errors. | 598 // Report syntax errors. |
| 562 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 599 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
| 563 ParseErrorType error_type = kSyntaxError) { | 600 ParseErrorType error_type = kSyntaxError) { |
| 564 Scanner::Location source_location = scanner()->location(); | 601 Scanner::Location source_location = scanner()->location(); |
| 565 Traits::ReportMessageAt(source_location, message, arg, error_type); | 602 Traits::ReportMessageAt(source_location, message, arg, error_type); |
| 566 } | 603 } |
| 567 | 604 |
| 568 void ReportMessageAt(Scanner::Location location, | 605 void ReportMessageAt(Scanner::Location location, |
| 569 MessageTemplate::Template message, | 606 MessageTemplate::Template message, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 *ok = false; | 673 *ok = false; |
| 637 } else if (is_strict(language_mode) && | 674 } else if (is_strict(language_mode) && |
| 638 !classifier->is_valid_strict_mode_formal_parameters()) { | 675 !classifier->is_valid_strict_mode_formal_parameters()) { |
| 639 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 676 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); |
| 640 *ok = false; | 677 *ok = false; |
| 641 } | 678 } |
| 642 } | 679 } |
| 643 | 680 |
| 644 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 681 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
| 645 ExpressionT expr, | 682 ExpressionT expr, |
| 646 bool parenthesized_formals, bool* ok) { | 683 bool parenthesized_formals, bool is_async, |
| 684 bool* ok) { |
| 647 if (classifier->is_valid_binding_pattern()) { | 685 if (classifier->is_valid_binding_pattern()) { |
| 648 // A simple arrow formal parameter: IDENTIFIER => BODY. | 686 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 649 if (!this->IsIdentifier(expr)) { | 687 if (!this->IsIdentifier(expr)) { |
| 650 Traits::ReportMessageAt(scanner()->location(), | 688 Traits::ReportMessageAt(scanner()->location(), |
| 651 MessageTemplate::kUnexpectedToken, | 689 MessageTemplate::kUnexpectedToken, |
| 652 Token::String(scanner()->current_token())); | 690 Token::String(scanner()->current_token())); |
| 653 *ok = false; | 691 *ok = false; |
| 654 } | 692 } |
| 655 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 693 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
| 656 // If after parsing the expr, we see an error but the expression is | 694 // If after parsing the expr, we see an error but the expression is |
| 657 // neither a valid binding pattern nor a valid parenthesized formal | 695 // neither a valid binding pattern nor a valid parenthesized formal |
| 658 // parameter list, show the "arrow formal parameters" error if the formals | 696 // parameter list, show the "arrow formal parameters" error if the formals |
| 659 // started with a parenthesis, and the binding pattern error otherwise. | 697 // started with a parenthesis, and the binding pattern error otherwise. |
| 660 const typename ExpressionClassifier::Error& error = | 698 const typename ExpressionClassifier::Error& error = |
| 661 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 699 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
| 662 : classifier->binding_pattern_error(); | 700 : classifier->binding_pattern_error(); |
| 663 ReportClassifierError(error); | 701 ReportClassifierError(error); |
| 664 *ok = false; | 702 *ok = false; |
| 665 } | 703 } |
| 704 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { |
| 705 const typename ExpressionClassifier::Error& error = |
| 706 classifier->async_arrow_formal_parameters_error(); |
| 707 ReportClassifierError(error); |
| 708 *ok = false; |
| 709 } |
| 666 } | 710 } |
| 667 | 711 |
| 668 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 712 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
| 669 if (!classifier->is_valid_let_pattern()) { | 713 if (!classifier->is_valid_let_pattern()) { |
| 670 ReportClassifierError(classifier->let_pattern_error()); | 714 ReportClassifierError(classifier->let_pattern_error()); |
| 671 *ok = false; | 715 *ok = false; |
| 672 } | 716 } |
| 673 } | 717 } |
| 674 | 718 |
| 675 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 719 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 return ParseIdentifierOrStrictReservedWord(this->is_generator(), | 773 return ParseIdentifierOrStrictReservedWord(this->is_generator(), |
| 730 is_strict_reserved, ok); | 774 is_strict_reserved, ok); |
| 731 } | 775 } |
| 732 | 776 |
| 733 IdentifierT ParseIdentifierName(bool* ok); | 777 IdentifierT ParseIdentifierName(bool* ok); |
| 734 | 778 |
| 735 ExpressionT ParseRegExpLiteral(bool seen_equal, | 779 ExpressionT ParseRegExpLiteral(bool seen_equal, |
| 736 ExpressionClassifier* classifier, bool* ok); | 780 ExpressionClassifier* classifier, bool* ok); |
| 737 | 781 |
| 738 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 782 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 739 bool* ok); | 783 bool* is_async, bool* ok); |
| 784 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 785 bool* ok) { |
| 786 bool is_async; |
| 787 return ParsePrimaryExpression(classifier, &is_async, ok); |
| 788 } |
| 740 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 789 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 741 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 790 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| 742 bool* ok); | 791 bool* ok); |
| 743 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 792 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| 744 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 793 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 745 bool* is_computed_name, | 794 bool* is_await, bool* is_computed_name, |
| 746 ExpressionClassifier* classifier, bool* ok); | 795 ExpressionClassifier* classifier, bool* ok); |
| 747 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 796 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 748 ObjectLiteralPropertyT ParsePropertyDefinition( | 797 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 749 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 798 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 750 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 799 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 751 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 800 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
| 752 typename Traits::Type::ExpressionList ParseArguments( | 801 typename Traits::Type::ExpressionList ParseArguments( |
| 802 Scanner::Location* first_spread_pos, bool maybe_arrow, |
| 803 ExpressionClassifier* classifier, bool* ok); |
| 804 typename Traits::Type::ExpressionList ParseArguments( |
| 753 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 805 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 754 bool* ok); | 806 bool* ok) { |
| 807 return ParseArguments(first_spread_pos, false, classifier, ok); |
| 808 } |
| 755 | 809 |
| 756 ExpressionT ParseAssignmentExpression(bool accept_IN, | 810 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 757 ExpressionClassifier* classifier, | 811 ExpressionClassifier* classifier, |
| 758 bool* ok); | 812 bool* ok); |
| 759 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 813 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| 760 ExpressionT ParseConditionalExpression(bool accept_IN, | 814 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 761 ExpressionClassifier* classifier, | 815 ExpressionClassifier* classifier, |
| 762 bool* ok); | 816 bool* ok); |
| 763 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 817 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 764 ExpressionClassifier* classifier, bool* ok); | 818 ExpressionClassifier* classifier, bool* ok); |
| 765 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 819 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 766 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 820 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 767 bool* ok); | 821 bool* ok); |
| 768 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 822 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| 769 bool* ok); | 823 bool* ok); |
| 770 ExpressionT ParseMemberWithNewPrefixesExpression( | 824 ExpressionT ParseMemberWithNewPrefixesExpression( |
| 771 ExpressionClassifier* classifier, bool* ok); | 825 ExpressionClassifier* classifier, bool* is_async, bool* ok); |
| 772 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | 826 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, |
| 827 bool* is_async, bool* ok); |
| 773 ExpressionT ParseMemberExpressionContinuation( | 828 ExpressionT ParseMemberExpressionContinuation( |
| 774 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | 829 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 830 bool* ok); |
| 775 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 831 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
| 776 const FormalParametersT& parameters, | 832 const FormalParametersT& parameters, |
| 833 bool is_async, |
| 777 const ExpressionClassifier& classifier, | 834 const ExpressionClassifier& classifier, |
| 778 bool* ok); | 835 bool* ok); |
| 779 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 836 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
| 780 ExpressionClassifier* classifier, bool* ok); | 837 ExpressionClassifier* classifier, bool* ok); |
| 781 void AddTemplateExpression(ExpressionT); | 838 void AddTemplateExpression(ExpressionT); |
| 782 ExpressionT ParseSuperExpression(bool is_new, | 839 ExpressionT ParseSuperExpression(bool is_new, |
| 783 ExpressionClassifier* classifier, bool* ok); | 840 ExpressionClassifier* classifier, bool* ok); |
| 784 ExpressionT ParseNewTargetExpression(bool* ok); | 841 ExpressionT ParseNewTargetExpression(bool* ok); |
| 785 | 842 |
| 786 void ParseFormalParameter(FormalParametersT* parameters, | 843 void ParseFormalParameter(FormalParametersT* parameters, |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 Scanner* scanner_; | 966 Scanner* scanner_; |
| 910 bool stack_overflow_; | 967 bool stack_overflow_; |
| 911 | 968 |
| 912 bool allow_lazy_; | 969 bool allow_lazy_; |
| 913 bool allow_natives_; | 970 bool allow_natives_; |
| 914 bool allow_tailcalls_; | 971 bool allow_tailcalls_; |
| 915 bool allow_harmony_restrictive_declarations_; | 972 bool allow_harmony_restrictive_declarations_; |
| 916 bool allow_harmony_do_expressions_; | 973 bool allow_harmony_do_expressions_; |
| 917 bool allow_harmony_function_name_; | 974 bool allow_harmony_function_name_; |
| 918 bool allow_harmony_function_sent_; | 975 bool allow_harmony_function_sent_; |
| 976 bool allow_harmony_async_await_; |
| 919 }; | 977 }; |
| 920 | 978 |
| 921 template <class Traits> | 979 template <class Traits> |
| 922 ParserBase<Traits>::FunctionState::FunctionState( | 980 ParserBase<Traits>::FunctionState::FunctionState( |
| 923 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 981 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
| 924 FunctionKind kind, typename Traits::Type::Factory* factory) | 982 FunctionKind kind, typename Traits::Type::Factory* factory) |
| 925 : next_materialized_literal_index_(0), | 983 : next_materialized_literal_index_(0), |
| 926 expected_property_count_(0), | 984 expected_property_count_(0), |
| 927 this_location_(Scanner::Location::invalid()), | 985 this_location_(Scanner::Location::invalid()), |
| 928 return_location_(Scanner::Location::invalid()), | 986 return_location_(Scanner::Location::invalid()), |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 } | 1118 } |
| 1061 if (this->IsArguments(name)) { | 1119 if (this->IsArguments(name)) { |
| 1062 scope_->RecordArgumentsUsage(); | 1120 scope_->RecordArgumentsUsage(); |
| 1063 classifier->RecordStrictModeFormalParameterError( | 1121 classifier->RecordStrictModeFormalParameterError( |
| 1064 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1122 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1065 if (is_strict(language_mode())) { | 1123 if (is_strict(language_mode())) { |
| 1066 classifier->RecordBindingPatternError( | 1124 classifier->RecordBindingPatternError( |
| 1067 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1125 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1068 } | 1126 } |
| 1069 } | 1127 } |
| 1128 if (this->IsAwait(name)) { |
| 1129 if (is_async_function()) { |
| 1130 classifier->RecordPatternError( |
| 1131 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); |
| 1132 } |
| 1133 classifier->RecordAsyncArrowFormalParametersError( |
| 1134 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); |
| 1135 } |
| 1070 | 1136 |
| 1071 if (classifier->duplicate_finder() != nullptr && | 1137 if (classifier->duplicate_finder() != nullptr && |
| 1072 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1138 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 1073 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1139 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1074 } | 1140 } |
| 1075 return name; | 1141 return name; |
| 1076 } else if (is_sloppy(language_mode()) && | 1142 } else if (is_sloppy(language_mode()) && |
| 1077 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1143 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1078 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1144 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
| 1079 next == Token::LET || next == Token::STATIC || | 1145 next == Token::LET || next == Token::STATIC || |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1178 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
| 1113 *is_strict_reserved = true; | 1179 *is_strict_reserved = true; |
| 1114 } else { | 1180 } else { |
| 1115 ReportUnexpectedToken(next); | 1181 ReportUnexpectedToken(next); |
| 1116 *ok = false; | 1182 *ok = false; |
| 1117 return Traits::EmptyIdentifier(); | 1183 return Traits::EmptyIdentifier(); |
| 1118 } | 1184 } |
| 1119 | 1185 |
| 1120 IdentifierT name = this->GetSymbol(scanner()); | 1186 IdentifierT name = this->GetSymbol(scanner()); |
| 1121 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1187 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1188 |
| 1122 return name; | 1189 return name; |
| 1123 } | 1190 } |
| 1124 | 1191 |
| 1125 | 1192 |
| 1126 template <class Traits> | 1193 template <class Traits> |
| 1127 typename ParserBase<Traits>::IdentifierT | 1194 typename ParserBase<Traits>::IdentifierT |
| 1128 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1195 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
| 1129 Token::Value next = Next(); | 1196 Token::Value next = Next(); |
| 1130 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1197 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
| 1131 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1198 next != Token::LET && next != Token::STATIC && next != Token::YIELD && |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 #define DUMMY ) // to make indentation work | 1243 #define DUMMY ) // to make indentation work |
| 1177 #undef DUMMY | 1244 #undef DUMMY |
| 1178 | 1245 |
| 1179 // Used in functions where the return type is not ExpressionT. | 1246 // Used in functions where the return type is not ExpressionT. |
| 1180 #define CHECK_OK_CUSTOM(x) ok); \ | 1247 #define CHECK_OK_CUSTOM(x) ok); \ |
| 1181 if (!*ok) return this->x(); \ | 1248 if (!*ok) return this->x(); \ |
| 1182 ((void)0 | 1249 ((void)0 |
| 1183 #define DUMMY ) // to make indentation work | 1250 #define DUMMY ) // to make indentation work |
| 1184 #undef DUMMY | 1251 #undef DUMMY |
| 1185 | 1252 |
| 1186 | |
| 1187 template <class Traits> | 1253 template <class Traits> |
| 1188 typename ParserBase<Traits>::ExpressionT | 1254 typename ParserBase<Traits>::ExpressionT |
| 1189 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, | 1255 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 1190 bool* ok) { | 1256 bool* is_async, bool* ok) { |
| 1191 // PrimaryExpression :: | 1257 // PrimaryExpression :: |
| 1192 // 'this' | 1258 // 'this' |
| 1193 // 'null' | 1259 // 'null' |
| 1194 // 'true' | 1260 // 'true' |
| 1195 // 'false' | 1261 // 'false' |
| 1196 // Identifier | 1262 // Identifier |
| 1197 // Number | 1263 // Number |
| 1198 // String | 1264 // String |
| 1199 // ArrayLiteral | 1265 // ArrayLiteral |
| 1200 // ObjectLiteral | 1266 // ObjectLiteral |
| 1201 // RegExpLiteral | 1267 // RegExpLiteral |
| 1202 // ClassLiteral | 1268 // ClassLiteral |
| 1203 // '(' Expression ')' | 1269 // '(' Expression ')' |
| 1204 // TemplateLiteral | 1270 // TemplateLiteral |
| 1205 // do Block | 1271 // do Block |
| 1272 // AsyncFunctionExpression |
| 1206 | 1273 |
| 1207 int beg_pos = peek_position(); | 1274 int beg_pos = peek_position(); |
| 1208 switch (peek()) { | 1275 switch (peek()) { |
| 1209 case Token::THIS: { | 1276 case Token::THIS: { |
| 1210 BindingPatternUnexpectedToken(classifier); | 1277 BindingPatternUnexpectedToken(classifier); |
| 1211 Consume(Token::THIS); | 1278 Consume(Token::THIS); |
| 1212 return this->ThisExpression(scope_, factory(), beg_pos); | 1279 return this->ThisExpression(scope_, factory(), beg_pos); |
| 1213 } | 1280 } |
| 1214 | 1281 |
| 1215 case Token::NULL_LITERAL: | 1282 case Token::NULL_LITERAL: |
| 1216 case Token::TRUE_LITERAL: | 1283 case Token::TRUE_LITERAL: |
| 1217 case Token::FALSE_LITERAL: | 1284 case Token::FALSE_LITERAL: |
| 1218 BindingPatternUnexpectedToken(classifier); | 1285 BindingPatternUnexpectedToken(classifier); |
| 1219 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1286 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1220 case Token::SMI: | 1287 case Token::SMI: |
| 1221 case Token::NUMBER: | 1288 case Token::NUMBER: |
| 1222 BindingPatternUnexpectedToken(classifier); | 1289 BindingPatternUnexpectedToken(classifier); |
| 1223 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1290 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1224 | 1291 |
| 1225 case Token::IDENTIFIER: | 1292 case Token::IDENTIFIER: |
| 1293 if (allow_harmony_async_await() && |
| 1294 PeekContextualKeyword(CStrVector("async")) && |
| 1295 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 1296 if (PeekAhead() == Token::FUNCTION) { |
| 1297 Consume(Token::IDENTIFIER); |
| 1298 return this->ParseAsyncFunctionExpression(CHECK_OK); |
| 1299 } |
| 1300 // CoverCallExpressionAndAsyncArrowHead |
| 1301 *is_async = true; |
| 1302 } |
| 1303 /* Falls through */ |
| 1226 case Token::LET: | 1304 case Token::LET: |
| 1227 case Token::STATIC: | 1305 case Token::STATIC: |
| 1228 case Token::YIELD: | 1306 case Token::YIELD: |
| 1229 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1307 case Token::ESCAPED_STRICT_RESERVED_WORD: |
| 1230 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1308 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1231 // Using eval or arguments in this context is OK even in strict mode. | 1309 // Using eval or arguments in this context is OK even in strict mode. |
| 1232 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1310 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 1233 return this->ExpressionFromIdentifier( | 1311 return this->ExpressionFromIdentifier( |
| 1234 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1312 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
| 1235 } | 1313 } |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 | 1560 |
| 1483 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, | 1561 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, |
| 1484 literal_index, pos); | 1562 literal_index, pos); |
| 1485 if (first_spread_index >= 0) { | 1563 if (first_spread_index >= 0) { |
| 1486 result = factory()->NewRewritableExpression(result); | 1564 result = factory()->NewRewritableExpression(result); |
| 1487 Traits::QueueNonPatternForRewriting(result); | 1565 Traits::QueueNonPatternForRewriting(result); |
| 1488 } | 1566 } |
| 1489 return result; | 1567 return result; |
| 1490 } | 1568 } |
| 1491 | 1569 |
| 1492 | |
| 1493 template <class Traits> | 1570 template <class Traits> |
| 1494 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1571 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| 1495 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1572 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await, |
| 1496 ExpressionClassifier* classifier, bool* ok) { | 1573 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
| 1497 Token::Value token = peek(); | 1574 Token::Value token = peek(); |
| 1498 int pos = peek_position(); | 1575 int pos = peek_position(); |
| 1499 | 1576 |
| 1500 // For non computed property names we normalize the name a bit: | 1577 // For non computed property names we normalize the name a bit: |
| 1501 // | 1578 // |
| 1502 // "12" -> 12 | 1579 // "12" -> 12 |
| 1503 // 12.3 -> "12.3" | 1580 // 12.3 -> "12.3" |
| 1504 // 12.30 -> "12.3" | 1581 // 12.30 -> "12.3" |
| 1505 // identifier -> "identifier" | 1582 // identifier -> "identifier" |
| 1506 // | 1583 // |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1531 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1608 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
| 1532 classifier->Accumulate(&computed_name_classifier, | 1609 classifier->Accumulate(&computed_name_classifier, |
| 1533 ExpressionClassifier::ExpressionProductions); | 1610 ExpressionClassifier::ExpressionProductions); |
| 1534 Expect(Token::RBRACK, CHECK_OK); | 1611 Expect(Token::RBRACK, CHECK_OK); |
| 1535 return expression; | 1612 return expression; |
| 1536 } | 1613 } |
| 1537 | 1614 |
| 1538 default: | 1615 default: |
| 1539 *name = ParseIdentifierName(CHECK_OK); | 1616 *name = ParseIdentifierName(CHECK_OK); |
| 1540 scanner()->IsGetOrSet(is_get, is_set); | 1617 scanner()->IsGetOrSet(is_get, is_set); |
| 1618 if (this->IsAwait(*name)) { |
| 1619 *is_await = true; |
| 1620 } |
| 1541 break; | 1621 break; |
| 1542 } | 1622 } |
| 1543 | 1623 |
| 1544 uint32_t index; | 1624 uint32_t index; |
| 1545 return this->IsArrayIndex(*name, &index) | 1625 return this->IsArrayIndex(*name, &index) |
| 1546 ? factory()->NewNumberLiteral(index, pos) | 1626 ? factory()->NewNumberLiteral(index, pos) |
| 1547 : factory()->NewStringLiteral(*name, pos); | 1627 : factory()->NewStringLiteral(*name, pos); |
| 1548 } | 1628 } |
| 1549 | 1629 |
| 1550 | 1630 |
| 1551 template <class Traits> | 1631 template <class Traits> |
| 1552 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1632 typename ParserBase<Traits>::ObjectLiteralPropertyT |
| 1553 ParserBase<Traits>::ParsePropertyDefinition( | 1633 ParserBase<Traits>::ParsePropertyDefinition( |
| 1554 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1634 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 1555 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1635 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 1556 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1636 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
| 1557 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1637 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| 1558 ExpressionT value = this->EmptyExpression(); | 1638 ExpressionT value = this->EmptyExpression(); |
| 1559 bool is_get = false; | 1639 bool is_get = false; |
| 1560 bool is_set = false; | 1640 bool is_set = false; |
| 1641 bool is_await = false; |
| 1561 bool is_generator = Check(Token::MUL); | 1642 bool is_generator = Check(Token::MUL); |
| 1562 | 1643 |
| 1563 Token::Value name_token = peek(); | 1644 Token::Value name_token = peek(); |
| 1645 |
| 1646 bool is_async = allow_harmony_async_await() && !is_generator && |
| 1647 name_token == Token::IDENTIFIER && |
| 1648 PeekContextualKeyword(CStrVector("async")) && |
| 1649 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 1650 PeekAhead() != Token::LPAREN; |
| 1651 |
| 1564 int next_beg_pos = scanner()->peek_location().beg_pos; | 1652 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 1565 int next_end_pos = scanner()->peek_location().end_pos; | 1653 int next_end_pos = scanner()->peek_location().end_pos; |
| 1566 ExpressionT name_expression = | 1654 ExpressionT name_expression = ParsePropertyName( |
| 1567 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, | 1655 name, &is_get, &is_set, &is_await, is_computed_name, classifier, |
| 1568 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1656 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1569 | 1657 |
| 1570 if (fni_ != nullptr && !*is_computed_name) { | 1658 if (fni_ != nullptr && !*is_computed_name) { |
| 1571 this->PushLiteralName(fni_, *name); | 1659 this->PushLiteralName(fni_, *name); |
| 1572 } | 1660 } |
| 1573 | 1661 |
| 1574 if (!in_class && !is_generator) { | 1662 if (!in_class && !is_generator) { |
| 1575 DCHECK(!is_static); | 1663 DCHECK(!is_static); |
| 1576 | 1664 |
| 1577 if (peek() == Token::COLON) { | 1665 if (peek() == Token::COLON) { |
| 1578 // PropertyDefinition | 1666 // PropertyDefinition |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1603 // CoverInitializedName | 1691 // CoverInitializedName |
| 1604 // IdentifierReference Initializer? | 1692 // IdentifierReference Initializer? |
| 1605 if (classifier->duplicate_finder() != nullptr && | 1693 if (classifier->duplicate_finder() != nullptr && |
| 1606 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1694 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 1607 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1695 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1608 } | 1696 } |
| 1609 if (name_token == Token::LET) { | 1697 if (name_token == Token::LET) { |
| 1610 classifier->RecordLetPatternError( | 1698 classifier->RecordLetPatternError( |
| 1611 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1699 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 1612 } | 1700 } |
| 1613 | 1701 if (is_await && is_async_function()) { |
| 1702 classifier->RecordPatternError( |
| 1703 Scanner::Location(next_beg_pos, next_end_pos), |
| 1704 MessageTemplate::kAwaitBindingIdentifier); |
| 1705 } |
| 1614 ExpressionT lhs = this->ExpressionFromIdentifier( | 1706 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 1615 *name, next_beg_pos, next_end_pos, scope_, factory()); | 1707 *name, next_beg_pos, next_end_pos, scope_, factory()); |
| 1616 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 1708 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
| 1617 | 1709 |
| 1618 if (peek() == Token::ASSIGN) { | 1710 if (peek() == Token::ASSIGN) { |
| 1619 Consume(Token::ASSIGN); | 1711 Consume(Token::ASSIGN); |
| 1620 ExpressionClassifier rhs_classifier(this); | 1712 ExpressionClassifier rhs_classifier(this); |
| 1621 ExpressionT rhs = this->ParseAssignmentExpression( | 1713 ExpressionT rhs = this->ParseAssignmentExpression( |
| 1622 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1714 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1623 Traits::RewriteNonPattern(&rhs_classifier, | 1715 Traits::RewriteNonPattern(&rhs_classifier, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1641 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 1733 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
| 1642 false); | 1734 false); |
| 1643 } | 1735 } |
| 1644 } | 1736 } |
| 1645 | 1737 |
| 1646 // Method definitions are never valid in patterns. | 1738 // Method definitions are never valid in patterns. |
| 1647 classifier->RecordPatternError( | 1739 classifier->RecordPatternError( |
| 1648 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1740 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 1649 MessageTemplate::kInvalidDestructuringTarget); | 1741 MessageTemplate::kInvalidDestructuringTarget); |
| 1650 | 1742 |
| 1743 if (is_async) { |
| 1744 DCHECK(!is_generator); |
| 1745 DCHECK(!is_get); |
| 1746 DCHECK(!is_set); |
| 1747 bool dont_care; |
| 1748 name_expression = ParsePropertyName( |
| 1749 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 1750 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1751 } |
| 1752 |
| 1651 if (is_generator || peek() == Token::LPAREN) { | 1753 if (is_generator || peek() == Token::LPAREN) { |
| 1652 // MethodDefinition | 1754 // MethodDefinition |
| 1653 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1755 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 1654 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1756 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 1655 if (!*is_computed_name) { | 1757 if (!*is_computed_name) { |
| 1656 checker->CheckProperty(name_token, kMethodProperty, is_static, | 1758 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 1657 is_generator, | 1759 is_generator, |
| 1658 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1760 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1659 } | 1761 } |
| 1660 | 1762 |
| 1661 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1763 FunctionKind kind = is_generator |
| 1662 : FunctionKind::kConciseMethod; | 1764 ? FunctionKind::kConciseGeneratorMethod |
| 1765 : is_async ? FunctionKind::kAsyncConciseMethod |
| 1766 : FunctionKind::kConciseMethod; |
| 1663 | 1767 |
| 1664 if (in_class && !is_static && this->IsConstructor(*name)) { | 1768 if (in_class && !is_static && this->IsConstructor(*name)) { |
| 1665 *has_seen_constructor = true; | 1769 *has_seen_constructor = true; |
| 1666 kind = has_extends ? FunctionKind::kSubclassConstructor | 1770 kind = has_extends ? FunctionKind::kSubclassConstructor |
| 1667 : FunctionKind::kBaseConstructor; | 1771 : FunctionKind::kBaseConstructor; |
| 1668 } | 1772 } |
| 1669 | 1773 |
| 1670 value = this->ParseFunctionLiteral( | 1774 value = this->ParseFunctionLiteral( |
| 1671 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 1775 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 1672 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 1776 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1690 | 1794 |
| 1691 if (is_get || is_set) { | 1795 if (is_get || is_set) { |
| 1692 // MethodDefinition (Accessors) | 1796 // MethodDefinition (Accessors) |
| 1693 // get PropertyName '(' ')' '{' FunctionBody '}' | 1797 // get PropertyName '(' ')' '{' FunctionBody '}' |
| 1694 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 1798 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
| 1695 *name = this->EmptyIdentifier(); | 1799 *name = this->EmptyIdentifier(); |
| 1696 bool dont_care = false; | 1800 bool dont_care = false; |
| 1697 name_token = peek(); | 1801 name_token = peek(); |
| 1698 | 1802 |
| 1699 name_expression = ParsePropertyName( | 1803 name_expression = ParsePropertyName( |
| 1700 name, &dont_care, &dont_care, is_computed_name, classifier, | 1804 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 1701 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1805 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1702 | 1806 |
| 1703 if (!*is_computed_name) { | 1807 if (!*is_computed_name) { |
| 1704 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 1808 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
| 1705 is_generator, | 1809 is_generator, |
| 1706 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1810 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1707 } | 1811 } |
| 1708 | 1812 |
| 1709 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 1813 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
| 1710 *name, scanner()->location(), kSkipFunctionNameCheck, | 1814 *name, scanner()->location(), kSkipFunctionNameCheck, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 | 1889 |
| 1786 // Computation of literal_index must happen before pre parse bailout. | 1890 // Computation of literal_index must happen before pre parse bailout. |
| 1787 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1891 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1788 | 1892 |
| 1789 return factory()->NewObjectLiteral(properties, | 1893 return factory()->NewObjectLiteral(properties, |
| 1790 literal_index, | 1894 literal_index, |
| 1791 number_of_boilerplate_properties, | 1895 number_of_boilerplate_properties, |
| 1792 pos); | 1896 pos); |
| 1793 } | 1897 } |
| 1794 | 1898 |
| 1795 | |
| 1796 template <class Traits> | 1899 template <class Traits> |
| 1797 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 1900 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| 1798 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, | 1901 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, |
| 1799 bool* ok) { | 1902 ExpressionClassifier* classifier, bool* ok) { |
| 1800 // Arguments :: | 1903 // Arguments :: |
| 1801 // '(' (AssignmentExpression)*[','] ')' | 1904 // '(' (AssignmentExpression)*[','] ')' |
| 1802 | 1905 |
| 1803 Scanner::Location spread_arg = Scanner::Location::invalid(); | 1906 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 1804 typename Traits::Type::ExpressionList result = | 1907 typename Traits::Type::ExpressionList result = |
| 1805 this->NewExpressionList(4, zone_); | 1908 this->NewExpressionList(4, zone_); |
| 1806 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1909 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1807 bool done = (peek() == Token::RPAREN); | 1910 bool done = (peek() == Token::RPAREN); |
| 1808 bool was_unspread = false; | 1911 bool was_unspread = false; |
| 1809 int unspread_sequences_count = 0; | 1912 int unspread_sequences_count = 0; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 } | 1947 } |
| 1845 } | 1948 } |
| 1846 Scanner::Location location = scanner_->location(); | 1949 Scanner::Location location = scanner_->location(); |
| 1847 if (Token::RPAREN != Next()) { | 1950 if (Token::RPAREN != Next()) { |
| 1848 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 1951 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 1849 *ok = false; | 1952 *ok = false; |
| 1850 return this->NullExpressionList(); | 1953 return this->NullExpressionList(); |
| 1851 } | 1954 } |
| 1852 *first_spread_arg_loc = spread_arg; | 1955 *first_spread_arg_loc = spread_arg; |
| 1853 | 1956 |
| 1854 if (spread_arg.IsValid()) { | 1957 if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) { |
| 1855 // Unspread parameter sequences are translated into array literals in the | 1958 // Unspread parameter sequences are translated into array literals in the |
| 1856 // parser. Ensure that the number of materialized literals matches between | 1959 // parser. Ensure that the number of materialized literals matches between |
| 1857 // the parser and preparser | 1960 // the parser and preparser |
| 1858 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 1961 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 1859 } | 1962 } |
| 1860 | 1963 |
| 1861 return result; | 1964 return result; |
| 1862 } | 1965 } |
| 1863 | 1966 |
| 1864 // Precedence = 2 | 1967 // Precedence = 2 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1876 int lhs_beg_pos = peek_position(); | 1979 int lhs_beg_pos = peek_position(); |
| 1877 | 1980 |
| 1878 if (peek() == Token::YIELD && is_generator()) { | 1981 if (peek() == Token::YIELD && is_generator()) { |
| 1879 return this->ParseYieldExpression(classifier, ok); | 1982 return this->ParseYieldExpression(classifier, ok); |
| 1880 } | 1983 } |
| 1881 | 1984 |
| 1882 FuncNameInferrer::State fni_state(fni_); | 1985 FuncNameInferrer::State fni_state(fni_); |
| 1883 ParserBase<Traits>::Checkpoint checkpoint(this); | 1986 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 1884 ExpressionClassifier arrow_formals_classifier(this, | 1987 ExpressionClassifier arrow_formals_classifier(this, |
| 1885 classifier->duplicate_finder()); | 1988 classifier->duplicate_finder()); |
| 1989 |
| 1990 bool is_async = allow_harmony_async_await() && peek() == Token::IDENTIFIER && |
| 1991 PeekContextualKeyword(CStrVector("async")) && |
| 1992 !scanner()->HasAnyLineTerminatorAfterNext(); |
| 1993 |
| 1886 bool parenthesized_formals = peek() == Token::LPAREN; | 1994 bool parenthesized_formals = peek() == Token::LPAREN; |
| 1887 if (!parenthesized_formals) { | 1995 if (!is_async && !parenthesized_formals) { |
| 1888 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 1996 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
| 1889 } | 1997 } |
| 1890 ExpressionT expression = this->ParseConditionalExpression( | 1998 ExpressionT expression = this->ParseConditionalExpression( |
| 1891 accept_IN, &arrow_formals_classifier, CHECK_OK); | 1999 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 2000 |
| 2001 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { |
| 2002 // async Identifier => AsyncConciseBody |
| 2003 IdentifierT name = |
| 2004 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
| 2005 expression = this->ExpressionFromIdentifier( |
| 2006 name, position(), scanner()->location().end_pos, scope_, factory()); |
| 2007 } |
| 2008 |
| 1892 if (peek() == Token::ARROW) { | 2009 if (peek() == Token::ARROW) { |
| 1893 classifier->RecordPatternError(scanner()->peek_location(), | 2010 classifier->RecordPatternError(scanner()->peek_location(), |
| 1894 MessageTemplate::kUnexpectedToken, | 2011 MessageTemplate::kUnexpectedToken, |
| 1895 Token::String(Token::ARROW)); | 2012 Token::String(Token::ARROW)); |
| 1896 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2013 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| 1897 parenthesized_formals, CHECK_OK); | 2014 parenthesized_formals, is_async, CHECK_OK); |
| 1898 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2015 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| 1899 Scope* scope = | 2016 Scope* scope = |
| 1900 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2017 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
| 1901 // Because the arrow's parameters were parsed in the outer scope, any | 2018 // Because the arrow's parameters were parsed in the outer scope, any |
| 1902 // usage flags that might have been triggered there need to be copied | 2019 // usage flags that might have been triggered there need to be copied |
| 1903 // to the arrow scope. | 2020 // to the arrow scope. |
| 1904 scope_->PropagateUsageFlagsToScope(scope); | 2021 scope_->PropagateUsageFlagsToScope(scope); |
| 1905 FormalParametersT parameters(scope); | 2022 FormalParametersT parameters(scope); |
| 1906 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2023 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
| 1907 scope->SetHasNonSimpleParameters(); | 2024 scope->SetHasNonSimpleParameters(); |
| 1908 parameters.is_simple = false; | 2025 parameters.is_simple = false; |
| 1909 } | 2026 } |
| 1910 | 2027 |
| 1911 checkpoint.Restore(¶meters.materialized_literals_count); | 2028 checkpoint.Restore(¶meters.materialized_literals_count); |
| 1912 | 2029 |
| 1913 scope->set_start_position(lhs_beg_pos); | 2030 scope->set_start_position(lhs_beg_pos); |
| 1914 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2031 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 1915 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2032 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
| 1916 &duplicate_loc, CHECK_OK); | 2033 &duplicate_loc, CHECK_OK); |
| 1917 if (duplicate_loc.IsValid()) { | 2034 if (duplicate_loc.IsValid()) { |
| 1918 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2035 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 1919 duplicate_loc); | 2036 duplicate_loc); |
| 1920 } | 2037 } |
| 1921 expression = this->ParseArrowFunctionLiteral( | 2038 expression = this->ParseArrowFunctionLiteral( |
| 1922 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 2039 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); |
| 1923 | 2040 |
| 1924 if (fni_ != nullptr) fni_->Infer(); | 2041 if (fni_ != nullptr) fni_->Infer(); |
| 1925 | 2042 |
| 1926 return expression; | 2043 return expression; |
| 1927 } | 2044 } |
| 1928 | 2045 |
| 1929 if (this->IsValidReferenceExpression(expression)) { | 2046 if (this->IsValidReferenceExpression(expression)) { |
| 1930 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2047 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
| 1931 } | 2048 } |
| 1932 | 2049 |
| 1933 // "expression" was not itself an arrow function parameter list, but it might | 2050 // "expression" was not itself an arrow function parameter list, but it might |
| 1934 // form part of one. Propagate speculative formal parameter error locations. | 2051 // form part of one. Propagate speculative formal parameter error locations. |
| 1935 // Do not merge pending non-pattern expressions yet! | 2052 // Do not merge pending non-pattern expressions yet! |
| 1936 classifier->Accumulate( | 2053 classifier->Accumulate( |
| 1937 &arrow_formals_classifier, | 2054 &arrow_formals_classifier, |
| 1938 ExpressionClassifier::StandardProductions | | 2055 ExpressionClassifier::StandardProductions | |
| 1939 ExpressionClassifier::FormalParametersProductions | | 2056 ExpressionClassifier::FormalParametersProductions | |
| 1940 ExpressionClassifier::CoverInitializedNameProduction, | 2057 ExpressionClassifier::CoverInitializedNameProduction | |
| 2058 ExpressionClassifier::AsyncArrowFormalParametersProduction, |
| 1941 false); | 2059 false); |
| 1942 | 2060 |
| 1943 if (!Token::IsAssignmentOp(peek())) { | 2061 if (!Token::IsAssignmentOp(peek())) { |
| 1944 // Parsed conditional expression only (no assignment). | 2062 // Parsed conditional expression only (no assignment). |
| 1945 // Now pending non-pattern expressions must be merged. | 2063 // Now pending non-pattern expressions must be merged. |
| 1946 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2064 classifier->MergeNonPatterns(&arrow_formals_classifier); |
| 1947 return expression; | 2065 return expression; |
| 1948 } | 2066 } |
| 1949 | 2067 |
| 1950 // Now pending non-pattern expressions must be discarded. | 2068 // Now pending non-pattern expressions must be discarded. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2173 // PostfixExpression | 2291 // PostfixExpression |
| 2174 // 'delete' UnaryExpression | 2292 // 'delete' UnaryExpression |
| 2175 // 'void' UnaryExpression | 2293 // 'void' UnaryExpression |
| 2176 // 'typeof' UnaryExpression | 2294 // 'typeof' UnaryExpression |
| 2177 // '++' UnaryExpression | 2295 // '++' UnaryExpression |
| 2178 // '--' UnaryExpression | 2296 // '--' UnaryExpression |
| 2179 // '+' UnaryExpression | 2297 // '+' UnaryExpression |
| 2180 // '-' UnaryExpression | 2298 // '-' UnaryExpression |
| 2181 // '~' UnaryExpression | 2299 // '~' UnaryExpression |
| 2182 // '!' UnaryExpression | 2300 // '!' UnaryExpression |
| 2301 // [+Await] AwaitExpression[?Yield] |
| 2183 | 2302 |
| 2184 Token::Value op = peek(); | 2303 Token::Value op = peek(); |
| 2185 if (Token::IsUnaryOp(op)) { | 2304 if (Token::IsUnaryOp(op)) { |
| 2186 BindingPatternUnexpectedToken(classifier); | 2305 BindingPatternUnexpectedToken(classifier); |
| 2187 ArrowFormalParametersUnexpectedToken(classifier); | 2306 ArrowFormalParametersUnexpectedToken(classifier); |
| 2188 | 2307 |
| 2189 op = Next(); | 2308 op = Next(); |
| 2190 int pos = position(); | 2309 int pos = position(); |
| 2191 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2310 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2192 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2311 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2218 expression, beg_pos, scanner()->location().end_pos, | 2337 expression, beg_pos, scanner()->location().end_pos, |
| 2219 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2338 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
| 2220 this->MarkExpressionAsAssigned(expression); | 2339 this->MarkExpressionAsAssigned(expression); |
| 2221 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2340 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2222 | 2341 |
| 2223 return factory()->NewCountOperation(op, | 2342 return factory()->NewCountOperation(op, |
| 2224 true /* prefix */, | 2343 true /* prefix */, |
| 2225 expression, | 2344 expression, |
| 2226 position()); | 2345 position()); |
| 2227 | 2346 |
| 2347 } else if (is_async_function() && |
| 2348 PeekContextualKeyword(CStrVector("await"))) { |
| 2349 int beg_pos = peek_position(); |
| 2350 Consume(Token::IDENTIFIER); |
| 2351 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
| 2352 |
| 2353 classifier->RecordFormalParameterInitializerError( |
| 2354 Scanner::Location(beg_pos, scanner()->location().end_pos), |
| 2355 MessageTemplate::kAwaitExpressionFormalParameter); |
| 2356 |
| 2357 return Traits::RewriteAwaitExpression(value, beg_pos); |
| 2228 } else { | 2358 } else { |
| 2229 return this->ParsePostfixExpression(classifier, ok); | 2359 return this->ParsePostfixExpression(classifier, ok); |
| 2230 } | 2360 } |
| 2231 } | 2361 } |
| 2232 | 2362 |
| 2233 | 2363 |
| 2234 template <class Traits> | 2364 template <class Traits> |
| 2235 typename ParserBase<Traits>::ExpressionT | 2365 typename ParserBase<Traits>::ExpressionT |
| 2236 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2366 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2237 bool* ok) { | 2367 bool* ok) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2262 return expression; | 2392 return expression; |
| 2263 } | 2393 } |
| 2264 | 2394 |
| 2265 | 2395 |
| 2266 template <class Traits> | 2396 template <class Traits> |
| 2267 typename ParserBase<Traits>::ExpressionT | 2397 typename ParserBase<Traits>::ExpressionT |
| 2268 ParserBase<Traits>::ParseLeftHandSideExpression( | 2398 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 2269 ExpressionClassifier* classifier, bool* ok) { | 2399 ExpressionClassifier* classifier, bool* ok) { |
| 2270 // LeftHandSideExpression :: | 2400 // LeftHandSideExpression :: |
| 2271 // (NewExpression | MemberExpression) ... | 2401 // (NewExpression | MemberExpression) ... |
| 2272 | 2402 bool is_async = false; |
| 2273 ExpressionT result = | 2403 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
| 2274 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2404 classifier, &is_async, CHECK_OK); |
| 2275 | 2405 |
| 2276 while (true) { | 2406 while (true) { |
| 2277 switch (peek()) { | 2407 switch (peek()) { |
| 2278 case Token::LBRACK: { | 2408 case Token::LBRACK: { |
| 2279 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2409 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2280 BindingPatternUnexpectedToken(classifier); | 2410 BindingPatternUnexpectedToken(classifier); |
| 2281 ArrowFormalParametersUnexpectedToken(classifier); | 2411 ArrowFormalParametersUnexpectedToken(classifier); |
| 2282 Consume(Token::LBRACK); | 2412 Consume(Token::LBRACK); |
| 2283 int pos = position(); | 2413 int pos = position(); |
| 2284 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2414 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
| 2285 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2415 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2286 result = factory()->NewProperty(result, index, pos); | 2416 result = factory()->NewProperty(result, index, pos); |
| 2287 Expect(Token::RBRACK, CHECK_OK); | 2417 Expect(Token::RBRACK, CHECK_OK); |
| 2288 break; | 2418 break; |
| 2289 } | 2419 } |
| 2290 | 2420 |
| 2291 case Token::LPAREN: { | 2421 case Token::LPAREN: { |
| 2422 int pos; |
| 2292 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2423 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2293 BindingPatternUnexpectedToken(classifier); | 2424 BindingPatternUnexpectedToken(classifier); |
| 2294 ArrowFormalParametersUnexpectedToken(classifier); | |
| 2295 | |
| 2296 int pos; | |
| 2297 if (scanner()->current_token() == Token::IDENTIFIER || | 2425 if (scanner()->current_token() == Token::IDENTIFIER || |
| 2298 scanner()->current_token() == Token::SUPER) { | 2426 scanner()->current_token() == Token::SUPER) { |
| 2299 // For call of an identifier we want to report position of | 2427 // For call of an identifier we want to report position of |
| 2300 // the identifier as position of the call in the stack trace. | 2428 // the identifier as position of the call in the stack trace. |
| 2301 pos = position(); | 2429 pos = position(); |
| 2302 } else { | 2430 } else { |
| 2303 // For other kinds of calls we record position of the parenthesis as | 2431 // For other kinds of calls we record position of the parenthesis as |
| 2304 // position of the call. Note that this is extremely important for | 2432 // position of the call. Note that this is extremely important for |
| 2305 // expressions of the form function(){...}() for which call position | 2433 // expressions of the form function(){...}() for which call position |
| 2306 // should not point to the closing brace otherwise it will intersect | 2434 // should not point to the closing brace otherwise it will intersect |
| 2307 // with positions recorded for function literal and confuse debugger. | 2435 // with positions recorded for function literal and confuse debugger. |
| 2308 pos = peek_position(); | 2436 pos = peek_position(); |
| 2309 // Also the trailing parenthesis are a hint that the function will | 2437 // Also the trailing parenthesis are a hint that the function will |
| 2310 // be called immediately. If we happen to have parsed a preceding | 2438 // be called immediately. If we happen to have parsed a preceding |
| 2311 // function literal eagerly, we can also compile it eagerly. | 2439 // function literal eagerly, we can also compile it eagerly. |
| 2312 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2440 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2313 result->AsFunctionLiteral()->set_should_eager_compile(); | 2441 result->AsFunctionLiteral()->set_should_eager_compile(); |
| 2314 } | 2442 } |
| 2315 } | 2443 } |
| 2316 Scanner::Location spread_pos; | 2444 Scanner::Location spread_pos; |
| 2317 typename Traits::Type::ExpressionList args = | 2445 typename Traits::Type::ExpressionList args = |
| 2318 ParseArguments(&spread_pos, classifier, CHECK_OK); | 2446 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); |
| 2447 |
| 2448 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { |
| 2449 if (args->length()) { |
| 2450 // async ( Arguments ) => ... |
| 2451 return Traits::ExpressionListToExpression(args); |
| 2452 } |
| 2453 // async () => ... |
| 2454 return factory()->NewEmptyParentheses(pos); |
| 2455 } |
| 2456 |
| 2457 ArrowFormalParametersUnexpectedToken(classifier); |
| 2319 | 2458 |
| 2320 // Keep track of eval() calls since they disable all local variable | 2459 // Keep track of eval() calls since they disable all local variable |
| 2321 // optimizations. | 2460 // optimizations. |
| 2322 // The calls that need special treatment are the | 2461 // The calls that need special treatment are the |
| 2323 // direct eval calls. These calls are all of the form eval(...), with | 2462 // direct eval calls. These calls are all of the form eval(...), with |
| 2324 // no explicit receiver. | 2463 // no explicit receiver. |
| 2325 // These calls are marked as potentially direct eval calls. Whether | 2464 // These calls are marked as potentially direct eval calls. Whether |
| 2326 // they are actually direct calls to eval is determined at run time. | 2465 // they are actually direct calls to eval is determined at run time. |
| 2327 this->CheckPossibleEvalCall(result, scope_); | 2466 this->CheckPossibleEvalCall(result, scope_); |
| 2328 | 2467 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2367 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2506 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
| 2368 break; | 2507 break; |
| 2369 } | 2508 } |
| 2370 | 2509 |
| 2371 default: | 2510 default: |
| 2372 return result; | 2511 return result; |
| 2373 } | 2512 } |
| 2374 } | 2513 } |
| 2375 } | 2514 } |
| 2376 | 2515 |
| 2377 | |
| 2378 template <class Traits> | 2516 template <class Traits> |
| 2379 typename ParserBase<Traits>::ExpressionT | 2517 typename ParserBase<Traits>::ExpressionT |
| 2380 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( | 2518 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| 2381 ExpressionClassifier* classifier, bool* ok) { | 2519 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
| 2382 // NewExpression :: | 2520 // NewExpression :: |
| 2383 // ('new')+ MemberExpression | 2521 // ('new')+ MemberExpression |
| 2384 // | 2522 // |
| 2385 // NewTarget :: | 2523 // NewTarget :: |
| 2386 // 'new' '.' 'target' | 2524 // 'new' '.' 'target' |
| 2387 | 2525 |
| 2388 // The grammar for new expressions is pretty warped. We can have several 'new' | 2526 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2389 // keywords following each other, and then a MemberExpression. When we see '(' | 2527 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2390 // after the MemberExpression, it's associated with the rightmost unassociated | 2528 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2391 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2529 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2404 ArrowFormalParametersUnexpectedToken(classifier); | 2542 ArrowFormalParametersUnexpectedToken(classifier); |
| 2405 Consume(Token::NEW); | 2543 Consume(Token::NEW); |
| 2406 int new_pos = position(); | 2544 int new_pos = position(); |
| 2407 ExpressionT result = this->EmptyExpression(); | 2545 ExpressionT result = this->EmptyExpression(); |
| 2408 if (peek() == Token::SUPER) { | 2546 if (peek() == Token::SUPER) { |
| 2409 const bool is_new = true; | 2547 const bool is_new = true; |
| 2410 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2548 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 2411 } else if (peek() == Token::PERIOD) { | 2549 } else if (peek() == Token::PERIOD) { |
| 2412 return ParseNewTargetExpression(CHECK_OK); | 2550 return ParseNewTargetExpression(CHECK_OK); |
| 2413 } else { | 2551 } else { |
| 2414 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2552 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, |
| 2553 CHECK_OK); |
| 2415 } | 2554 } |
| 2416 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2555 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2417 if (peek() == Token::LPAREN) { | 2556 if (peek() == Token::LPAREN) { |
| 2418 // NewExpression with arguments. | 2557 // NewExpression with arguments. |
| 2419 Scanner::Location spread_pos; | 2558 Scanner::Location spread_pos; |
| 2420 typename Traits::Type::ExpressionList args = | 2559 typename Traits::Type::ExpressionList args = |
| 2421 this->ParseArguments(&spread_pos, classifier, CHECK_OK); | 2560 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
| 2422 | 2561 |
| 2423 if (spread_pos.IsValid()) { | 2562 if (spread_pos.IsValid()) { |
| 2424 args = Traits::PrepareSpreadArguments(args); | 2563 args = Traits::PrepareSpreadArguments(args); |
| 2425 result = Traits::SpreadCallNew(result, args, new_pos); | 2564 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2426 } else { | 2565 } else { |
| 2427 result = factory()->NewCallNew(result, args, new_pos); | 2566 result = factory()->NewCallNew(result, args, new_pos); |
| 2428 } | 2567 } |
| 2429 // The expression can still continue with . or [ after the arguments. | 2568 // The expression can still continue with . or [ after the arguments. |
| 2430 result = | 2569 result = this->ParseMemberExpressionContinuation(result, is_async, |
| 2431 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2570 classifier, CHECK_OK); |
| 2432 return result; | 2571 return result; |
| 2433 } | 2572 } |
| 2434 // NewExpression without arguments. | 2573 // NewExpression without arguments. |
| 2435 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2574 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2436 new_pos); | 2575 new_pos); |
| 2437 } | 2576 } |
| 2438 // No 'new' or 'super' keyword. | 2577 // No 'new' or 'super' keyword. |
| 2439 return this->ParseMemberExpression(classifier, ok); | 2578 return this->ParseMemberExpression(classifier, is_async, ok); |
| 2440 } | 2579 } |
| 2441 | 2580 |
| 2442 | |
| 2443 template <class Traits> | 2581 template <class Traits> |
| 2444 typename ParserBase<Traits>::ExpressionT | 2582 typename ParserBase<Traits>::ExpressionT |
| 2445 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, | 2583 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
| 2446 bool* ok) { | 2584 bool* is_async, bool* ok) { |
| 2447 // MemberExpression :: | 2585 // MemberExpression :: |
| 2448 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2586 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 2449 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 2587 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 2450 | 2588 |
| 2451 // The '[' Expression ']' and '.' Identifier parts are parsed by | 2589 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 2452 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 2590 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 2453 // caller. | 2591 // caller. |
| 2454 | 2592 |
| 2455 // Parse the initial primary or function expression. | 2593 // Parse the initial primary or function expression. |
| 2456 ExpressionT result = this->EmptyExpression(); | 2594 ExpressionT result = this->EmptyExpression(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 name, function_name_location, | 2631 name, function_name_location, |
| 2494 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 2632 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
| 2495 : kFunctionNameValidityUnknown, | 2633 : kFunctionNameValidityUnknown, |
| 2496 is_generator ? FunctionKind::kGeneratorFunction | 2634 is_generator ? FunctionKind::kGeneratorFunction |
| 2497 : FunctionKind::kNormalFunction, | 2635 : FunctionKind::kNormalFunction, |
| 2498 function_token_position, function_type, language_mode(), CHECK_OK); | 2636 function_token_position, function_type, language_mode(), CHECK_OK); |
| 2499 } else if (peek() == Token::SUPER) { | 2637 } else if (peek() == Token::SUPER) { |
| 2500 const bool is_new = false; | 2638 const bool is_new = false; |
| 2501 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2639 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 2502 } else { | 2640 } else { |
| 2503 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2641 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); |
| 2504 } | 2642 } |
| 2505 | 2643 |
| 2506 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2644 result = |
| 2645 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); |
| 2507 return result; | 2646 return result; |
| 2508 } | 2647 } |
| 2509 | 2648 |
| 2510 | 2649 |
| 2511 template <class Traits> | 2650 template <class Traits> |
| 2512 typename ParserBase<Traits>::ExpressionT | 2651 typename ParserBase<Traits>::ExpressionT |
| 2513 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 2652 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| 2514 ExpressionClassifier* classifier, | 2653 ExpressionClassifier* classifier, |
| 2515 bool* ok) { | 2654 bool* ok) { |
| 2516 Expect(Token::SUPER, CHECK_OK); | 2655 Expect(Token::SUPER, CHECK_OK); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2563 if (!scope_->ReceiverScope()->is_function_scope()) { | 2702 if (!scope_->ReceiverScope()->is_function_scope()) { |
| 2564 ReportMessageAt(scanner()->location(), | 2703 ReportMessageAt(scanner()->location(), |
| 2565 MessageTemplate::kUnexpectedNewTarget); | 2704 MessageTemplate::kUnexpectedNewTarget); |
| 2566 *ok = false; | 2705 *ok = false; |
| 2567 return this->EmptyExpression(); | 2706 return this->EmptyExpression(); |
| 2568 } | 2707 } |
| 2569 | 2708 |
| 2570 return this->NewTargetExpression(scope_, factory(), pos); | 2709 return this->NewTargetExpression(scope_, factory(), pos); |
| 2571 } | 2710 } |
| 2572 | 2711 |
| 2573 | |
| 2574 template <class Traits> | 2712 template <class Traits> |
| 2575 typename ParserBase<Traits>::ExpressionT | 2713 typename ParserBase<Traits>::ExpressionT |
| 2576 ParserBase<Traits>::ParseMemberExpressionContinuation( | 2714 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 2577 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 2715 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 2716 bool* ok) { |
| 2578 // Parses this part of MemberExpression: | 2717 // Parses this part of MemberExpression: |
| 2579 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 2718 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 2580 while (true) { | 2719 while (true) { |
| 2581 switch (peek()) { | 2720 switch (peek()) { |
| 2582 case Token::LBRACK: { | 2721 case Token::LBRACK: { |
| 2722 *is_async = false; |
| 2583 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2723 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2584 BindingPatternUnexpectedToken(classifier); | 2724 BindingPatternUnexpectedToken(classifier); |
| 2585 ArrowFormalParametersUnexpectedToken(classifier); | 2725 ArrowFormalParametersUnexpectedToken(classifier); |
| 2586 | 2726 |
| 2587 Consume(Token::LBRACK); | 2727 Consume(Token::LBRACK); |
| 2588 int pos = position(); | 2728 int pos = position(); |
| 2589 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 2729 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
| 2590 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2730 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2591 expression = factory()->NewProperty(expression, index, pos); | 2731 expression = factory()->NewProperty(expression, index, pos); |
| 2592 if (fni_ != NULL) { | 2732 if (fni_ != NULL) { |
| 2593 this->PushPropertyName(fni_, index); | 2733 this->PushPropertyName(fni_, index); |
| 2594 } | 2734 } |
| 2595 Expect(Token::RBRACK, CHECK_OK); | 2735 Expect(Token::RBRACK, CHECK_OK); |
| 2596 break; | 2736 break; |
| 2597 } | 2737 } |
| 2598 case Token::PERIOD: { | 2738 case Token::PERIOD: { |
| 2739 *is_async = false; |
| 2599 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2740 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2600 BindingPatternUnexpectedToken(classifier); | 2741 BindingPatternUnexpectedToken(classifier); |
| 2601 ArrowFormalParametersUnexpectedToken(classifier); | 2742 ArrowFormalParametersUnexpectedToken(classifier); |
| 2602 | 2743 |
| 2603 Consume(Token::PERIOD); | 2744 Consume(Token::PERIOD); |
| 2604 int pos = position(); | 2745 int pos = position(); |
| 2605 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2746 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 2606 expression = factory()->NewProperty( | 2747 expression = factory()->NewProperty( |
| 2607 expression, factory()->NewStringLiteral(name, pos), pos); | 2748 expression, factory()->NewStringLiteral(name, pos), pos); |
| 2608 if (fni_ != NULL) { | 2749 if (fni_ != NULL) { |
| 2609 this->PushLiteralName(fni_, name); | 2750 this->PushLiteralName(fni_, name); |
| 2610 } | 2751 } |
| 2611 break; | 2752 break; |
| 2612 } | 2753 } |
| 2613 case Token::TEMPLATE_SPAN: | 2754 case Token::TEMPLATE_SPAN: |
| 2614 case Token::TEMPLATE_TAIL: { | 2755 case Token::TEMPLATE_TAIL: { |
| 2756 *is_async = false; |
| 2615 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2757 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2616 BindingPatternUnexpectedToken(classifier); | 2758 BindingPatternUnexpectedToken(classifier); |
| 2617 ArrowFormalParametersUnexpectedToken(classifier); | 2759 ArrowFormalParametersUnexpectedToken(classifier); |
| 2618 int pos; | 2760 int pos; |
| 2619 if (scanner()->current_token() == Token::IDENTIFIER) { | 2761 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 2620 pos = position(); | 2762 pos = position(); |
| 2621 } else { | 2763 } else { |
| 2622 pos = peek_position(); | 2764 pos = peek_position(); |
| 2623 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2765 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2624 // If the tag function looks like an IIFE, set_parenthesized() to | 2766 // If the tag function looks like an IIFE, set_parenthesized() to |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 case Token::IDENTIFIER: | 2914 case Token::IDENTIFIER: |
| 2773 case Token::STATIC: | 2915 case Token::STATIC: |
| 2774 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 2916 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
| 2775 case Token::YIELD: | 2917 case Token::YIELD: |
| 2776 return true; | 2918 return true; |
| 2777 default: | 2919 default: |
| 2778 return false; | 2920 return false; |
| 2779 } | 2921 } |
| 2780 } | 2922 } |
| 2781 | 2923 |
| 2782 | |
| 2783 template <class Traits> | 2924 template <class Traits> |
| 2784 typename ParserBase<Traits>::ExpressionT | 2925 typename ParserBase<Traits>::ExpressionT |
| 2785 ParserBase<Traits>::ParseArrowFunctionLiteral( | 2926 ParserBase<Traits>::ParseArrowFunctionLiteral( |
| 2786 bool accept_IN, const FormalParametersT& formal_parameters, | 2927 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
| 2787 const ExpressionClassifier& formals_classifier, bool* ok) { | 2928 const ExpressionClassifier& formals_classifier, bool* ok) { |
| 2788 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 2929 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 2789 // ASI inserts `;` after arrow parameters if a line terminator is found. | 2930 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 2790 // `=> ...` is never a valid expression, so report as syntax error. | 2931 // `=> ...` is never a valid expression, so report as syntax error. |
| 2791 // If next token is not `=>`, it's a syntax error anyways. | 2932 // If next token is not `=>`, it's a syntax error anyways. |
| 2792 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 2933 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 2793 *ok = false; | 2934 *ok = false; |
| 2794 return this->EmptyExpression(); | 2935 return this->EmptyExpression(); |
| 2795 } | 2936 } |
| 2796 | 2937 |
| 2797 typename Traits::Type::StatementList body; | 2938 typename Traits::Type::StatementList body; |
| 2798 int num_parameters = formal_parameters.scope->num_parameters(); | 2939 int num_parameters = formal_parameters.scope->num_parameters(); |
| 2799 int materialized_literal_count = -1; | 2940 int materialized_literal_count = -1; |
| 2800 int expected_property_count = -1; | 2941 int expected_property_count = -1; |
| 2801 Scanner::Location super_loc; | 2942 Scanner::Location super_loc; |
| 2802 | 2943 |
| 2803 { | 2944 { |
| 2804 typename Traits::Type::Factory function_factory(ast_value_factory()); | 2945 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 2805 FunctionState function_state(&function_state_, &scope_, | 2946 FunctionState function_state( |
| 2806 formal_parameters.scope, kArrowFunction, | 2947 &function_state_, &scope_, formal_parameters.scope, |
| 2807 &function_factory); | 2948 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); |
| 2808 | 2949 |
| 2809 function_state.SkipMaterializedLiterals( | 2950 function_state.SkipMaterializedLiterals( |
| 2810 formal_parameters.materialized_literals_count); | 2951 formal_parameters.materialized_literals_count); |
| 2811 | 2952 |
| 2812 this->ReindexLiterals(formal_parameters); | 2953 this->ReindexLiterals(formal_parameters); |
| 2813 | 2954 |
| 2814 Expect(Token::ARROW, CHECK_OK); | 2955 Expect(Token::ARROW, CHECK_OK); |
| 2815 | 2956 |
| 2816 if (peek() == Token::LBRACE) { | 2957 if (peek() == Token::LBRACE) { |
| 2817 // Multiple statement body | 2958 // Multiple statement body |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3096 has_seen_constructor_ = true; | 3237 has_seen_constructor_ = true; |
| 3097 return; | 3238 return; |
| 3098 } | 3239 } |
| 3099 } | 3240 } |
| 3100 | 3241 |
| 3101 | 3242 |
| 3102 } // namespace internal | 3243 } // namespace internal |
| 3103 } // namespace v8 | 3244 } // namespace v8 |
| 3104 | 3245 |
| 3105 #endif // V8_PARSING_PARSER_BASE_H | 3246 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |