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 { | |
Dan Ehrenberg
2016/05/05 01:14:40
Cute overloading idiom. We could do this elsewhere
| |
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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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_for_in_(false), | 144 allow_harmony_for_in_(false), |
119 allow_harmony_function_name_(false), | 145 allow_harmony_function_name_(false), |
120 allow_harmony_function_sent_(false) {} | 146 allow_harmony_function_sent_(false), |
147 allow_harmony_async_await_(false) {} | |
121 | 148 |
122 #define ALLOW_ACCESSORS(name) \ | 149 #define ALLOW_ACCESSORS(name) \ |
123 bool allow_##name() const { return allow_##name##_; } \ | 150 bool allow_##name() const { return allow_##name##_; } \ |
124 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 151 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
125 | 152 |
126 #define SCANNER_ACCESSORS(name) \ | 153 #define SCANNER_ACCESSORS(name) \ |
127 bool allow_##name() const { return scanner_->allow_##name(); } \ | 154 bool allow_##name() const { return scanner_->allow_##name(); } \ |
128 void set_allow_##name(bool allow) { \ | 155 void set_allow_##name(bool allow) { \ |
129 return scanner_->set_allow_##name(allow); \ | 156 return scanner_->set_allow_##name(allow); \ |
130 } | 157 } |
131 | 158 |
132 ALLOW_ACCESSORS(lazy); | 159 ALLOW_ACCESSORS(lazy); |
133 ALLOW_ACCESSORS(natives); | 160 ALLOW_ACCESSORS(natives); |
134 ALLOW_ACCESSORS(tailcalls); | 161 ALLOW_ACCESSORS(tailcalls); |
135 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 162 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
136 ALLOW_ACCESSORS(harmony_do_expressions); | 163 ALLOW_ACCESSORS(harmony_do_expressions); |
137 ALLOW_ACCESSORS(harmony_for_in); | 164 ALLOW_ACCESSORS(harmony_for_in); |
138 ALLOW_ACCESSORS(harmony_function_name); | 165 ALLOW_ACCESSORS(harmony_function_name); |
139 ALLOW_ACCESSORS(harmony_function_sent); | 166 ALLOW_ACCESSORS(harmony_function_sent); |
167 ALLOW_ACCESSORS(harmony_async_await); | |
140 SCANNER_ACCESSORS(harmony_exponentiation_operator); | 168 SCANNER_ACCESSORS(harmony_exponentiation_operator); |
141 | 169 |
142 #undef SCANNER_ACCESSORS | 170 #undef SCANNER_ACCESSORS |
143 #undef ALLOW_ACCESSORS | 171 #undef ALLOW_ACCESSORS |
144 | 172 |
145 uintptr_t stack_limit() const { return stack_limit_; } | 173 uintptr_t stack_limit() const { return stack_limit_; } |
146 | 174 |
147 protected: | 175 protected: |
148 enum AllowRestrictedIdentifiers { | 176 enum AllowRestrictedIdentifiers { |
149 kAllowRestrictedIdentifiers, | 177 kAllowRestrictedIdentifiers, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 this_location_ = location; | 293 this_location_ = location; |
266 } | 294 } |
267 void set_super_location(Scanner::Location location) { | 295 void set_super_location(Scanner::Location location) { |
268 super_location_ = location; | 296 super_location_ = location; |
269 } | 297 } |
270 void set_return_location(Scanner::Location location) { | 298 void set_return_location(Scanner::Location location) { |
271 return_location_ = location; | 299 return_location_ = location; |
272 } | 300 } |
273 | 301 |
274 bool is_generator() const { return IsGeneratorFunction(kind_); } | 302 bool is_generator() const { return IsGeneratorFunction(kind_); } |
303 bool is_async_function() const { return IsAsyncFunction(kind_); } | |
275 | 304 |
276 FunctionKind kind() const { return kind_; } | 305 FunctionKind kind() const { return kind_; } |
277 FunctionState* outer() const { return outer_function_state_; } | 306 FunctionState* outer() const { return outer_function_state_; } |
278 | 307 |
279 void set_generator_object_variable( | 308 void set_generator_object_variable( |
280 typename Traits::Type::GeneratorVariable* variable) { | 309 typename Traits::Type::GeneratorVariable* variable) { |
281 DCHECK(variable != NULL); | 310 DCHECK(variable != NULL); |
282 DCHECK(is_generator()); | 311 DCHECK(is_generator()); |
283 generator_object_variable_ = variable; | 312 generator_object_variable_ = variable; |
284 } | 313 } |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
572 return true; | 601 return true; |
573 } | 602 } |
574 return false; | 603 return false; |
575 } | 604 } |
576 | 605 |
577 bool PeekContextualKeyword(Vector<const char> keyword) { | 606 bool PeekContextualKeyword(Vector<const char> keyword) { |
578 return peek() == Token::IDENTIFIER && | 607 return peek() == Token::IDENTIFIER && |
579 scanner()->is_next_contextual_keyword(keyword); | 608 scanner()->is_next_contextual_keyword(keyword); |
580 } | 609 } |
581 | 610 |
611 bool PeekAheadContextualKeyword(Vector<const char> keyword) { | |
612 return PeekAhead() == Token::IDENTIFIER && | |
613 scanner()->is_next_next_contextual_keyword(keyword); | |
614 } | |
615 | |
582 void ExpectMetaProperty(Vector<const char> property_name, | 616 void ExpectMetaProperty(Vector<const char> property_name, |
583 const char* full_name, int pos, bool* ok); | 617 const char* full_name, int pos, bool* ok); |
584 | 618 |
585 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 619 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
586 Expect(Token::IDENTIFIER, ok); | 620 Expect(Token::IDENTIFIER, ok); |
587 if (!*ok) return; | 621 if (!*ok) return; |
588 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 622 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
589 ReportUnexpectedToken(scanner()->current_token()); | 623 ReportUnexpectedToken(scanner()->current_token()); |
590 *ok = false; | 624 *ok = false; |
591 } | 625 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
662 return 0; // 0 precedence will terminate binary expression parsing | 696 return 0; // 0 precedence will terminate binary expression parsing |
663 return Token::Precedence(token); | 697 return Token::Precedence(token); |
664 } | 698 } |
665 | 699 |
666 typename Traits::Type::Factory* factory() { | 700 typename Traits::Type::Factory* factory() { |
667 return function_state_->factory(); | 701 return function_state_->factory(); |
668 } | 702 } |
669 | 703 |
670 LanguageMode language_mode() { return scope_->language_mode(); } | 704 LanguageMode language_mode() { return scope_->language_mode(); } |
671 bool is_generator() const { return function_state_->is_generator(); } | 705 bool is_generator() const { return function_state_->is_generator(); } |
706 bool is_async_function() const { | |
707 return function_state_->is_async_function(); | |
708 } | |
672 | 709 |
673 // Report syntax errors. | 710 // Report syntax errors. |
674 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 711 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
675 ParseErrorType error_type = kSyntaxError) { | 712 ParseErrorType error_type = kSyntaxError) { |
676 Scanner::Location source_location = scanner()->location(); | 713 Scanner::Location source_location = scanner()->location(); |
677 Traits::ReportMessageAt(source_location, message, arg, error_type); | 714 Traits::ReportMessageAt(source_location, message, arg, error_type); |
678 } | 715 } |
679 | 716 |
680 void ReportMessageAt(Scanner::Location location, | 717 void ReportMessageAt(Scanner::Location location, |
681 MessageTemplate::Template message, | 718 MessageTemplate::Template message, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 *ok = false; | 785 *ok = false; |
749 } else if (is_strict(language_mode) && | 786 } else if (is_strict(language_mode) && |
750 !classifier->is_valid_strict_mode_formal_parameters()) { | 787 !classifier->is_valid_strict_mode_formal_parameters()) { |
751 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 788 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); |
752 *ok = false; | 789 *ok = false; |
753 } | 790 } |
754 } | 791 } |
755 | 792 |
756 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 793 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
757 ExpressionT expr, | 794 ExpressionT expr, |
758 bool parenthesized_formals, bool* ok) { | 795 bool parenthesized_formals, bool is_async, |
796 bool* ok) { | |
759 if (classifier->is_valid_binding_pattern()) { | 797 if (classifier->is_valid_binding_pattern()) { |
760 // A simple arrow formal parameter: IDENTIFIER => BODY. | 798 // A simple arrow formal parameter: IDENTIFIER => BODY. |
761 if (!this->IsIdentifier(expr)) { | 799 if (!this->IsIdentifier(expr)) { |
762 Traits::ReportMessageAt(scanner()->location(), | 800 Traits::ReportMessageAt(scanner()->location(), |
763 MessageTemplate::kUnexpectedToken, | 801 MessageTemplate::kUnexpectedToken, |
764 Token::String(scanner()->current_token())); | 802 Token::String(scanner()->current_token())); |
765 *ok = false; | 803 *ok = false; |
766 } | 804 } |
767 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 805 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
768 // If after parsing the expr, we see an error but the expression is | 806 // If after parsing the expr, we see an error but the expression is |
769 // neither a valid binding pattern nor a valid parenthesized formal | 807 // neither a valid binding pattern nor a valid parenthesized formal |
770 // parameter list, show the "arrow formal parameters" error if the formals | 808 // parameter list, show the "arrow formal parameters" error if the formals |
771 // started with a parenthesis, and the binding pattern error otherwise. | 809 // started with a parenthesis, and the binding pattern error otherwise. |
772 const typename ExpressionClassifier::Error& error = | 810 const typename ExpressionClassifier::Error& error = |
773 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 811 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
774 : classifier->binding_pattern_error(); | 812 : classifier->binding_pattern_error(); |
775 ReportClassifierError(error); | 813 ReportClassifierError(error); |
776 *ok = false; | 814 *ok = false; |
777 } | 815 } |
816 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | |
817 const typename ExpressionClassifier::Error& error = | |
818 classifier->async_arrow_formal_parameters_error(); | |
819 ReportClassifierError(error); | |
820 *ok = false; | |
821 } | |
778 } | 822 } |
779 | 823 |
780 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 824 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
781 if (!classifier->is_valid_let_pattern()) { | 825 if (!classifier->is_valid_let_pattern()) { |
782 ReportClassifierError(classifier->let_pattern_error()); | 826 ReportClassifierError(classifier->let_pattern_error()); |
783 *ok = false; | 827 *ok = false; |
784 } | 828 } |
785 } | 829 } |
786 | 830 |
787 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, | 831 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
841 return ParseIdentifierOrStrictReservedWord(this->is_generator(), | 885 return ParseIdentifierOrStrictReservedWord(this->is_generator(), |
842 is_strict_reserved, ok); | 886 is_strict_reserved, ok); |
843 } | 887 } |
844 | 888 |
845 IdentifierT ParseIdentifierName(bool* ok); | 889 IdentifierT ParseIdentifierName(bool* ok); |
846 | 890 |
847 ExpressionT ParseRegExpLiteral(bool seen_equal, | 891 ExpressionT ParseRegExpLiteral(bool seen_equal, |
848 ExpressionClassifier* classifier, bool* ok); | 892 ExpressionClassifier* classifier, bool* ok); |
849 | 893 |
850 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 894 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
851 bool* ok); | 895 bool* is_async, bool* ok); |
896 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
897 bool* ok) { | |
898 bool is_async; | |
899 return ParsePrimaryExpression(classifier, &is_async, ok); | |
900 } | |
852 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 901 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
853 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 902 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
854 bool* ok); | 903 bool* ok); |
855 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 904 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
856 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 905 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
857 bool* is_computed_name, | 906 bool* is_await, bool* is_computed_name, |
858 ExpressionClassifier* classifier, bool* ok); | 907 ExpressionClassifier* classifier, bool* ok); |
859 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 908 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
860 ObjectLiteralPropertyT ParsePropertyDefinition( | 909 ObjectLiteralPropertyT ParsePropertyDefinition( |
861 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 910 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
862 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 911 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
863 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 912 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
864 typename Traits::Type::ExpressionList ParseArguments( | 913 typename Traits::Type::ExpressionList ParseArguments( |
914 Scanner::Location* first_spread_pos, bool maybe_arrow, | |
915 ExpressionClassifier* classifier, bool* ok); | |
916 typename Traits::Type::ExpressionList ParseArguments( | |
865 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 917 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
866 bool* ok); | 918 bool* ok) { |
919 return ParseArguments(first_spread_pos, false, classifier, ok); | |
920 } | |
867 | 921 |
868 ExpressionT ParseAssignmentExpression(bool accept_IN, | 922 ExpressionT ParseAssignmentExpression(bool accept_IN, |
869 ExpressionClassifier* classifier, | 923 ExpressionClassifier* classifier, |
870 bool* ok); | 924 bool* ok); |
871 ExpressionT ParseYieldExpression(bool accept_IN, | 925 ExpressionT ParseYieldExpression(bool accept_IN, |
872 ExpressionClassifier* classifier, bool* ok); | 926 ExpressionClassifier* classifier, bool* ok); |
873 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 927 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
874 bool* ok); | 928 bool* ok); |
875 ExpressionT ParseConditionalExpression(bool accept_IN, | 929 ExpressionT ParseConditionalExpression(bool accept_IN, |
876 ExpressionClassifier* classifier, | 930 ExpressionClassifier* classifier, |
877 bool* ok); | 931 bool* ok); |
878 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 932 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
879 ExpressionClassifier* classifier, bool* ok); | 933 ExpressionClassifier* classifier, bool* ok); |
880 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 934 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
881 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 935 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
882 bool* ok); | 936 bool* ok); |
883 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 937 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
884 bool* ok); | 938 bool* ok); |
885 ExpressionT ParseMemberWithNewPrefixesExpression( | 939 ExpressionT ParseMemberWithNewPrefixesExpression( |
886 ExpressionClassifier* classifier, bool* ok); | 940 ExpressionClassifier* classifier, bool* is_async, bool* ok); |
887 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | 941 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, |
942 bool* is_async, bool* ok); | |
888 ExpressionT ParseMemberExpressionContinuation( | 943 ExpressionT ParseMemberExpressionContinuation( |
889 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | 944 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
945 bool* ok); | |
890 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 946 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
891 const FormalParametersT& parameters, | 947 const FormalParametersT& parameters, |
948 bool is_async, | |
892 const ExpressionClassifier& classifier, | 949 const ExpressionClassifier& classifier, |
893 bool* ok); | 950 bool* ok); |
894 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 951 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
895 ExpressionClassifier* classifier, bool* ok); | 952 ExpressionClassifier* classifier, bool* ok); |
896 void AddTemplateExpression(ExpressionT); | 953 void AddTemplateExpression(ExpressionT); |
897 ExpressionT ParseSuperExpression(bool is_new, | 954 ExpressionT ParseSuperExpression(bool is_new, |
898 ExpressionClassifier* classifier, bool* ok); | 955 ExpressionClassifier* classifier, bool* ok); |
899 ExpressionT ParseNewTargetExpression(bool* ok); | 956 ExpressionT ParseNewTargetExpression(bool* ok); |
900 | 957 |
901 void ParseFormalParameter(FormalParametersT* parameters, | 958 void ParseFormalParameter(FormalParametersT* parameters, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1024 bool stack_overflow_; | 1081 bool stack_overflow_; |
1025 | 1082 |
1026 bool allow_lazy_; | 1083 bool allow_lazy_; |
1027 bool allow_natives_; | 1084 bool allow_natives_; |
1028 bool allow_tailcalls_; | 1085 bool allow_tailcalls_; |
1029 bool allow_harmony_restrictive_declarations_; | 1086 bool allow_harmony_restrictive_declarations_; |
1030 bool allow_harmony_do_expressions_; | 1087 bool allow_harmony_do_expressions_; |
1031 bool allow_harmony_for_in_; | 1088 bool allow_harmony_for_in_; |
1032 bool allow_harmony_function_name_; | 1089 bool allow_harmony_function_name_; |
1033 bool allow_harmony_function_sent_; | 1090 bool allow_harmony_function_sent_; |
1091 bool allow_harmony_async_await_; | |
1034 }; | 1092 }; |
1035 | 1093 |
1036 template <class Traits> | 1094 template <class Traits> |
1037 ParserBase<Traits>::FunctionState::FunctionState( | 1095 ParserBase<Traits>::FunctionState::FunctionState( |
1038 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 1096 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
1039 FunctionKind kind, typename Traits::Type::Factory* factory) | 1097 FunctionKind kind, typename Traits::Type::Factory* factory) |
1040 : next_materialized_literal_index_(0), | 1098 : next_materialized_literal_index_(0), |
1041 expected_property_count_(0), | 1099 expected_property_count_(0), |
1042 this_location_(Scanner::Location::invalid()), | 1100 this_location_(Scanner::Location::invalid()), |
1043 return_location_(Scanner::Location::invalid()), | 1101 return_location_(Scanner::Location::invalid()), |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1184 } | 1242 } |
1185 if (this->IsArguments(name)) { | 1243 if (this->IsArguments(name)) { |
1186 scope_->RecordArgumentsUsage(); | 1244 scope_->RecordArgumentsUsage(); |
1187 classifier->RecordStrictModeFormalParameterError( | 1245 classifier->RecordStrictModeFormalParameterError( |
1188 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1246 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1189 if (is_strict(language_mode())) { | 1247 if (is_strict(language_mode())) { |
1190 classifier->RecordBindingPatternError( | 1248 classifier->RecordBindingPatternError( |
1191 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1249 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1192 } | 1250 } |
1193 } | 1251 } |
1252 if (this->IsAwait(name)) { | |
1253 if (is_async_function()) { | |
1254 classifier->RecordPatternError( | |
1255 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | |
1256 } | |
1257 classifier->RecordAsyncArrowFormalParametersError( | |
1258 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | |
Dan Ehrenberg
2016/05/05 01:14:40
"await is only treated as a FutureReservedWord whe
caitp (gmail)
2016/05/05 01:36:57
Ideally we'd have a variety of versions of this me
| |
1259 } | |
1194 | 1260 |
1195 if (classifier->duplicate_finder() != nullptr && | 1261 if (classifier->duplicate_finder() != nullptr && |
1196 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1262 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
1197 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1263 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
1198 } | 1264 } |
1199 return name; | 1265 return name; |
1200 } else if (is_sloppy(language_mode()) && | 1266 } else if (is_sloppy(language_mode()) && |
1201 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1267 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
1202 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1268 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
1203 next == Token::LET || next == Token::STATIC || | 1269 next == Token::LET || next == Token::STATIC || |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1302 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
1237 *is_strict_reserved = true; | 1303 *is_strict_reserved = true; |
1238 } else { | 1304 } else { |
1239 ReportUnexpectedToken(next); | 1305 ReportUnexpectedToken(next); |
1240 *ok = false; | 1306 *ok = false; |
1241 return Traits::EmptyIdentifier(); | 1307 return Traits::EmptyIdentifier(); |
1242 } | 1308 } |
1243 | 1309 |
1244 IdentifierT name = this->GetSymbol(scanner()); | 1310 IdentifierT name = this->GetSymbol(scanner()); |
1245 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1311 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1312 | |
Dan Ehrenberg
2016/05/05 01:14:40
Spurious whitespace change.
caitp (gmail)
2016/05/05 01:36:57
Acknowledged.
| |
1246 return name; | 1313 return name; |
1247 } | 1314 } |
1248 | 1315 |
1249 template <class Traits> | 1316 template <class Traits> |
1250 typename ParserBase<Traits>::IdentifierT | 1317 typename ParserBase<Traits>::IdentifierT |
1251 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1318 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1252 Token::Value next = Next(); | 1319 Token::Value next = Next(); |
1253 if (next != Token::IDENTIFIER && next != Token::ENUM && | 1320 if (next != Token::IDENTIFIER && next != Token::ENUM && |
1254 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && | 1321 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
1255 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && | 1322 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1299 #define DUMMY ) // to make indentation work | 1366 #define DUMMY ) // to make indentation work |
1300 #undef DUMMY | 1367 #undef DUMMY |
1301 | 1368 |
1302 // Used in functions where the return type is not ExpressionT. | 1369 // Used in functions where the return type is not ExpressionT. |
1303 #define CHECK_OK_CUSTOM(x) ok); \ | 1370 #define CHECK_OK_CUSTOM(x) ok); \ |
1304 if (!*ok) return this->x(); \ | 1371 if (!*ok) return this->x(); \ |
1305 ((void)0 | 1372 ((void)0 |
1306 #define DUMMY ) // to make indentation work | 1373 #define DUMMY ) // to make indentation work |
1307 #undef DUMMY | 1374 #undef DUMMY |
1308 | 1375 |
1309 | |
Dan Ehrenberg
2016/05/05 01:14:40
Spurious whitespace change.
| |
1310 template <class Traits> | 1376 template <class Traits> |
1311 typename ParserBase<Traits>::ExpressionT | 1377 typename ParserBase<Traits>::ExpressionT |
1312 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, | 1378 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
1313 bool* ok) { | 1379 bool* is_async, bool* ok) { |
1314 // PrimaryExpression :: | 1380 // PrimaryExpression :: |
1315 // 'this' | 1381 // 'this' |
1316 // 'null' | 1382 // 'null' |
1317 // 'true' | 1383 // 'true' |
1318 // 'false' | 1384 // 'false' |
1319 // Identifier | 1385 // Identifier |
1320 // Number | 1386 // Number |
1321 // String | 1387 // String |
1322 // ArrayLiteral | 1388 // ArrayLiteral |
1323 // ObjectLiteral | 1389 // ObjectLiteral |
1324 // RegExpLiteral | 1390 // RegExpLiteral |
1325 // ClassLiteral | 1391 // ClassLiteral |
1326 // '(' Expression ')' | 1392 // '(' Expression ')' |
1327 // TemplateLiteral | 1393 // TemplateLiteral |
1328 // do Block | 1394 // do Block |
1395 // AsyncFunctionExpression | |
1329 | 1396 |
1330 int beg_pos = peek_position(); | 1397 int beg_pos = peek_position(); |
1331 switch (peek()) { | 1398 switch (peek()) { |
1332 case Token::THIS: { | 1399 case Token::THIS: { |
1333 BindingPatternUnexpectedToken(classifier); | 1400 BindingPatternUnexpectedToken(classifier); |
1334 Consume(Token::THIS); | 1401 Consume(Token::THIS); |
1335 return this->ThisExpression(scope_, factory(), beg_pos); | 1402 return this->ThisExpression(scope_, factory(), beg_pos); |
1336 } | 1403 } |
1337 | 1404 |
1338 case Token::NULL_LITERAL: | 1405 case Token::NULL_LITERAL: |
1339 case Token::TRUE_LITERAL: | 1406 case Token::TRUE_LITERAL: |
1340 case Token::FALSE_LITERAL: | 1407 case Token::FALSE_LITERAL: |
1341 BindingPatternUnexpectedToken(classifier); | 1408 BindingPatternUnexpectedToken(classifier); |
1342 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1409 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1343 case Token::SMI: | 1410 case Token::SMI: |
1344 case Token::NUMBER: | 1411 case Token::NUMBER: |
1345 BindingPatternUnexpectedToken(classifier); | 1412 BindingPatternUnexpectedToken(classifier); |
1346 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1413 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1347 | 1414 |
1348 case Token::IDENTIFIER: | 1415 case Token::IDENTIFIER: |
1416 if (allow_harmony_async_await() && | |
1417 PeekContextualKeyword(CStrVector("async")) && | |
1418 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
1419 if (PeekAhead() == Token::FUNCTION) { | |
1420 Consume(Token::IDENTIFIER); | |
1421 return this->ParseAsyncFunctionExpression(CHECK_OK); | |
1422 } | |
1423 // CoverCallExpressionAndAsyncArrowHead | |
1424 *is_async = true; | |
1425 } | |
1426 /* Falls through */ | |
1349 case Token::LET: | 1427 case Token::LET: |
1350 case Token::STATIC: | 1428 case Token::STATIC: |
1351 case Token::YIELD: | 1429 case Token::YIELD: |
1352 case Token::AWAIT: | 1430 case Token::AWAIT: |
1353 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1431 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1354 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1432 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1355 // Using eval or arguments in this context is OK even in strict mode. | 1433 // Using eval or arguments in this context is OK even in strict mode. |
1356 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1434 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
1357 return this->ExpressionFromIdentifier( | 1435 return this->ExpressionFromIdentifier( |
1358 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1436 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1609 | 1687 |
1610 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, | 1688 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, |
1611 literal_index, pos); | 1689 literal_index, pos); |
1612 if (first_spread_index >= 0) { | 1690 if (first_spread_index >= 0) { |
1613 result = factory()->NewRewritableExpression(result); | 1691 result = factory()->NewRewritableExpression(result); |
1614 Traits::QueueNonPatternForRewriting(result); | 1692 Traits::QueueNonPatternForRewriting(result); |
1615 } | 1693 } |
1616 return result; | 1694 return result; |
1617 } | 1695 } |
1618 | 1696 |
1619 | |
1620 template <class Traits> | 1697 template <class Traits> |
1621 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1698 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
1622 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1699 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await, |
1623 ExpressionClassifier* classifier, bool* ok) { | 1700 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
1624 Token::Value token = peek(); | 1701 Token::Value token = peek(); |
1625 int pos = peek_position(); | 1702 int pos = peek_position(); |
1626 | 1703 |
1627 // For non computed property names we normalize the name a bit: | 1704 // For non computed property names we normalize the name a bit: |
1628 // | 1705 // |
1629 // "12" -> 12 | 1706 // "12" -> 12 |
1630 // 12.3 -> "12.3" | 1707 // 12.3 -> "12.3" |
1631 // 12.30 -> "12.3" | 1708 // 12.30 -> "12.3" |
1632 // identifier -> "identifier" | 1709 // identifier -> "identifier" |
1633 // | 1710 // |
(...skipping 24 matching lines...) Expand all Loading... | |
1658 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1735 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
1659 classifier->Accumulate(&computed_name_classifier, | 1736 classifier->Accumulate(&computed_name_classifier, |
1660 ExpressionClassifier::ExpressionProductions); | 1737 ExpressionClassifier::ExpressionProductions); |
1661 Expect(Token::RBRACK, CHECK_OK); | 1738 Expect(Token::RBRACK, CHECK_OK); |
1662 return expression; | 1739 return expression; |
1663 } | 1740 } |
1664 | 1741 |
1665 default: | 1742 default: |
1666 *name = ParseIdentifierName(CHECK_OK); | 1743 *name = ParseIdentifierName(CHECK_OK); |
1667 scanner()->IsGetOrSet(is_get, is_set); | 1744 scanner()->IsGetOrSet(is_get, is_set); |
1745 if (this->IsAwait(*name)) { | |
1746 *is_await = true; | |
1747 } | |
1668 break; | 1748 break; |
1669 } | 1749 } |
1670 | 1750 |
1671 uint32_t index; | 1751 uint32_t index; |
1672 return this->IsArrayIndex(*name, &index) | 1752 return this->IsArrayIndex(*name, &index) |
1673 ? factory()->NewNumberLiteral(index, pos) | 1753 ? factory()->NewNumberLiteral(index, pos) |
1674 : factory()->NewStringLiteral(*name, pos); | 1754 : factory()->NewStringLiteral(*name, pos); |
1675 } | 1755 } |
1676 | 1756 |
1677 | 1757 |
1678 template <class Traits> | 1758 template <class Traits> |
1679 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1759 typename ParserBase<Traits>::ObjectLiteralPropertyT |
1680 ParserBase<Traits>::ParsePropertyDefinition( | 1760 ParserBase<Traits>::ParsePropertyDefinition( |
1681 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1761 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1682 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1762 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
1683 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1763 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
1684 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1764 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
1685 ExpressionT value = this->EmptyExpression(); | 1765 ExpressionT value = this->EmptyExpression(); |
1686 bool is_get = false; | 1766 bool is_get = false; |
1687 bool is_set = false; | 1767 bool is_set = false; |
1768 bool is_await = false; | |
1688 bool is_generator = Check(Token::MUL); | 1769 bool is_generator = Check(Token::MUL); |
1689 | 1770 |
1690 Token::Value name_token = peek(); | 1771 Token::Value name_token = peek(); |
1772 | |
1773 bool is_async = allow_harmony_async_await() && !is_generator && | |
1774 name_token == Token::IDENTIFIER && | |
1775 PeekContextualKeyword(CStrVector("async")) && | |
1776 !scanner()->HasAnyLineTerminatorAfterNext() && | |
1777 PeekAhead() != Token::LPAREN; | |
1778 | |
1691 int next_beg_pos = scanner()->peek_location().beg_pos; | 1779 int next_beg_pos = scanner()->peek_location().beg_pos; |
1692 int next_end_pos = scanner()->peek_location().end_pos; | 1780 int next_end_pos = scanner()->peek_location().end_pos; |
1693 ExpressionT name_expression = | 1781 ExpressionT name_expression = ParsePropertyName( |
1694 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, | 1782 name, &is_get, &is_set, &is_await, is_computed_name, classifier, |
1695 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1783 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1696 | 1784 |
1697 if (fni_ != nullptr && !*is_computed_name) { | 1785 if (fni_ != nullptr && !*is_computed_name) { |
1698 this->PushLiteralName(fni_, *name); | 1786 this->PushLiteralName(fni_, *name); |
1699 } | 1787 } |
1700 | 1788 |
1701 if (!in_class && !is_generator) { | 1789 if (!in_class && !is_generator) { |
1702 DCHECK(!is_static); | 1790 DCHECK(!is_static); |
1703 | 1791 |
1704 if (peek() == Token::COLON) { | 1792 if (peek() == Token::COLON) { |
1705 // PropertyDefinition | 1793 // PropertyDefinition |
(...skipping 24 matching lines...) Expand all Loading... | |
1730 // CoverInitializedName | 1818 // CoverInitializedName |
1731 // IdentifierReference Initializer? | 1819 // IdentifierReference Initializer? |
1732 if (classifier->duplicate_finder() != nullptr && | 1820 if (classifier->duplicate_finder() != nullptr && |
1733 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1821 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
1734 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1822 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
1735 } | 1823 } |
1736 if (name_token == Token::LET) { | 1824 if (name_token == Token::LET) { |
1737 classifier->RecordLetPatternError( | 1825 classifier->RecordLetPatternError( |
1738 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1826 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1739 } | 1827 } |
1740 | 1828 if (is_await && is_async_function()) { |
1829 classifier->RecordPatternError( | |
1830 Scanner::Location(next_beg_pos, next_end_pos), | |
1831 MessageTemplate::kAwaitBindingIdentifier); | |
1832 } | |
1741 ExpressionT lhs = this->ExpressionFromIdentifier( | 1833 ExpressionT lhs = this->ExpressionFromIdentifier( |
1742 *name, next_beg_pos, next_end_pos, scope_, factory()); | 1834 *name, next_beg_pos, next_end_pos, scope_, factory()); |
1743 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 1835 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
1744 | 1836 |
1745 if (peek() == Token::ASSIGN) { | 1837 if (peek() == Token::ASSIGN) { |
1746 Consume(Token::ASSIGN); | 1838 Consume(Token::ASSIGN); |
1747 ExpressionClassifier rhs_classifier(this); | 1839 ExpressionClassifier rhs_classifier(this); |
1748 ExpressionT rhs = this->ParseAssignmentExpression( | 1840 ExpressionT rhs = this->ParseAssignmentExpression( |
1749 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1841 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1750 Traits::RewriteNonPattern(&rhs_classifier, | 1842 Traits::RewriteNonPattern(&rhs_classifier, |
(...skipping 17 matching lines...) Expand all Loading... | |
1768 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 1860 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
1769 false); | 1861 false); |
1770 } | 1862 } |
1771 } | 1863 } |
1772 | 1864 |
1773 // Method definitions are never valid in patterns. | 1865 // Method definitions are never valid in patterns. |
1774 classifier->RecordPatternError( | 1866 classifier->RecordPatternError( |
1775 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1867 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
1776 MessageTemplate::kInvalidDestructuringTarget); | 1868 MessageTemplate::kInvalidDestructuringTarget); |
1777 | 1869 |
1870 if (is_async) { | |
1871 DCHECK(!is_generator); | |
1872 DCHECK(!is_get); | |
1873 DCHECK(!is_set); | |
1874 bool dont_care; | |
1875 name_expression = ParsePropertyName( | |
1876 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, | |
1877 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
1878 } | |
1879 | |
1778 if (is_generator || peek() == Token::LPAREN) { | 1880 if (is_generator || peek() == Token::LPAREN) { |
1779 // MethodDefinition | 1881 // MethodDefinition |
1780 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1882 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1781 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1883 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1782 if (!*is_computed_name) { | 1884 if (!*is_computed_name) { |
1783 checker->CheckProperty(name_token, kMethodProperty, is_static, | 1885 checker->CheckProperty(name_token, kMethodProperty, is_static, |
1784 is_generator, | 1886 is_generator, |
1785 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1887 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1786 } | 1888 } |
1787 | 1889 |
1788 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1890 FunctionKind kind = is_generator |
1789 : FunctionKind::kConciseMethod; | 1891 ? FunctionKind::kConciseGeneratorMethod |
1892 : is_async ? FunctionKind::kAsyncConciseMethod | |
1893 : FunctionKind::kConciseMethod; | |
1790 | 1894 |
1791 if (in_class && !is_static && this->IsConstructor(*name)) { | 1895 if (in_class && !is_static && this->IsConstructor(*name)) { |
1792 *has_seen_constructor = true; | 1896 *has_seen_constructor = true; |
1793 kind = has_extends ? FunctionKind::kSubclassConstructor | 1897 kind = has_extends ? FunctionKind::kSubclassConstructor |
1794 : FunctionKind::kBaseConstructor; | 1898 : FunctionKind::kBaseConstructor; |
1795 } | 1899 } |
1796 | 1900 |
1797 value = this->ParseFunctionLiteral( | 1901 value = this->ParseFunctionLiteral( |
1798 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 1902 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
1799 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 1903 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
(...skipping 17 matching lines...) Expand all Loading... | |
1817 | 1921 |
1818 if (is_get || is_set) { | 1922 if (is_get || is_set) { |
1819 // MethodDefinition (Accessors) | 1923 // MethodDefinition (Accessors) |
1820 // get PropertyName '(' ')' '{' FunctionBody '}' | 1924 // get PropertyName '(' ')' '{' FunctionBody '}' |
1821 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 1925 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
1822 *name = this->EmptyIdentifier(); | 1926 *name = this->EmptyIdentifier(); |
1823 bool dont_care = false; | 1927 bool dont_care = false; |
1824 name_token = peek(); | 1928 name_token = peek(); |
1825 | 1929 |
1826 name_expression = ParsePropertyName( | 1930 name_expression = ParsePropertyName( |
1827 name, &dont_care, &dont_care, is_computed_name, classifier, | 1931 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
1828 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1932 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1829 | 1933 |
1830 if (!*is_computed_name) { | 1934 if (!*is_computed_name) { |
1831 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 1935 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
1832 is_generator, | 1936 is_generator, |
1833 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1937 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1834 } | 1938 } |
1835 | 1939 |
1836 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 1940 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
1837 *name, scanner()->location(), kSkipFunctionNameCheck, | 1941 *name, scanner()->location(), kSkipFunctionNameCheck, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1912 | 2016 |
1913 // Computation of literal_index must happen before pre parse bailout. | 2017 // Computation of literal_index must happen before pre parse bailout. |
1914 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2018 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1915 | 2019 |
1916 return factory()->NewObjectLiteral(properties, | 2020 return factory()->NewObjectLiteral(properties, |
1917 literal_index, | 2021 literal_index, |
1918 number_of_boilerplate_properties, | 2022 number_of_boilerplate_properties, |
1919 pos); | 2023 pos); |
1920 } | 2024 } |
1921 | 2025 |
1922 | |
1923 template <class Traits> | 2026 template <class Traits> |
1924 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2027 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
1925 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, | 2028 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, |
1926 bool* ok) { | 2029 ExpressionClassifier* classifier, bool* ok) { |
1927 // Arguments :: | 2030 // Arguments :: |
1928 // '(' (AssignmentExpression)*[','] ')' | 2031 // '(' (AssignmentExpression)*[','] ')' |
1929 | 2032 |
1930 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2033 Scanner::Location spread_arg = Scanner::Location::invalid(); |
1931 typename Traits::Type::ExpressionList result = | 2034 typename Traits::Type::ExpressionList result = |
1932 this->NewExpressionList(4, zone_); | 2035 this->NewExpressionList(4, zone_); |
1933 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2036 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1934 bool done = (peek() == Token::RPAREN); | 2037 bool done = (peek() == Token::RPAREN); |
1935 bool was_unspread = false; | 2038 bool was_unspread = false; |
1936 int unspread_sequences_count = 0; | 2039 int unspread_sequences_count = 0; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1972 } | 2075 } |
1973 } | 2076 } |
1974 Scanner::Location location = scanner_->location(); | 2077 Scanner::Location location = scanner_->location(); |
1975 if (Token::RPAREN != Next()) { | 2078 if (Token::RPAREN != Next()) { |
1976 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2079 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
1977 *ok = false; | 2080 *ok = false; |
1978 return this->NullExpressionList(); | 2081 return this->NullExpressionList(); |
1979 } | 2082 } |
1980 *first_spread_arg_loc = spread_arg; | 2083 *first_spread_arg_loc = spread_arg; |
1981 | 2084 |
1982 if (spread_arg.IsValid()) { | 2085 if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) { |
1983 // Unspread parameter sequences are translated into array literals in the | 2086 // Unspread parameter sequences are translated into array literals in the |
1984 // parser. Ensure that the number of materialized literals matches between | 2087 // parser. Ensure that the number of materialized literals matches between |
1985 // the parser and preparser | 2088 // the parser and preparser |
1986 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2089 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
1987 } | 2090 } |
1988 | 2091 |
1989 return result; | 2092 return result; |
1990 } | 2093 } |
1991 | 2094 |
1992 // Precedence = 2 | 2095 // Precedence = 2 |
(...skipping 11 matching lines...) Expand all Loading... | |
2004 int lhs_beg_pos = peek_position(); | 2107 int lhs_beg_pos = peek_position(); |
2005 | 2108 |
2006 if (peek() == Token::YIELD && is_generator()) { | 2109 if (peek() == Token::YIELD && is_generator()) { |
2007 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2110 return this->ParseYieldExpression(accept_IN, classifier, ok); |
2008 } | 2111 } |
2009 | 2112 |
2010 FuncNameInferrer::State fni_state(fni_); | 2113 FuncNameInferrer::State fni_state(fni_); |
2011 ParserBase<Traits>::Checkpoint checkpoint(this); | 2114 ParserBase<Traits>::Checkpoint checkpoint(this); |
2012 ExpressionClassifier arrow_formals_classifier(this, | 2115 ExpressionClassifier arrow_formals_classifier(this, |
2013 classifier->duplicate_finder()); | 2116 classifier->duplicate_finder()); |
2117 | |
2118 bool is_async = allow_harmony_async_await() && peek() == Token::IDENTIFIER && | |
2119 PeekContextualKeyword(CStrVector("async")) && | |
2120 !scanner()->HasAnyLineTerminatorAfterNext(); | |
2121 | |
2014 bool parenthesized_formals = peek() == Token::LPAREN; | 2122 bool parenthesized_formals = peek() == Token::LPAREN; |
2015 if (!parenthesized_formals) { | 2123 if (!is_async && !parenthesized_formals) { |
2016 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2124 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
2017 } | 2125 } |
2018 ExpressionT expression = this->ParseConditionalExpression( | 2126 ExpressionT expression = this->ParseConditionalExpression( |
2019 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2127 accept_IN, &arrow_formals_classifier, CHECK_OK); |
2128 | |
2129 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { | |
2130 // async Identifier => AsyncConciseBody | |
2131 IdentifierT name = | |
2132 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | |
2133 expression = this->ExpressionFromIdentifier( | |
2134 name, position(), scanner()->location().end_pos, scope_, factory()); | |
2135 } | |
2136 | |
2020 if (peek() == Token::ARROW) { | 2137 if (peek() == Token::ARROW) { |
2021 classifier->RecordPatternError(scanner()->peek_location(), | 2138 classifier->RecordPatternError(scanner()->peek_location(), |
2022 MessageTemplate::kUnexpectedToken, | 2139 MessageTemplate::kUnexpectedToken, |
2023 Token::String(Token::ARROW)); | 2140 Token::String(Token::ARROW)); |
2024 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2141 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2025 parenthesized_formals, CHECK_OK); | 2142 parenthesized_formals, is_async, CHECK_OK); |
2026 // This reads strangely, but is correct: it checks whether any | 2143 // This reads strangely, but is correct: it checks whether any |
2027 // sub-expression of the parameter list failed to be a valid formal | 2144 // sub-expression of the parameter list failed to be a valid formal |
2028 // parameter initializer. Since YieldExpressions are banned anywhere | 2145 // parameter initializer. Since YieldExpressions are banned anywhere |
2029 // in an arrow parameter list, this is correct. | 2146 // in an arrow parameter list, this is correct. |
2030 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2147 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
2031 // "YieldExpression", which is its only use. | 2148 // "YieldExpression", which is its only use. |
2032 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2149 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
2150 | |
2033 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2151 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2034 Scope* scope = | 2152 Scope* scope = |
2035 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2153 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
2036 // Because the arrow's parameters were parsed in the outer scope, any | 2154 // Because the arrow's parameters were parsed in the outer scope, any |
2037 // usage flags that might have been triggered there need to be copied | 2155 // usage flags that might have been triggered there need to be copied |
2038 // to the arrow scope. | 2156 // to the arrow scope. |
2039 scope_->PropagateUsageFlagsToScope(scope); | 2157 scope_->PropagateUsageFlagsToScope(scope); |
2040 FormalParametersT parameters(scope); | 2158 FormalParametersT parameters(scope); |
2041 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2159 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
2042 scope->SetHasNonSimpleParameters(); | 2160 scope->SetHasNonSimpleParameters(); |
2043 parameters.is_simple = false; | 2161 parameters.is_simple = false; |
2044 } | 2162 } |
2045 | 2163 |
2046 checkpoint.Restore(¶meters.materialized_literals_count); | 2164 checkpoint.Restore(¶meters.materialized_literals_count); |
2047 | 2165 |
2048 scope->set_start_position(lhs_beg_pos); | 2166 scope->set_start_position(lhs_beg_pos); |
2049 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2167 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
2050 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2168 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
2051 &duplicate_loc, CHECK_OK); | 2169 &duplicate_loc, CHECK_OK); |
2052 if (duplicate_loc.IsValid()) { | 2170 if (duplicate_loc.IsValid()) { |
2053 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2171 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2054 duplicate_loc); | 2172 duplicate_loc); |
2055 } | 2173 } |
2056 expression = this->ParseArrowFunctionLiteral( | 2174 expression = this->ParseArrowFunctionLiteral( |
2057 accept_IN, parameters, arrow_formals_classifier, CHECK_OK); | 2175 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); |
2058 | 2176 |
2059 if (fni_ != nullptr) fni_->Infer(); | 2177 if (fni_ != nullptr) fni_->Infer(); |
2060 | 2178 |
2061 return expression; | 2179 return expression; |
2062 } | 2180 } |
2063 | 2181 |
2064 if (this->IsValidReferenceExpression(expression)) { | 2182 if (this->IsValidReferenceExpression(expression)) { |
2065 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2183 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
2066 } | 2184 } |
2067 | 2185 |
2068 // "expression" was not itself an arrow function parameter list, but it might | 2186 // "expression" was not itself an arrow function parameter list, but it might |
2069 // form part of one. Propagate speculative formal parameter error locations. | 2187 // form part of one. Propagate speculative formal parameter error locations. |
2070 // Do not merge pending non-pattern expressions yet! | 2188 // Do not merge pending non-pattern expressions yet! |
2071 classifier->Accumulate( | 2189 classifier->Accumulate( |
2072 &arrow_formals_classifier, | 2190 &arrow_formals_classifier, |
2073 ExpressionClassifier::StandardProductions | | 2191 ExpressionClassifier::StandardProductions | |
2074 ExpressionClassifier::FormalParametersProductions | | 2192 ExpressionClassifier::FormalParametersProductions | |
2075 ExpressionClassifier::CoverInitializedNameProduction, | 2193 ExpressionClassifier::CoverInitializedNameProduction | |
2194 ExpressionClassifier::AsyncArrowFormalParametersProduction, | |
2076 false); | 2195 false); |
2077 | 2196 |
2078 if (!Token::IsAssignmentOp(peek())) { | 2197 if (!Token::IsAssignmentOp(peek())) { |
2079 // Parsed conditional expression only (no assignment). | 2198 // Parsed conditional expression only (no assignment). |
2080 // Now pending non-pattern expressions must be merged. | 2199 // Now pending non-pattern expressions must be merged. |
2081 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2200 classifier->MergeNonPatterns(&arrow_formals_classifier); |
2082 return expression; | 2201 return expression; |
2083 } | 2202 } |
2084 | 2203 |
2085 // Now pending non-pattern expressions must be discarded. | 2204 // Now pending non-pattern expressions must be discarded. |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2368 // PostfixExpression | 2487 // PostfixExpression |
2369 // 'delete' UnaryExpression | 2488 // 'delete' UnaryExpression |
2370 // 'void' UnaryExpression | 2489 // 'void' UnaryExpression |
2371 // 'typeof' UnaryExpression | 2490 // 'typeof' UnaryExpression |
2372 // '++' UnaryExpression | 2491 // '++' UnaryExpression |
2373 // '--' UnaryExpression | 2492 // '--' UnaryExpression |
2374 // '+' UnaryExpression | 2493 // '+' UnaryExpression |
2375 // '-' UnaryExpression | 2494 // '-' UnaryExpression |
2376 // '~' UnaryExpression | 2495 // '~' UnaryExpression |
2377 // '!' UnaryExpression | 2496 // '!' UnaryExpression |
2497 // [+Await] AwaitExpression[?Yield] | |
2378 | 2498 |
2379 Token::Value op = peek(); | 2499 Token::Value op = peek(); |
2380 if (Token::IsUnaryOp(op)) { | 2500 if (Token::IsUnaryOp(op)) { |
2381 BindingPatternUnexpectedToken(classifier); | 2501 BindingPatternUnexpectedToken(classifier); |
2382 ArrowFormalParametersUnexpectedToken(classifier); | 2502 ArrowFormalParametersUnexpectedToken(classifier); |
2383 | 2503 |
2384 op = Next(); | 2504 op = Next(); |
2385 int pos = position(); | 2505 int pos = position(); |
2386 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2506 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2387 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2507 CheckNoTailCallExpressions(classifier, CHECK_OK); |
(...skipping 27 matching lines...) Expand all Loading... | |
2415 expression, beg_pos, scanner()->location().end_pos, | 2535 expression, beg_pos, scanner()->location().end_pos, |
2416 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2536 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
2417 this->MarkExpressionAsAssigned(expression); | 2537 this->MarkExpressionAsAssigned(expression); |
2418 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2538 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2419 | 2539 |
2420 return factory()->NewCountOperation(op, | 2540 return factory()->NewCountOperation(op, |
2421 true /* prefix */, | 2541 true /* prefix */, |
2422 expression, | 2542 expression, |
2423 position()); | 2543 position()); |
2424 | 2544 |
2545 } else if (is_async_function() && peek() == Token::AWAIT) { | |
2546 int beg_pos = peek_position(); | |
2547 Consume(Token::AWAIT); | |
2548 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | |
2549 | |
2550 classifier->RecordFormalParameterInitializerError( | |
2551 Scanner::Location(beg_pos, scanner()->location().end_pos), | |
2552 MessageTemplate::kAwaitExpressionFormalParameter); | |
2553 | |
2554 return Traits::RewriteAwaitExpression(value, beg_pos); | |
2425 } else { | 2555 } else { |
2426 return this->ParsePostfixExpression(classifier, ok); | 2556 return this->ParsePostfixExpression(classifier, ok); |
2427 } | 2557 } |
2428 } | 2558 } |
2429 | 2559 |
2430 | 2560 |
2431 template <class Traits> | 2561 template <class Traits> |
2432 typename ParserBase<Traits>::ExpressionT | 2562 typename ParserBase<Traits>::ExpressionT |
2433 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2563 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
2434 bool* ok) { | 2564 bool* ok) { |
(...skipping 29 matching lines...) Expand all Loading... | |
2464 typename ParserBase<Traits>::ExpressionT | 2594 typename ParserBase<Traits>::ExpressionT |
2465 ParserBase<Traits>::ParseLeftHandSideExpression( | 2595 ParserBase<Traits>::ParseLeftHandSideExpression( |
2466 ExpressionClassifier* classifier, bool* ok) { | 2596 ExpressionClassifier* classifier, bool* ok) { |
2467 // LeftHandSideExpression :: | 2597 // LeftHandSideExpression :: |
2468 // (NewExpression | MemberExpression) ... | 2598 // (NewExpression | MemberExpression) ... |
2469 | 2599 |
2470 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { | 2600 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
2471 return this->ParseTailCallExpression(classifier, ok); | 2601 return this->ParseTailCallExpression(classifier, ok); |
2472 } | 2602 } |
2473 | 2603 |
2474 ExpressionT result = | 2604 bool is_async = false; |
2475 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2605 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
2606 classifier, &is_async, CHECK_OK); | |
2476 | 2607 |
2477 while (true) { | 2608 while (true) { |
2478 switch (peek()) { | 2609 switch (peek()) { |
2479 case Token::LBRACK: { | 2610 case Token::LBRACK: { |
2480 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2611 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2481 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2612 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2482 BindingPatternUnexpectedToken(classifier); | 2613 BindingPatternUnexpectedToken(classifier); |
2483 ArrowFormalParametersUnexpectedToken(classifier); | 2614 ArrowFormalParametersUnexpectedToken(classifier); |
2484 Consume(Token::LBRACK); | 2615 Consume(Token::LBRACK); |
2485 int pos = position(); | 2616 int pos = position(); |
2486 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2617 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2487 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2618 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2488 result = factory()->NewProperty(result, index, pos); | 2619 result = factory()->NewProperty(result, index, pos); |
2489 Expect(Token::RBRACK, CHECK_OK); | 2620 Expect(Token::RBRACK, CHECK_OK); |
2490 break; | 2621 break; |
2491 } | 2622 } |
2492 | 2623 |
2493 case Token::LPAREN: { | 2624 case Token::LPAREN: { |
2494 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2625 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2626 int pos; | |
2495 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2627 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2496 BindingPatternUnexpectedToken(classifier); | 2628 BindingPatternUnexpectedToken(classifier); |
2497 ArrowFormalParametersUnexpectedToken(classifier); | |
2498 | |
2499 int pos; | |
2500 if (scanner()->current_token() == Token::IDENTIFIER || | 2629 if (scanner()->current_token() == Token::IDENTIFIER || |
2501 scanner()->current_token() == Token::SUPER) { | 2630 scanner()->current_token() == Token::SUPER) { |
2502 // For call of an identifier we want to report position of | 2631 // For call of an identifier we want to report position of |
2503 // the identifier as position of the call in the stack trace. | 2632 // the identifier as position of the call in the stack trace. |
2504 pos = position(); | 2633 pos = position(); |
2505 } else { | 2634 } else { |
2506 // For other kinds of calls we record position of the parenthesis as | 2635 // For other kinds of calls we record position of the parenthesis as |
2507 // position of the call. Note that this is extremely important for | 2636 // position of the call. Note that this is extremely important for |
2508 // expressions of the form function(){...}() for which call position | 2637 // expressions of the form function(){...}() for which call position |
2509 // should not point to the closing brace otherwise it will intersect | 2638 // should not point to the closing brace otherwise it will intersect |
2510 // with positions recorded for function literal and confuse debugger. | 2639 // with positions recorded for function literal and confuse debugger. |
2511 pos = peek_position(); | 2640 pos = peek_position(); |
2512 // Also the trailing parenthesis are a hint that the function will | 2641 // Also the trailing parenthesis are a hint that the function will |
2513 // be called immediately. If we happen to have parsed a preceding | 2642 // be called immediately. If we happen to have parsed a preceding |
2514 // function literal eagerly, we can also compile it eagerly. | 2643 // function literal eagerly, we can also compile it eagerly. |
2515 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2644 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2516 result->AsFunctionLiteral()->set_should_eager_compile(); | 2645 result->AsFunctionLiteral()->set_should_eager_compile(); |
2517 } | 2646 } |
2518 } | 2647 } |
2519 Scanner::Location spread_pos; | 2648 Scanner::Location spread_pos; |
2520 typename Traits::Type::ExpressionList args = | 2649 typename Traits::Type::ExpressionList args = |
2521 ParseArguments(&spread_pos, classifier, CHECK_OK); | 2650 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); |
2651 | |
2652 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { | |
2653 if (args->length()) { | |
2654 // async ( Arguments ) => ... | |
2655 return Traits::ExpressionListToExpression(args); | |
2656 } | |
2657 // async () => ... | |
2658 return factory()->NewEmptyParentheses(pos); | |
2659 } | |
2660 | |
2661 ArrowFormalParametersUnexpectedToken(classifier); | |
2522 | 2662 |
2523 // Keep track of eval() calls since they disable all local variable | 2663 // Keep track of eval() calls since they disable all local variable |
2524 // optimizations. | 2664 // optimizations. |
2525 // The calls that need special treatment are the | 2665 // The calls that need special treatment are the |
2526 // direct eval calls. These calls are all of the form eval(...), with | 2666 // direct eval calls. These calls are all of the form eval(...), with |
2527 // no explicit receiver. | 2667 // no explicit receiver. |
2528 // These calls are marked as potentially direct eval calls. Whether | 2668 // These calls are marked as potentially direct eval calls. Whether |
2529 // they are actually direct calls to eval is determined at run time. | 2669 // they are actually direct calls to eval is determined at run time. |
2530 this->CheckPossibleEvalCall(result, scope_); | 2670 this->CheckPossibleEvalCall(result, scope_); |
2531 | 2671 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2572 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2712 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2573 break; | 2713 break; |
2574 } | 2714 } |
2575 | 2715 |
2576 default: | 2716 default: |
2577 return result; | 2717 return result; |
2578 } | 2718 } |
2579 } | 2719 } |
2580 } | 2720 } |
2581 | 2721 |
2582 | |
2583 template <class Traits> | 2722 template <class Traits> |
2584 typename ParserBase<Traits>::ExpressionT | 2723 typename ParserBase<Traits>::ExpressionT |
2585 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( | 2724 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
2586 ExpressionClassifier* classifier, bool* ok) { | 2725 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
2587 // NewExpression :: | 2726 // NewExpression :: |
2588 // ('new')+ MemberExpression | 2727 // ('new')+ MemberExpression |
2589 // | 2728 // |
2590 // NewTarget :: | 2729 // NewTarget :: |
2591 // 'new' '.' 'target' | 2730 // 'new' '.' 'target' |
2592 | 2731 |
2593 // The grammar for new expressions is pretty warped. We can have several 'new' | 2732 // The grammar for new expressions is pretty warped. We can have several 'new' |
2594 // keywords following each other, and then a MemberExpression. When we see '(' | 2733 // keywords following each other, and then a MemberExpression. When we see '(' |
2595 // after the MemberExpression, it's associated with the rightmost unassociated | 2734 // after the MemberExpression, it's associated with the rightmost unassociated |
2596 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2735 // 'new' to create a NewExpression with arguments. However, a NewExpression |
(...skipping 12 matching lines...) Expand all Loading... | |
2609 ArrowFormalParametersUnexpectedToken(classifier); | 2748 ArrowFormalParametersUnexpectedToken(classifier); |
2610 Consume(Token::NEW); | 2749 Consume(Token::NEW); |
2611 int new_pos = position(); | 2750 int new_pos = position(); |
2612 ExpressionT result = this->EmptyExpression(); | 2751 ExpressionT result = this->EmptyExpression(); |
2613 if (peek() == Token::SUPER) { | 2752 if (peek() == Token::SUPER) { |
2614 const bool is_new = true; | 2753 const bool is_new = true; |
2615 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2754 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
2616 } else if (peek() == Token::PERIOD) { | 2755 } else if (peek() == Token::PERIOD) { |
2617 return ParseNewTargetExpression(CHECK_OK); | 2756 return ParseNewTargetExpression(CHECK_OK); |
2618 } else { | 2757 } else { |
2619 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2758 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, |
2759 CHECK_OK); | |
2620 } | 2760 } |
2621 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2761 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2622 if (peek() == Token::LPAREN) { | 2762 if (peek() == Token::LPAREN) { |
2623 // NewExpression with arguments. | 2763 // NewExpression with arguments. |
2624 Scanner::Location spread_pos; | 2764 Scanner::Location spread_pos; |
2625 typename Traits::Type::ExpressionList args = | 2765 typename Traits::Type::ExpressionList args = |
2626 this->ParseArguments(&spread_pos, classifier, CHECK_OK); | 2766 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
2627 | 2767 |
2628 if (spread_pos.IsValid()) { | 2768 if (spread_pos.IsValid()) { |
2629 args = Traits::PrepareSpreadArguments(args); | 2769 args = Traits::PrepareSpreadArguments(args); |
2630 result = Traits::SpreadCallNew(result, args, new_pos); | 2770 result = Traits::SpreadCallNew(result, args, new_pos); |
2631 } else { | 2771 } else { |
2632 result = factory()->NewCallNew(result, args, new_pos); | 2772 result = factory()->NewCallNew(result, args, new_pos); |
2633 } | 2773 } |
2634 // The expression can still continue with . or [ after the arguments. | 2774 // The expression can still continue with . or [ after the arguments. |
2635 result = | 2775 result = this->ParseMemberExpressionContinuation(result, is_async, |
2636 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2776 classifier, CHECK_OK); |
2637 return result; | 2777 return result; |
2638 } | 2778 } |
2639 // NewExpression without arguments. | 2779 // NewExpression without arguments. |
2640 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2780 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2641 new_pos); | 2781 new_pos); |
2642 } | 2782 } |
2643 // No 'new' or 'super' keyword. | 2783 // No 'new' or 'super' keyword. |
2644 return this->ParseMemberExpression(classifier, ok); | 2784 return this->ParseMemberExpression(classifier, is_async, ok); |
2645 } | 2785 } |
2646 | 2786 |
2647 | |
2648 template <class Traits> | 2787 template <class Traits> |
2649 typename ParserBase<Traits>::ExpressionT | 2788 typename ParserBase<Traits>::ExpressionT |
2650 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, | 2789 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
2651 bool* ok) { | 2790 bool* is_async, bool* ok) { |
2652 // MemberExpression :: | 2791 // MemberExpression :: |
2653 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2792 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
2654 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 2793 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
2655 | 2794 |
2656 // The '[' Expression ']' and '.' Identifier parts are parsed by | 2795 // The '[' Expression ']' and '.' Identifier parts are parsed by |
2657 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 2796 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
2658 // caller. | 2797 // caller. |
2659 | 2798 |
2660 // Parse the initial primary or function expression. | 2799 // Parse the initial primary or function expression. |
2661 ExpressionT result = this->EmptyExpression(); | 2800 ExpressionT result = this->EmptyExpression(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2698 name, function_name_location, | 2837 name, function_name_location, |
2699 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 2838 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
2700 : kFunctionNameValidityUnknown, | 2839 : kFunctionNameValidityUnknown, |
2701 is_generator ? FunctionKind::kGeneratorFunction | 2840 is_generator ? FunctionKind::kGeneratorFunction |
2702 : FunctionKind::kNormalFunction, | 2841 : FunctionKind::kNormalFunction, |
2703 function_token_position, function_type, language_mode(), CHECK_OK); | 2842 function_token_position, function_type, language_mode(), CHECK_OK); |
2704 } else if (peek() == Token::SUPER) { | 2843 } else if (peek() == Token::SUPER) { |
2705 const bool is_new = false; | 2844 const bool is_new = false; |
2706 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2845 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
2707 } else { | 2846 } else { |
2708 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2847 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); |
2709 } | 2848 } |
2710 | 2849 |
2711 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2850 result = |
2851 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); | |
2712 return result; | 2852 return result; |
2713 } | 2853 } |
2714 | 2854 |
2715 | 2855 |
2716 template <class Traits> | 2856 template <class Traits> |
2717 typename ParserBase<Traits>::ExpressionT | 2857 typename ParserBase<Traits>::ExpressionT |
2718 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 2858 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
2719 ExpressionClassifier* classifier, | 2859 ExpressionClassifier* classifier, |
2720 bool* ok) { | 2860 bool* ok) { |
2721 Expect(Token::SUPER, CHECK_OK); | 2861 Expect(Token::SUPER, CHECK_OK); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2768 if (!scope_->ReceiverScope()->is_function_scope()) { | 2908 if (!scope_->ReceiverScope()->is_function_scope()) { |
2769 ReportMessageAt(scanner()->location(), | 2909 ReportMessageAt(scanner()->location(), |
2770 MessageTemplate::kUnexpectedNewTarget); | 2910 MessageTemplate::kUnexpectedNewTarget); |
2771 *ok = false; | 2911 *ok = false; |
2772 return this->EmptyExpression(); | 2912 return this->EmptyExpression(); |
2773 } | 2913 } |
2774 | 2914 |
2775 return this->NewTargetExpression(scope_, factory(), pos); | 2915 return this->NewTargetExpression(scope_, factory(), pos); |
2776 } | 2916 } |
2777 | 2917 |
2778 | |
2779 template <class Traits> | 2918 template <class Traits> |
2780 typename ParserBase<Traits>::ExpressionT | 2919 typename ParserBase<Traits>::ExpressionT |
2781 ParserBase<Traits>::ParseMemberExpressionContinuation( | 2920 ParserBase<Traits>::ParseMemberExpressionContinuation( |
2782 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 2921 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
2922 bool* ok) { | |
2783 // Parses this part of MemberExpression: | 2923 // Parses this part of MemberExpression: |
2784 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 2924 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
2785 while (true) { | 2925 while (true) { |
2786 switch (peek()) { | 2926 switch (peek()) { |
2787 case Token::LBRACK: { | 2927 case Token::LBRACK: { |
2928 *is_async = false; | |
2788 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2929 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2789 BindingPatternUnexpectedToken(classifier); | 2930 BindingPatternUnexpectedToken(classifier); |
2790 ArrowFormalParametersUnexpectedToken(classifier); | 2931 ArrowFormalParametersUnexpectedToken(classifier); |
2791 | 2932 |
2792 Consume(Token::LBRACK); | 2933 Consume(Token::LBRACK); |
2793 int pos = position(); | 2934 int pos = position(); |
2794 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 2935 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
2795 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2936 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2796 expression = factory()->NewProperty(expression, index, pos); | 2937 expression = factory()->NewProperty(expression, index, pos); |
2797 if (fni_ != NULL) { | 2938 if (fni_ != NULL) { |
2798 this->PushPropertyName(fni_, index); | 2939 this->PushPropertyName(fni_, index); |
2799 } | 2940 } |
2800 Expect(Token::RBRACK, CHECK_OK); | 2941 Expect(Token::RBRACK, CHECK_OK); |
2801 break; | 2942 break; |
2802 } | 2943 } |
2803 case Token::PERIOD: { | 2944 case Token::PERIOD: { |
2945 *is_async = false; | |
2804 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2946 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2805 BindingPatternUnexpectedToken(classifier); | 2947 BindingPatternUnexpectedToken(classifier); |
2806 ArrowFormalParametersUnexpectedToken(classifier); | 2948 ArrowFormalParametersUnexpectedToken(classifier); |
2807 | 2949 |
2808 Consume(Token::PERIOD); | 2950 Consume(Token::PERIOD); |
2809 int pos = position(); | 2951 int pos = position(); |
2810 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2952 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2811 expression = factory()->NewProperty( | 2953 expression = factory()->NewProperty( |
2812 expression, factory()->NewStringLiteral(name, pos), pos); | 2954 expression, factory()->NewStringLiteral(name, pos), pos); |
2813 if (fni_ != NULL) { | 2955 if (fni_ != NULL) { |
2814 this->PushLiteralName(fni_, name); | 2956 this->PushLiteralName(fni_, name); |
2815 } | 2957 } |
2816 break; | 2958 break; |
2817 } | 2959 } |
2818 case Token::TEMPLATE_SPAN: | 2960 case Token::TEMPLATE_SPAN: |
2819 case Token::TEMPLATE_TAIL: { | 2961 case Token::TEMPLATE_TAIL: { |
2962 *is_async = false; | |
2820 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2963 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2821 BindingPatternUnexpectedToken(classifier); | 2964 BindingPatternUnexpectedToken(classifier); |
2822 ArrowFormalParametersUnexpectedToken(classifier); | 2965 ArrowFormalParametersUnexpectedToken(classifier); |
2823 int pos; | 2966 int pos; |
2824 if (scanner()->current_token() == Token::IDENTIFIER) { | 2967 if (scanner()->current_token() == Token::IDENTIFIER) { |
2825 pos = position(); | 2968 pos = position(); |
2826 } else { | 2969 } else { |
2827 pos = peek_position(); | 2970 pos = peek_position(); |
2828 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2971 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2829 // If the tag function looks like an IIFE, set_parenthesized() to | 2972 // If the tag function looks like an IIFE, set_parenthesized() to |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2978 case Token::STATIC: | 3121 case Token::STATIC: |
2979 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 3122 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
2980 case Token::YIELD: | 3123 case Token::YIELD: |
2981 case Token::AWAIT: | 3124 case Token::AWAIT: |
2982 return true; | 3125 return true; |
2983 default: | 3126 default: |
2984 return false; | 3127 return false; |
2985 } | 3128 } |
2986 } | 3129 } |
2987 | 3130 |
2988 | |
2989 template <class Traits> | 3131 template <class Traits> |
2990 typename ParserBase<Traits>::ExpressionT | 3132 typename ParserBase<Traits>::ExpressionT |
2991 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3133 ParserBase<Traits>::ParseArrowFunctionLiteral( |
2992 bool accept_IN, const FormalParametersT& formal_parameters, | 3134 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
2993 const ExpressionClassifier& formals_classifier, bool* ok) { | 3135 const ExpressionClassifier& formals_classifier, bool* ok) { |
2994 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3136 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
2995 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3137 // ASI inserts `;` after arrow parameters if a line terminator is found. |
2996 // `=> ...` is never a valid expression, so report as syntax error. | 3138 // `=> ...` is never a valid expression, so report as syntax error. |
2997 // If next token is not `=>`, it's a syntax error anyways. | 3139 // If next token is not `=>`, it's a syntax error anyways. |
2998 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3140 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
2999 *ok = false; | 3141 *ok = false; |
3000 return this->EmptyExpression(); | 3142 return this->EmptyExpression(); |
3001 } | 3143 } |
3002 | 3144 |
3003 typename Traits::Type::StatementList body; | 3145 typename Traits::Type::StatementList body; |
3004 int num_parameters = formal_parameters.scope->num_parameters(); | 3146 int num_parameters = formal_parameters.scope->num_parameters(); |
3005 int materialized_literal_count = -1; | 3147 int materialized_literal_count = -1; |
3006 int expected_property_count = -1; | 3148 int expected_property_count = -1; |
3007 Scanner::Location super_loc; | 3149 Scanner::Location super_loc; |
3008 | 3150 |
3009 { | 3151 { |
3010 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3152 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3011 FunctionState function_state(&function_state_, &scope_, | 3153 FunctionState function_state( |
3012 formal_parameters.scope, kArrowFunction, | 3154 &function_state_, &scope_, formal_parameters.scope, |
3013 &function_factory); | 3155 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); |
3014 | 3156 |
3015 function_state.SkipMaterializedLiterals( | 3157 function_state.SkipMaterializedLiterals( |
3016 formal_parameters.materialized_literals_count); | 3158 formal_parameters.materialized_literals_count); |
3017 | 3159 |
3018 this->ReindexLiterals(formal_parameters); | 3160 this->ReindexLiterals(formal_parameters); |
3019 | 3161 |
3020 Expect(Token::ARROW, CHECK_OK); | 3162 Expect(Token::ARROW, CHECK_OK); |
3021 | 3163 |
3022 if (peek() == Token::LBRACE) { | 3164 if (peek() == Token::LBRACE) { |
3023 // Multiple statement body | 3165 // Multiple statement body |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3311 has_seen_constructor_ = true; | 3453 has_seen_constructor_ = true; |
3312 return; | 3454 return; |
3313 } | 3455 } |
3314 } | 3456 } |
3315 | 3457 |
3316 | 3458 |
3317 } // namespace internal | 3459 } // namespace internal |
3318 } // namespace v8 | 3460 } // namespace v8 |
3319 | 3461 |
3320 #endif // V8_PARSING_PARSER_BASE_H | 3462 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |