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 |