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/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 // The ParserTypes structure encapsulates the differences in the | 168 // The ParserTypes structure encapsulates the differences in the |
169 // types used in parsing methods. E.g., Parser methods use Expression* | 169 // types used in parsing methods. E.g., Parser methods use Expression* |
170 // and PreParser methods use PreParserExpression. For any given parser | 170 // and PreParser methods use PreParserExpression. For any given parser |
171 // implementation class Impl, it is expected to contain the following typedefs: | 171 // implementation class Impl, it is expected to contain the following typedefs: |
172 // | 172 // |
173 // template <> | 173 // template <> |
174 // struct ParserTypes<Impl> { | 174 // struct ParserTypes<Impl> { |
175 // // Synonyms for ParserBase<Impl> and Impl, respectively. | 175 // // Synonyms for ParserBase<Impl> and Impl, respectively. |
176 // typedef Base; | 176 // typedef Base; |
177 // typedef Impl; | 177 // typedef Impl; |
178 // // TODO(nikolaos): these three will probably go away, as they are | 178 // // TODO(nikolaos): these two will probably go away, as they are |
179 // // not related to pure parsing. | 179 // // not related to pure parsing. |
180 // typedef GeneratorVariable; | 180 // typedef GeneratorVariable; |
181 // typedef AstProperties; | 181 // typedef AstProperties; |
182 // typedef ExpressionClassifier; | |
183 // // Return types for traversing functions. | 182 // // Return types for traversing functions. |
184 // typedef Identifier; | 183 // typedef Identifier; |
185 // typedef Expression; | 184 // typedef Expression; |
186 // typedef YieldExpression; | 185 // typedef YieldExpression; |
187 // typedef FunctionLiteral; | 186 // typedef FunctionLiteral; |
188 // typedef ClassLiteral; | 187 // typedef ClassLiteral; |
189 // typedef Literal; | 188 // typedef Literal; |
190 // typedef ObjectLiteralProperty; | 189 // typedef ObjectLiteralProperty; |
191 // typedef ExpressionList; | 190 // typedef ExpressionList; |
192 // typedef PropertyList; | 191 // typedef PropertyList; |
(...skipping 13 matching lines...) Expand all Loading... | |
206 // Shorten type names defined by ParserTypes<Impl>. | 205 // Shorten type names defined by ParserTypes<Impl>. |
207 typedef ParserTypes<Impl> Types; | 206 typedef ParserTypes<Impl> Types; |
208 typedef typename Types::Expression ExpressionT; | 207 typedef typename Types::Expression ExpressionT; |
209 typedef typename Types::Identifier IdentifierT; | 208 typedef typename Types::Identifier IdentifierT; |
210 typedef typename Types::FormalParameter FormalParameterT; | 209 typedef typename Types::FormalParameter FormalParameterT; |
211 typedef typename Types::FormalParameters FormalParametersT; | 210 typedef typename Types::FormalParameters FormalParametersT; |
212 typedef typename Types::FunctionLiteral FunctionLiteralT; | 211 typedef typename Types::FunctionLiteral FunctionLiteralT; |
213 typedef typename Types::Literal LiteralT; | 212 typedef typename Types::Literal LiteralT; |
214 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; | 213 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; |
215 typedef typename Types::StatementList StatementListT; | 214 typedef typename Types::StatementList StatementListT; |
216 typedef typename Types::ExpressionClassifier ExpressionClassifier; | 215 typedef typename v8::internal::ExpressionClassifier<Types> |
216 ExpressionClassifier; | |
217 | 217 |
218 // All implementation-specific methods must be called through this. | 218 // All implementation-specific methods must be called through this. |
219 Impl* impl() { return static_cast<Impl*>(this); } | 219 Impl* impl() { return static_cast<Impl*>(this); } |
220 const Impl* impl() const { return static_cast<const Impl*>(this); } | 220 const Impl* impl() const { return static_cast<const Impl*>(this); } |
221 | 221 |
222 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 222 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
223 v8::Extension* extension, AstValueFactory* ast_value_factory, | 223 v8::Extension* extension, AstValueFactory* ast_value_factory, |
224 ParserRecorder* log) | 224 ParserRecorder* log) |
225 : scope_state_(nullptr), | 225 : scope_state_(nullptr), |
226 function_state_(nullptr), | 226 function_state_(nullptr), |
227 extension_(extension), | 227 extension_(extension), |
228 fni_(nullptr), | 228 fni_(nullptr), |
229 ast_value_factory_(ast_value_factory), | 229 ast_value_factory_(ast_value_factory), |
230 ast_node_factory_(ast_value_factory), | 230 ast_node_factory_(ast_value_factory), |
231 log_(log), | 231 log_(log), |
232 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 232 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
233 parsing_module_(false), | 233 parsing_module_(false), |
234 stack_limit_(stack_limit), | 234 stack_limit_(stack_limit), |
235 zone_(zone), | 235 zone_(zone), |
236 classifier_(nullptr), | |
236 scanner_(scanner), | 237 scanner_(scanner), |
237 stack_overflow_(false), | 238 stack_overflow_(false), |
238 allow_lazy_(false), | 239 allow_lazy_(false), |
239 allow_natives_(false), | 240 allow_natives_(false), |
240 allow_tailcalls_(false), | 241 allow_tailcalls_(false), |
241 allow_harmony_restrictive_declarations_(false), | 242 allow_harmony_restrictive_declarations_(false), |
242 allow_harmony_do_expressions_(false), | 243 allow_harmony_do_expressions_(false), |
243 allow_harmony_for_in_(false), | 244 allow_harmony_for_in_(false), |
244 allow_harmony_function_sent_(false), | 245 allow_harmony_function_sent_(false), |
245 allow_harmony_async_await_(false), | 246 allow_harmony_async_await_(false), |
(...skipping 17 matching lines...) Expand all Loading... | |
263 | 264 |
264 #undef ALLOW_ACCESSORS | 265 #undef ALLOW_ACCESSORS |
265 | 266 |
266 uintptr_t stack_limit() const { return stack_limit_; } | 267 uintptr_t stack_limit() const { return stack_limit_; } |
267 | 268 |
268 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 269 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
269 | 270 |
270 Zone* zone() const { return zone_; } | 271 Zone* zone() const { return zone_; } |
271 | 272 |
272 protected: | 273 protected: |
274 friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>; | |
275 | |
273 enum AllowRestrictedIdentifiers { | 276 enum AllowRestrictedIdentifiers { |
274 kAllowRestrictedIdentifiers, | 277 kAllowRestrictedIdentifiers, |
275 kDontAllowRestrictedIdentifiers | 278 kDontAllowRestrictedIdentifiers |
276 }; | 279 }; |
277 | 280 |
278 enum Mode { | 281 enum Mode { |
279 PARSE_LAZILY, | 282 PARSE_LAZILY, |
280 PARSE_EAGERLY | 283 PARSE_EAGERLY |
281 }; | 284 }; |
282 | 285 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
826 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 829 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
827 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, | 830 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
828 ok); | 831 ok); |
829 } | 832 } |
830 | 833 |
831 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 834 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
832 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, | 835 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
833 ok); | 836 ok); |
834 } | 837 } |
835 | 838 |
836 void CheckDestructuringElement(ExpressionT element, | 839 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); |
837 ExpressionClassifier* classifier, int beg_pos, | |
838 int end_pos); | |
839 | 840 |
840 // Checking the name of a function literal. This has to be done after parsing | 841 // Checking the name of a function literal. This has to be done after parsing |
841 // the function, since the function can declare itself strict. | 842 // the function, since the function can declare itself strict. |
842 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 843 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
843 FunctionNameValidity function_name_validity, | 844 FunctionNameValidity function_name_validity, |
844 const Scanner::Location& function_name_loc, bool* ok) { | 845 const Scanner::Location& function_name_loc, bool* ok) { |
845 if (function_name_validity == kSkipFunctionNameCheck) return; | 846 if (function_name_validity == kSkipFunctionNameCheck) return; |
846 // The function name needs to be checked in strict mode. | 847 // The function name needs to be checked in strict mode. |
847 if (is_sloppy(language_mode)) return; | 848 if (is_sloppy(language_mode)) return; |
848 | 849 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
908 void ReportUnexpectedTokenAt( | 909 void ReportUnexpectedTokenAt( |
909 Scanner::Location location, Token::Value token, | 910 Scanner::Location location, Token::Value token, |
910 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 911 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
911 | 912 |
912 void ReportClassifierError( | 913 void ReportClassifierError( |
913 const typename ExpressionClassifier::Error& error) { | 914 const typename ExpressionClassifier::Error& error) { |
914 impl()->ReportMessageAt(error.location, error.message, error.arg, | 915 impl()->ReportMessageAt(error.location, error.message, error.arg, |
915 error.type); | 916 error.type); |
916 } | 917 } |
917 | 918 |
918 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 919 void ValidateExpression(bool* ok) { |
919 if (!classifier->is_valid_expression()) { | 920 if (!classifier()->is_valid_expression()) { |
920 ReportClassifierError(classifier->expression_error()); | 921 ReportClassifierError(classifier()->expression_error()); |
921 *ok = false; | 922 *ok = false; |
922 } | 923 } |
923 } | 924 } |
924 | 925 |
925 void ValidateFormalParameterInitializer( | 926 void ValidateFormalParameterInitializer(bool* ok) { |
926 const ExpressionClassifier* classifier, bool* ok) { | 927 if (!classifier()->is_valid_formal_parameter_initializer()) { |
927 if (!classifier->is_valid_formal_parameter_initializer()) { | 928 ReportClassifierError(classifier()->formal_parameter_initializer_error()); |
928 ReportClassifierError(classifier->formal_parameter_initializer_error()); | |
929 *ok = false; | 929 *ok = false; |
930 } | 930 } |
931 } | 931 } |
932 | 932 |
933 void ValidateBindingPattern(const ExpressionClassifier* classifier, | 933 void ValidateBindingPattern(bool* ok) { |
934 bool* ok) { | 934 if (!classifier()->is_valid_binding_pattern()) { |
935 if (!classifier->is_valid_binding_pattern()) { | 935 ReportClassifierError(classifier()->binding_pattern_error()); |
936 ReportClassifierError(classifier->binding_pattern_error()); | |
937 *ok = false; | 936 *ok = false; |
938 } | 937 } |
939 } | 938 } |
940 | 939 |
941 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, | 940 void ValidateAssignmentPattern(bool* ok) { |
942 bool* ok) { | 941 if (!classifier()->is_valid_assignment_pattern()) { |
943 if (!classifier->is_valid_assignment_pattern()) { | 942 ReportClassifierError(classifier()->assignment_pattern_error()); |
944 ReportClassifierError(classifier->assignment_pattern_error()); | |
945 *ok = false; | 943 *ok = false; |
946 } | 944 } |
947 } | 945 } |
948 | 946 |
949 void ValidateFormalParameters(const ExpressionClassifier* classifier, | 947 void ValidateFormalParameters(LanguageMode language_mode, |
950 LanguageMode language_mode, | |
951 bool allow_duplicates, bool* ok) { | 948 bool allow_duplicates, bool* ok) { |
952 if (!allow_duplicates && | 949 if (!allow_duplicates && |
953 !classifier->is_valid_formal_parameter_list_without_duplicates()) { | 950 !classifier()->is_valid_formal_parameter_list_without_duplicates()) { |
954 ReportClassifierError(classifier->duplicate_formal_parameter_error()); | 951 ReportClassifierError(classifier()->duplicate_formal_parameter_error()); |
955 *ok = false; | 952 *ok = false; |
956 } else if (is_strict(language_mode) && | 953 } else if (is_strict(language_mode) && |
957 !classifier->is_valid_strict_mode_formal_parameters()) { | 954 !classifier()->is_valid_strict_mode_formal_parameters()) { |
958 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 955 ReportClassifierError(classifier()->strict_mode_formal_parameter_error()); |
959 *ok = false; | 956 *ok = false; |
960 } | 957 } |
961 } | 958 } |
962 | 959 |
963 bool IsValidArrowFormalParametersStart(Token::Value token) { | 960 bool IsValidArrowFormalParametersStart(Token::Value token) { |
964 return is_any_identifier(token) || token == Token::LPAREN; | 961 return is_any_identifier(token) || token == Token::LPAREN; |
965 } | 962 } |
966 | 963 |
967 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 964 void ValidateArrowFormalParameters(ExpressionT expr, |
968 ExpressionT expr, | |
969 bool parenthesized_formals, bool is_async, | 965 bool parenthesized_formals, bool is_async, |
970 bool* ok) { | 966 bool* ok) { |
971 if (classifier->is_valid_binding_pattern()) { | 967 if (classifier()->is_valid_binding_pattern()) { |
972 // A simple arrow formal parameter: IDENTIFIER => BODY. | 968 // A simple arrow formal parameter: IDENTIFIER => BODY. |
973 if (!impl()->IsIdentifier(expr)) { | 969 if (!impl()->IsIdentifier(expr)) { |
974 impl()->ReportMessageAt(scanner()->location(), | 970 impl()->ReportMessageAt(scanner()->location(), |
975 MessageTemplate::kUnexpectedToken, | 971 MessageTemplate::kUnexpectedToken, |
976 Token::String(scanner()->current_token())); | 972 Token::String(scanner()->current_token())); |
977 *ok = false; | 973 *ok = false; |
978 } | 974 } |
979 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 975 } else if (!classifier()->is_valid_arrow_formal_parameters()) { |
980 // If after parsing the expr, we see an error but the expression is | 976 // If after parsing the expr, we see an error but the expression is |
981 // neither a valid binding pattern nor a valid parenthesized formal | 977 // neither a valid binding pattern nor a valid parenthesized formal |
982 // parameter list, show the "arrow formal parameters" error if the formals | 978 // parameter list, show the "arrow formal parameters" error if the formals |
983 // started with a parenthesis, and the binding pattern error otherwise. | 979 // started with a parenthesis, and the binding pattern error otherwise. |
984 const typename ExpressionClassifier::Error& error = | 980 const typename ExpressionClassifier::Error& error = |
985 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 981 parenthesized_formals ? classifier()->arrow_formal_parameters_error() |
986 : classifier->binding_pattern_error(); | 982 : classifier()->binding_pattern_error(); |
987 ReportClassifierError(error); | 983 ReportClassifierError(error); |
988 *ok = false; | 984 *ok = false; |
989 } | 985 } |
990 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | 986 if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) { |
991 const typename ExpressionClassifier::Error& error = | 987 const typename ExpressionClassifier::Error& error = |
992 classifier->async_arrow_formal_parameters_error(); | 988 classifier()->async_arrow_formal_parameters_error(); |
993 ReportClassifierError(error); | 989 ReportClassifierError(error); |
994 *ok = false; | 990 *ok = false; |
995 } | 991 } |
996 } | 992 } |
997 | 993 |
998 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 994 void ValidateLetPattern(bool* ok) { |
999 if (!classifier->is_valid_let_pattern()) { | 995 if (!classifier()->is_valid_let_pattern()) { |
1000 ReportClassifierError(classifier->let_pattern_error()); | 996 ReportClassifierError(classifier()->let_pattern_error()); |
1001 *ok = false; | 997 *ok = false; |
1002 } | 998 } |
1003 } | 999 } |
1004 | 1000 |
1005 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, | 1001 void CheckNoTailCallExpressions(bool* ok) { |
1006 bool* ok) { | |
1007 if (FLAG_harmony_explicit_tailcalls && | 1002 if (FLAG_harmony_explicit_tailcalls && |
1008 classifier->has_tail_call_expression()) { | 1003 classifier()->has_tail_call_expression()) { |
1009 ReportClassifierError(classifier->tail_call_expression_error()); | 1004 ReportClassifierError(classifier()->tail_call_expression_error()); |
1010 *ok = false; | 1005 *ok = false; |
1011 } | 1006 } |
1012 } | 1007 } |
1013 | 1008 |
1014 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 1009 void ExpressionUnexpectedToken() { |
1015 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1010 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
1016 const char* arg; | 1011 const char* arg; |
1017 Scanner::Location location = scanner()->peek_location(); | 1012 Scanner::Location location = scanner()->peek_location(); |
1018 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1013 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
1019 classifier->RecordExpressionError(location, message, arg); | 1014 classifier()->RecordExpressionError(location, message, arg); |
1020 } | 1015 } |
1021 | 1016 |
1022 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 1017 void BindingPatternUnexpectedToken() { |
1023 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1018 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
1024 const char* arg; | 1019 const char* arg; |
1025 Scanner::Location location = scanner()->peek_location(); | 1020 Scanner::Location location = scanner()->peek_location(); |
1026 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1021 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
1027 classifier->RecordBindingPatternError(location, message, arg); | 1022 classifier()->RecordBindingPatternError(location, message, arg); |
1028 } | 1023 } |
1029 | 1024 |
1030 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { | 1025 void ArrowFormalParametersUnexpectedToken() { |
1031 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1026 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
1032 const char* arg; | 1027 const char* arg; |
1033 Scanner::Location location = scanner()->peek_location(); | 1028 Scanner::Location location = scanner()->peek_location(); |
1034 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1029 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
1035 classifier->RecordArrowFormalParametersError(location, message, arg); | 1030 classifier()->RecordArrowFormalParametersError(location, message, arg); |
1036 } | 1031 } |
1037 | 1032 |
1038 // Recursive descent functions: | 1033 // Recursive descent functions: |
1039 | 1034 |
1040 // Parses an identifier that is valid for the current scope, in particular it | 1035 // Parses an identifier that is valid for the current scope, in particular it |
1041 // fails on strict mode future reserved keywords in a strict scope. If | 1036 // fails on strict mode future reserved keywords in a strict scope. If |
1042 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 1037 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
1043 // "arguments" as identifier even in strict mode (this is needed in cases like | 1038 // "arguments" as identifier even in strict mode (this is needed in cases like |
1044 // "var foo = eval;"). | 1039 // "var foo = eval;"). |
1045 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 1040 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
1046 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1041 IdentifierT ParseAndClassifyIdentifier(bool* ok); |
1047 bool* ok); | |
1048 // Parses an identifier or a strict mode future reserved word, and indicate | 1042 // Parses an identifier or a strict mode future reserved word, and indicate |
1049 // whether it is strict mode future reserved. Allows passing in function_kind | 1043 // whether it is strict mode future reserved. Allows passing in function_kind |
1050 // for the case of parsing the identifier in a function expression, where the | 1044 // for the case of parsing the identifier in a function expression, where the |
1051 // relevant "function_kind" bit is of the function being parsed, not the | 1045 // relevant "function_kind" bit is of the function being parsed, not the |
1052 // containing function. | 1046 // containing function. |
1053 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind, | 1047 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind, |
1054 bool* is_strict_reserved, | 1048 bool* is_strict_reserved, |
1055 bool* ok); | 1049 bool* ok); |
1056 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 1050 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
1057 bool* ok) { | 1051 bool* ok) { |
1058 return ParseIdentifierOrStrictReservedWord(function_state_->kind(), | 1052 return ParseIdentifierOrStrictReservedWord(function_state_->kind(), |
1059 is_strict_reserved, ok); | 1053 is_strict_reserved, ok); |
1060 } | 1054 } |
1061 | 1055 |
1062 IdentifierT ParseIdentifierName(bool* ok); | 1056 IdentifierT ParseIdentifierName(bool* ok); |
1063 | 1057 |
1064 ExpressionT ParseRegExpLiteral(bool* ok); | 1058 ExpressionT ParseRegExpLiteral(bool* ok); |
1065 | 1059 |
1066 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 1060 ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok); |
1067 bool* is_async, bool* ok); | 1061 ExpressionT ParsePrimaryExpression(bool* ok) { |
1068 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
1069 bool* ok) { | |
1070 bool is_async; | 1062 bool is_async; |
1071 return ParsePrimaryExpression(classifier, &is_async, ok); | 1063 return ParsePrimaryExpression(&is_async, ok); |
1072 } | 1064 } |
1073 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 1065 |
1074 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 1066 // This method wraps the parsing of the expression inside a new expression |
1075 bool* ok); | 1067 // classifier and calls the RewriteNonPattern if parsing is successful. |
adamk
2016/08/30 22:24:52
Nit: s/the RewriteNonPattern/RewriteNonPattern/
nickie
2016/08/31 08:19:53
Done.
| |
1076 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 1068 V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok); |
1069 // This method does not wrap the parsing of the expression inside a | |
1070 // new expression classifier; it uses the top-level classifier instead. | |
adamk
2016/08/30 22:24:52
I think this comment should explain a bit more of
nickie
2016/08/31 08:19:53
Done. It now reads:
// This method wraps the par
| |
1071 ExpressionT ParseExpressionNoWrap(bool accept_IN, bool* ok); | |
adamk
2016/08/30 22:24:52
"ParseExpressionNoWrap" isn't at all clear to me.
nickie
2016/08/31 08:19:53
Before giving this a different name, I tried a few
adamk
2016/08/31 18:15:21
I like the comment (and the reference to CoverPare
| |
1072 | |
1073 ExpressionT ParseArrayLiteral(bool* ok); | |
1077 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 1074 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
1078 bool* is_computed_name, | 1075 bool* is_computed_name, bool* ok); |
1079 ExpressionClassifier* classifier, bool* ok); | 1076 ExpressionT ParseObjectLiteral(bool* ok); |
1080 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | |
1081 ObjectLiteralPropertyT ParsePropertyDefinition( | 1077 ObjectLiteralPropertyT ParsePropertyDefinition( |
1082 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1078 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1083 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, | 1079 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor, |
1084 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 1080 IdentifierT* name, bool* ok); |
1085 typename Types::ExpressionList ParseArguments( | 1081 typename Types::ExpressionList ParseArguments( |
1086 Scanner::Location* first_spread_pos, bool maybe_arrow, | 1082 Scanner::Location* first_spread_pos, bool maybe_arrow, bool* ok); |
1087 ExpressionClassifier* classifier, bool* ok); | |
1088 typename Types::ExpressionList ParseArguments( | 1083 typename Types::ExpressionList ParseArguments( |
1089 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1084 Scanner::Location* first_spread_pos, bool* ok) { |
1090 bool* ok) { | 1085 return ParseArguments(first_spread_pos, false, ok); |
1091 return ParseArguments(first_spread_pos, false, classifier, ok); | |
1092 } | 1086 } |
1093 | 1087 |
1094 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1088 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
1095 ExpressionClassifier* classifier, | 1089 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
1096 bool* ok); | 1090 ExpressionT ParseTailCallExpression(bool* ok); |
1097 ExpressionT ParseYieldExpression(bool accept_IN, | 1091 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
1098 ExpressionClassifier* classifier, bool* ok); | 1092 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
1099 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 1093 ExpressionT ParseUnaryExpression(bool* ok); |
1100 bool* ok); | 1094 ExpressionT ParsePostfixExpression(bool* ok); |
1101 ExpressionT ParseConditionalExpression(bool accept_IN, | 1095 ExpressionT ParseLeftHandSideExpression(bool* ok); |
1102 ExpressionClassifier* classifier, | 1096 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); |
1103 bool* ok); | 1097 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); |
1104 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1098 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
1105 ExpressionClassifier* classifier, bool* ok); | 1099 bool* is_async, bool* ok); |
1106 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | |
1107 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | |
1108 bool* ok); | |
1109 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | |
1110 bool* ok); | |
1111 ExpressionT ParseMemberWithNewPrefixesExpression( | |
1112 ExpressionClassifier* classifier, bool* is_async, bool* ok); | |
1113 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, | |
1114 bool* is_async, bool* ok); | |
1115 ExpressionT ParseMemberExpressionContinuation( | |
1116 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | |
1117 bool* ok); | |
1118 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1100 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
1119 const FormalParametersT& parameters, | 1101 const FormalParametersT& parameters, |
1120 bool is_async, | 1102 bool is_async, |
1121 const ExpressionClassifier& classifier, | |
1122 bool* ok); | 1103 bool* ok); |
1123 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 1104 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
1124 ExpressionClassifier* classifier, bool* ok); | |
1125 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1105 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
1126 ExpressionT ParseNewTargetExpression(bool* ok); | 1106 ExpressionT ParseNewTargetExpression(bool* ok); |
1127 | 1107 |
1128 void ParseFormalParameter(FormalParametersT* parameters, | 1108 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); |
1129 ExpressionClassifier* classifier, bool* ok); | 1109 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); |
1130 void ParseFormalParameterList(FormalParametersT* parameters, | |
1131 ExpressionClassifier* classifier, bool* ok); | |
1132 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1110 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1133 bool has_rest, int formals_start_pos, | 1111 bool has_rest, int formals_start_pos, |
1134 int formals_end_pos, bool* ok); | 1112 int formals_end_pos, bool* ok); |
1135 | 1113 |
1136 bool IsNextLetKeyword(); | 1114 bool IsNextLetKeyword(); |
1137 bool IsTrivialExpression(); | 1115 bool IsTrivialExpression(); |
1138 | 1116 |
1139 // Checks if the expression is a valid reference expression (e.g., on the | 1117 // Checks if the expression is a valid reference expression (e.g., on the |
1140 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1118 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1141 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1119 // we allow calls for web compatibility and rewrite them to a runtime throw. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1184 kAccessorProperty, | 1162 kAccessorProperty, |
1185 kValueProperty, | 1163 kValueProperty, |
1186 kMethodProperty | 1164 kMethodProperty |
1187 }; | 1165 }; |
1188 | 1166 |
1189 class ObjectLiteralCheckerBase { | 1167 class ObjectLiteralCheckerBase { |
1190 public: | 1168 public: |
1191 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 1169 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
1192 | 1170 |
1193 virtual void CheckProperty(Token::Value property, PropertyKind type, | 1171 virtual void CheckProperty(Token::Value property, PropertyKind type, |
1194 MethodKind method_type, | 1172 MethodKind method_type, bool* ok) = 0; |
1195 ExpressionClassifier* classifier, bool* ok) = 0; | |
1196 | 1173 |
1197 virtual ~ObjectLiteralCheckerBase() {} | 1174 virtual ~ObjectLiteralCheckerBase() {} |
1198 | 1175 |
1199 protected: | 1176 protected: |
1200 ParserBase* parser() const { return parser_; } | 1177 ParserBase* parser() const { return parser_; } |
1201 Scanner* scanner() const { return parser_->scanner(); } | 1178 Scanner* scanner() const { return parser_->scanner(); } |
1202 | 1179 |
1203 private: | 1180 private: |
1204 ParserBase* parser_; | 1181 ParserBase* parser_; |
1205 }; | 1182 }; |
1206 | 1183 |
1207 // Validation per ES6 object literals. | 1184 // Validation per ES6 object literals. |
1208 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { | 1185 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { |
1209 public: | 1186 public: |
1210 explicit ObjectLiteralChecker(ParserBase* parser) | 1187 explicit ObjectLiteralChecker(ParserBase* parser) |
1211 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} | 1188 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} |
1212 | 1189 |
1213 void CheckProperty(Token::Value property, PropertyKind type, | 1190 void CheckProperty(Token::Value property, PropertyKind type, |
1214 MethodKind method_type, ExpressionClassifier* classifier, | 1191 MethodKind method_type, bool* ok) override; |
1215 bool* ok) override; | |
1216 | 1192 |
1217 private: | 1193 private: |
1218 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } | 1194 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } |
1219 | 1195 |
1220 bool has_seen_proto_; | 1196 bool has_seen_proto_; |
1221 }; | 1197 }; |
1222 | 1198 |
1223 // Validation per ES6 class literals. | 1199 // Validation per ES6 class literals. |
1224 class ClassLiteralChecker : public ObjectLiteralCheckerBase { | 1200 class ClassLiteralChecker : public ObjectLiteralCheckerBase { |
1225 public: | 1201 public: |
1226 explicit ClassLiteralChecker(ParserBase* parser) | 1202 explicit ClassLiteralChecker(ParserBase* parser) |
1227 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} | 1203 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} |
1228 | 1204 |
1229 void CheckProperty(Token::Value property, PropertyKind type, | 1205 void CheckProperty(Token::Value property, PropertyKind type, |
1230 MethodKind method_type, ExpressionClassifier* classifier, | 1206 MethodKind method_type, bool* ok) override; |
1231 bool* ok) override; | |
1232 | 1207 |
1233 private: | 1208 private: |
1234 bool IsConstructor() { | 1209 bool IsConstructor() { |
1235 return this->scanner()->LiteralMatches("constructor", 11); | 1210 return this->scanner()->LiteralMatches("constructor", 11); |
1236 } | 1211 } |
1237 bool IsPrototype() { | 1212 bool IsPrototype() { |
1238 return this->scanner()->LiteralMatches("prototype", 9); | 1213 return this->scanner()->LiteralMatches("prototype", 9); |
1239 } | 1214 } |
1240 | 1215 |
1241 bool has_seen_constructor_; | 1216 bool has_seen_constructor_; |
1242 }; | 1217 }; |
1243 | 1218 |
1244 ModuleDescriptor* module() const { | 1219 ModuleDescriptor* module() const { |
1245 return scope()->AsModuleScope()->module(); | 1220 return scope()->AsModuleScope()->module(); |
1246 } | 1221 } |
1247 Scope* scope() const { return scope_state_->scope(); } | 1222 Scope* scope() const { return scope_state_->scope(); } |
1248 | 1223 |
1224 // Stack of expression classifiers. | |
1225 // The top of the stack is always pointed to by classifier(). | |
1226 V8_INLINE ExpressionClassifier* classifier() const { | |
1227 DCHECK_NOT_NULL(classifier_); | |
1228 return classifier_; | |
1229 } | |
1230 | |
1231 // Accumulates the classifier that is on top of the stack (inner) to | |
1232 // the one that is right below (outer) and pops the inner. | |
1233 V8_INLINE void Accumulate(unsigned productions, | |
1234 bool merge_non_patterns = true) { | |
1235 DCHECK_NOT_NULL(classifier_); | |
1236 ExpressionClassifier* previous = classifier_->previous(); | |
1237 DCHECK_NOT_NULL(previous); | |
1238 previous->Accumulate(classifier_, productions, merge_non_patterns); | |
1239 classifier_ = previous; | |
1240 } | |
1241 | |
1242 // Pops and discards the classifier that is on top of the stack | |
1243 // without accumulating. | |
1244 V8_INLINE void Discard() { | |
1245 DCHECK_NOT_NULL(classifier_); | |
1246 classifier_->Discard(); | |
1247 classifier_ = classifier_->previous(); | |
1248 } | |
1249 | |
1250 // Accumulate errors that can be arbitrarily deep in an expression. | |
1251 // These correspond to the ECMAScript spec's 'Contains' operation | |
1252 // on productions. This includes: | |
1253 // | |
1254 // - YieldExpression is disallowed in arrow parameters in a generator. | |
1255 // - AwaitExpression is disallowed in arrow parameters in an async function. | |
1256 // - AwaitExpression is disallowed in async arrow parameters. | |
1257 // | |
1258 V8_INLINE void AccumulateFormalParameterContainmentErrors() { | |
1259 Accumulate(ExpressionClassifier::FormalParameterInitializerProduction | | |
1260 ExpressionClassifier::AsyncArrowFormalParametersProduction); | |
1261 } | |
1262 | |
1263 // Parser base's protected field members. | |
1264 | |
1249 ScopeState* scope_state_; // Scope stack. | 1265 ScopeState* scope_state_; // Scope stack. |
1250 FunctionState* function_state_; // Function state stack. | 1266 FunctionState* function_state_; // Function state stack. |
1251 v8::Extension* extension_; | 1267 v8::Extension* extension_; |
1252 FuncNameInferrer* fni_; | 1268 FuncNameInferrer* fni_; |
1253 AstValueFactory* ast_value_factory_; // Not owned. | 1269 AstValueFactory* ast_value_factory_; // Not owned. |
1254 typename Types::Factory ast_node_factory_; | 1270 typename Types::Factory ast_node_factory_; |
1255 ParserRecorder* log_; | 1271 ParserRecorder* log_; |
1256 Mode mode_; | 1272 Mode mode_; |
1257 bool parsing_module_; | 1273 bool parsing_module_; |
1258 uintptr_t stack_limit_; | 1274 uintptr_t stack_limit_; |
1259 | 1275 |
1276 // Parser base's private field members. | |
1277 | |
1260 private: | 1278 private: |
1261 Zone* zone_; | 1279 Zone* zone_; |
1280 ExpressionClassifier* classifier_; | |
1262 | 1281 |
1263 Scanner* scanner_; | 1282 Scanner* scanner_; |
1264 bool stack_overflow_; | 1283 bool stack_overflow_; |
1265 | 1284 |
1266 bool allow_lazy_; | 1285 bool allow_lazy_; |
1267 bool allow_natives_; | 1286 bool allow_natives_; |
1268 bool allow_tailcalls_; | 1287 bool allow_tailcalls_; |
1269 bool allow_harmony_restrictive_declarations_; | 1288 bool allow_harmony_restrictive_declarations_; |
1270 bool allow_harmony_do_expressions_; | 1289 bool allow_harmony_do_expressions_; |
1271 bool allow_harmony_for_in_; | 1290 bool allow_harmony_for_in_; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1378 MessageTemplate::Template message) { | 1397 MessageTemplate::Template message) { |
1379 const char* arg; | 1398 const char* arg; |
1380 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); | 1399 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); |
1381 impl()->ReportMessageAt(source_location, message, arg); | 1400 impl()->ReportMessageAt(source_location, message, arg); |
1382 } | 1401 } |
1383 | 1402 |
1384 template <typename Impl> | 1403 template <typename Impl> |
1385 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( | 1404 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( |
1386 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 1405 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
1387 ExpressionClassifier classifier(this); | 1406 ExpressionClassifier classifier(this); |
1388 auto result = | 1407 auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(EmptyIdentifier)); |
1389 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | |
1390 | 1408 |
1391 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { | 1409 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
1392 ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1410 ValidateAssignmentPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); |
1393 ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1411 ValidateBindingPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); |
1394 } | 1412 } |
1395 | 1413 |
1396 return result; | 1414 return result; |
1397 } | 1415 } |
1398 | 1416 |
1399 template <typename Impl> | 1417 template <typename Impl> |
1400 typename ParserBase<Impl>::IdentifierT | 1418 typename ParserBase<Impl>::IdentifierT |
1401 ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1419 ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) { |
1402 bool* ok) { | |
1403 Token::Value next = Next(); | 1420 Token::Value next = Next(); |
1404 if (next == Token::IDENTIFIER || next == Token::ASYNC || | 1421 if (next == Token::IDENTIFIER || next == Token::ASYNC || |
1405 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { | 1422 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { |
1406 IdentifierT name = impl()->GetSymbol(); | 1423 IdentifierT name = impl()->GetSymbol(); |
1407 // When this function is used to read a formal parameter, we don't always | 1424 // When this function is used to read a formal parameter, we don't always |
1408 // know whether the function is going to be strict or sloppy. Indeed for | 1425 // know whether the function is going to be strict or sloppy. Indeed for |
1409 // arrow functions we don't always know that the identifier we are reading | 1426 // arrow functions we don't always know that the identifier we are reading |
1410 // is actually a formal parameter. Therefore besides the errors that we | 1427 // is actually a formal parameter. Therefore besides the errors that we |
1411 // must detect because we know we're in strict mode, we also record any | 1428 // must detect because we know we're in strict mode, we also record any |
1412 // error that we might make in the future once we know the language mode. | 1429 // error that we might make in the future once we know the language mode. |
1413 if (impl()->IsEvalOrArguments(name)) { | 1430 if (impl()->IsEvalOrArguments(name)) { |
1414 classifier->RecordStrictModeFormalParameterError( | 1431 classifier()->RecordStrictModeFormalParameterError( |
1415 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1432 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1416 if (is_strict(language_mode())) { | 1433 if (is_strict(language_mode())) { |
1417 classifier->RecordBindingPatternError( | 1434 classifier()->RecordBindingPatternError( |
1418 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1435 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1419 } | 1436 } |
1420 } else if (next == Token::AWAIT) { | 1437 } else if (next == Token::AWAIT) { |
1421 classifier->RecordAsyncArrowFormalParametersError( | 1438 classifier()->RecordAsyncArrowFormalParametersError( |
1422 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | 1439 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); |
1423 } | 1440 } |
1424 | 1441 |
1425 if (classifier->duplicate_finder() != nullptr && | 1442 if (classifier()->duplicate_finder() != nullptr && |
1426 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1443 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { |
1427 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1444 classifier()->RecordDuplicateFormalParameterError(scanner()->location()); |
1428 } | 1445 } |
1429 return name; | 1446 return name; |
1430 } else if (is_sloppy(language_mode()) && | 1447 } else if (is_sloppy(language_mode()) && |
1431 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1448 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
1432 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1449 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
1433 next == Token::LET || next == Token::STATIC || | 1450 next == Token::LET || next == Token::STATIC || |
1434 (next == Token::YIELD && !is_generator()))) { | 1451 (next == Token::YIELD && !is_generator()))) { |
1435 classifier->RecordStrictModeFormalParameterError( | 1452 classifier()->RecordStrictModeFormalParameterError( |
1436 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); | 1453 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
1437 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1454 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
1438 is_strict(language_mode())) { | 1455 is_strict(language_mode())) { |
1439 ReportUnexpectedToken(next); | 1456 ReportUnexpectedToken(next); |
1440 *ok = false; | 1457 *ok = false; |
1441 return impl()->EmptyIdentifier(); | 1458 return impl()->EmptyIdentifier(); |
1442 } | 1459 } |
1443 if (next == Token::LET || | 1460 if (next == Token::LET || |
1444 (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1461 (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
1445 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { | 1462 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { |
1446 classifier->RecordLetPatternError(scanner()->location(), | 1463 classifier()->RecordLetPatternError( |
1447 MessageTemplate::kLetInLexicalBinding); | 1464 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1448 } | 1465 } |
1449 return impl()->GetSymbol(); | 1466 return impl()->GetSymbol(); |
1450 } else { | 1467 } else { |
1451 ReportUnexpectedToken(next); | 1468 ReportUnexpectedToken(next); |
1452 *ok = false; | 1469 *ok = false; |
1453 return impl()->EmptyIdentifier(); | 1470 return impl()->EmptyIdentifier(); |
1454 } | 1471 } |
1455 } | 1472 } |
1456 | 1473 |
1457 template <class Impl> | 1474 template <class Impl> |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1515 *ok = false; | 1532 *ok = false; |
1516 return impl()->EmptyExpression(); | 1533 return impl()->EmptyExpression(); |
1517 } | 1534 } |
1518 int js_flags = flags.FromJust(); | 1535 int js_flags = flags.FromJust(); |
1519 Next(); | 1536 Next(); |
1520 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1537 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
1521 } | 1538 } |
1522 | 1539 |
1523 template <typename Impl> | 1540 template <typename Impl> |
1524 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( | 1541 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( |
1525 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 1542 bool* is_async, bool* ok) { |
1526 // PrimaryExpression :: | 1543 // PrimaryExpression :: |
1527 // 'this' | 1544 // 'this' |
1528 // 'null' | 1545 // 'null' |
1529 // 'true' | 1546 // 'true' |
1530 // 'false' | 1547 // 'false' |
1531 // Identifier | 1548 // Identifier |
1532 // Number | 1549 // Number |
1533 // String | 1550 // String |
1534 // ArrayLiteral | 1551 // ArrayLiteral |
1535 // ObjectLiteral | 1552 // ObjectLiteral |
1536 // RegExpLiteral | 1553 // RegExpLiteral |
1537 // ClassLiteral | 1554 // ClassLiteral |
1538 // '(' Expression ')' | 1555 // '(' Expression ')' |
1539 // TemplateLiteral | 1556 // TemplateLiteral |
1540 // do Block | 1557 // do Block |
1541 // AsyncFunctionExpression | 1558 // AsyncFunctionExpression |
1542 | 1559 |
1543 int beg_pos = peek_position(); | 1560 int beg_pos = peek_position(); |
1544 switch (peek()) { | 1561 switch (peek()) { |
1545 case Token::THIS: { | 1562 case Token::THIS: { |
1546 BindingPatternUnexpectedToken(classifier); | 1563 BindingPatternUnexpectedToken(); |
1547 Consume(Token::THIS); | 1564 Consume(Token::THIS); |
1548 return impl()->ThisExpression(beg_pos); | 1565 return impl()->ThisExpression(beg_pos); |
1549 } | 1566 } |
1550 | 1567 |
1551 case Token::NULL_LITERAL: | 1568 case Token::NULL_LITERAL: |
1552 case Token::TRUE_LITERAL: | 1569 case Token::TRUE_LITERAL: |
1553 case Token::FALSE_LITERAL: | 1570 case Token::FALSE_LITERAL: |
1554 case Token::SMI: | 1571 case Token::SMI: |
1555 case Token::NUMBER: | 1572 case Token::NUMBER: |
1556 BindingPatternUnexpectedToken(classifier); | 1573 BindingPatternUnexpectedToken(); |
1557 return impl()->ExpressionFromLiteral(Next(), beg_pos); | 1574 return impl()->ExpressionFromLiteral(Next(), beg_pos); |
1558 | 1575 |
1559 case Token::ASYNC: | 1576 case Token::ASYNC: |
1560 if (allow_harmony_async_await() && | 1577 if (allow_harmony_async_await() && |
1561 !scanner()->HasAnyLineTerminatorAfterNext() && | 1578 !scanner()->HasAnyLineTerminatorAfterNext() && |
1562 PeekAhead() == Token::FUNCTION) { | 1579 PeekAhead() == Token::FUNCTION) { |
1563 Consume(Token::ASYNC); | 1580 Consume(Token::ASYNC); |
1564 return impl()->ParseAsyncFunctionExpression(CHECK_OK); | 1581 return impl()->ParseAsyncFunctionExpression(CHECK_OK); |
1565 } | 1582 } |
1566 // CoverCallExpressionAndAsyncArrowHead | 1583 // CoverCallExpressionAndAsyncArrowHead |
1567 *is_async = true; | 1584 *is_async = true; |
1568 /* falls through */ | 1585 /* falls through */ |
1569 case Token::IDENTIFIER: | 1586 case Token::IDENTIFIER: |
1570 case Token::LET: | 1587 case Token::LET: |
1571 case Token::STATIC: | 1588 case Token::STATIC: |
1572 case Token::YIELD: | 1589 case Token::YIELD: |
1573 case Token::AWAIT: | 1590 case Token::AWAIT: |
1574 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1591 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1575 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1592 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1576 // Using eval or arguments in this context is OK even in strict mode. | 1593 // Using eval or arguments in this context is OK even in strict mode. |
1577 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1594 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); |
1578 return impl()->ExpressionFromIdentifier(name, beg_pos, | 1595 return impl()->ExpressionFromIdentifier(name, beg_pos, |
1579 scanner()->location().end_pos); | 1596 scanner()->location().end_pos); |
1580 } | 1597 } |
1581 | 1598 |
1582 case Token::STRING: { | 1599 case Token::STRING: { |
1583 BindingPatternUnexpectedToken(classifier); | 1600 BindingPatternUnexpectedToken(); |
1584 Consume(Token::STRING); | 1601 Consume(Token::STRING); |
1585 return impl()->ExpressionFromString(beg_pos); | 1602 return impl()->ExpressionFromString(beg_pos); |
1586 } | 1603 } |
1587 | 1604 |
1588 case Token::ASSIGN_DIV: | 1605 case Token::ASSIGN_DIV: |
1589 case Token::DIV: | 1606 case Token::DIV: |
1590 classifier->RecordBindingPatternError( | 1607 classifier()->RecordBindingPatternError( |
1591 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); | 1608 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); |
1592 return ParseRegExpLiteral(ok); | 1609 return ParseRegExpLiteral(ok); |
1593 | 1610 |
1594 case Token::LBRACK: | 1611 case Token::LBRACK: |
1595 return ParseArrayLiteral(classifier, ok); | 1612 return ParseArrayLiteral(ok); |
1596 | 1613 |
1597 case Token::LBRACE: | 1614 case Token::LBRACE: |
1598 return ParseObjectLiteral(classifier, ok); | 1615 return ParseObjectLiteral(ok); |
1599 | 1616 |
1600 case Token::LPAREN: { | 1617 case Token::LPAREN: { |
1601 // Arrow function formal parameters are either a single identifier or a | 1618 // Arrow function formal parameters are either a single identifier or a |
1602 // list of BindingPattern productions enclosed in parentheses. | 1619 // list of BindingPattern productions enclosed in parentheses. |
1603 // Parentheses are not valid on the LHS of a BindingPattern, so we use the | 1620 // Parentheses are not valid on the LHS of a BindingPattern, so we use the |
1604 // is_valid_binding_pattern() check to detect multiple levels of | 1621 // is_valid_binding_pattern() check to detect multiple levels of |
1605 // parenthesization. | 1622 // parenthesization. |
1606 bool pattern_error = !classifier->is_valid_binding_pattern(); | 1623 bool pattern_error = !classifier()->is_valid_binding_pattern(); |
1607 classifier->RecordPatternError(scanner()->peek_location(), | 1624 classifier()->RecordPatternError(scanner()->peek_location(), |
1608 MessageTemplate::kUnexpectedToken, | 1625 MessageTemplate::kUnexpectedToken, |
1609 Token::String(Token::LPAREN)); | 1626 Token::String(Token::LPAREN)); |
1610 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); | 1627 if (pattern_error) ArrowFormalParametersUnexpectedToken(); |
1611 Consume(Token::LPAREN); | 1628 Consume(Token::LPAREN); |
1612 if (Check(Token::RPAREN)) { | 1629 if (Check(Token::RPAREN)) { |
1613 // ()=>x. The continuation that looks for the => is in | 1630 // ()=>x. The continuation that looks for the => is in |
1614 // ParseAssignmentExpression. | 1631 // ParseAssignmentExpression. |
1615 classifier->RecordExpressionError(scanner()->location(), | 1632 classifier()->RecordExpressionError(scanner()->location(), |
1616 MessageTemplate::kUnexpectedToken, | 1633 MessageTemplate::kUnexpectedToken, |
1617 Token::String(Token::RPAREN)); | 1634 Token::String(Token::RPAREN)); |
1618 return factory()->NewEmptyParentheses(beg_pos); | 1635 return factory()->NewEmptyParentheses(beg_pos); |
1619 } else if (Check(Token::ELLIPSIS)) { | 1636 } else if (Check(Token::ELLIPSIS)) { |
1620 // (...x)=>x. The continuation that looks for the => is in | 1637 // (...x)=>x. The continuation that looks for the => is in |
1621 // ParseAssignmentExpression. | 1638 // ParseAssignmentExpression. |
1622 int ellipsis_pos = position(); | 1639 int ellipsis_pos = position(); |
1623 int expr_pos = peek_position(); | 1640 int expr_pos = peek_position(); |
1624 classifier->RecordExpressionError(scanner()->location(), | 1641 classifier()->RecordExpressionError(scanner()->location(), |
1625 MessageTemplate::kUnexpectedToken, | 1642 MessageTemplate::kUnexpectedToken, |
1626 Token::String(Token::ELLIPSIS)); | 1643 Token::String(Token::ELLIPSIS)); |
1627 classifier->RecordNonSimpleParameter(); | 1644 classifier()->RecordNonSimpleParameter(); |
1628 ExpressionClassifier binding_classifier(this); | 1645 ExpressionClassifier binding_classifier(this); |
1629 // TODO(adamk): The grammar for this is | 1646 // TODO(adamk): The grammar for this is |
1630 // BindingIdentifier | BindingPattern, so | 1647 // BindingIdentifier | BindingPattern, so |
1631 // ParseAssignmentExpression is overkill. | 1648 // ParseAssignmentExpression is overkill. |
1632 ExpressionT expr = | 1649 ExpressionT expr = ParseAssignmentExpression(true, CHECK_OK); |
1633 ParseAssignmentExpression(true, &binding_classifier, CHECK_OK); | |
1634 // This already couldn't be an expression or a pattern, so the | 1650 // This already couldn't be an expression or a pattern, so the |
1635 // only remaining possibility is an arrow formal parameter list. | 1651 // only remaining possibility is an arrow formal parameter list. |
1636 classifier->Accumulate( | 1652 impl()->Accumulate( |
1637 &binding_classifier, | |
1638 ExpressionClassifier::ArrowFormalParametersProduction); | 1653 ExpressionClassifier::ArrowFormalParametersProduction); |
1639 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { | 1654 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { |
1640 classifier->RecordArrowFormalParametersError( | 1655 classifier()->RecordArrowFormalParametersError( |
1641 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), | 1656 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), |
1642 MessageTemplate::kInvalidRestParameter); | 1657 MessageTemplate::kInvalidRestParameter); |
1643 } | 1658 } |
1644 if (peek() == Token::COMMA) { | 1659 if (peek() == Token::COMMA) { |
1645 impl()->ReportMessageAt(scanner()->peek_location(), | 1660 impl()->ReportMessageAt(scanner()->peek_location(), |
1646 MessageTemplate::kParamAfterRest); | 1661 MessageTemplate::kParamAfterRest); |
1647 *ok = false; | 1662 *ok = false; |
1648 return impl()->EmptyExpression(); | 1663 return impl()->EmptyExpression(); |
1649 } | 1664 } |
1650 Expect(Token::RPAREN, CHECK_OK); | 1665 Expect(Token::RPAREN, CHECK_OK); |
1651 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); | 1666 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); |
1652 } | 1667 } |
1653 // Heuristically try to detect immediately called functions before | 1668 // Heuristically try to detect immediately called functions before |
1654 // seeing the call parentheses. | 1669 // seeing the call parentheses. |
1655 function_state_->set_next_function_is_parenthesized(peek() == | 1670 function_state_->set_next_function_is_parenthesized(peek() == |
1656 Token::FUNCTION); | 1671 Token::FUNCTION); |
1657 ExpressionT expr = ParseExpression(true, classifier, CHECK_OK); | 1672 ExpressionT expr = ParseExpressionNoWrap(true, CHECK_OK); |
1658 Expect(Token::RPAREN, CHECK_OK); | 1673 Expect(Token::RPAREN, CHECK_OK); |
1659 return expr; | 1674 return expr; |
1660 } | 1675 } |
1661 | 1676 |
1662 case Token::CLASS: { | 1677 case Token::CLASS: { |
1663 BindingPatternUnexpectedToken(classifier); | 1678 BindingPatternUnexpectedToken(); |
1664 Consume(Token::CLASS); | 1679 Consume(Token::CLASS); |
1665 int class_token_position = position(); | 1680 int class_token_position = position(); |
1666 IdentifierT name = impl()->EmptyIdentifier(); | 1681 IdentifierT name = impl()->EmptyIdentifier(); |
1667 bool is_strict_reserved_name = false; | 1682 bool is_strict_reserved_name = false; |
1668 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1683 Scanner::Location class_name_location = Scanner::Location::invalid(); |
1669 if (peek_any_identifier()) { | 1684 if (peek_any_identifier()) { |
1670 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1685 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
1671 CHECK_OK); | 1686 CHECK_OK); |
1672 class_name_location = scanner()->location(); | 1687 class_name_location = scanner()->location(); |
1673 } | 1688 } |
1674 return impl()->ParseClassLiteral(classifier, name, class_name_location, | 1689 return impl()->ParseClassLiteral(name, class_name_location, |
1675 is_strict_reserved_name, | 1690 is_strict_reserved_name, |
1676 class_token_position, ok); | 1691 class_token_position, ok); |
1677 } | 1692 } |
1678 | 1693 |
1679 case Token::TEMPLATE_SPAN: | 1694 case Token::TEMPLATE_SPAN: |
1680 case Token::TEMPLATE_TAIL: | 1695 case Token::TEMPLATE_TAIL: |
1681 BindingPatternUnexpectedToken(classifier); | 1696 BindingPatternUnexpectedToken(); |
1682 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, classifier, | 1697 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok); |
1683 ok); | |
1684 | 1698 |
1685 case Token::MOD: | 1699 case Token::MOD: |
1686 if (allow_natives() || extension_ != NULL) { | 1700 if (allow_natives() || extension_ != NULL) { |
1687 BindingPatternUnexpectedToken(classifier); | 1701 BindingPatternUnexpectedToken(); |
1688 return impl()->ParseV8Intrinsic(ok); | 1702 return impl()->ParseV8Intrinsic(ok); |
1689 } | 1703 } |
1690 break; | 1704 break; |
1691 | 1705 |
1692 case Token::DO: | 1706 case Token::DO: |
1693 if (allow_harmony_do_expressions()) { | 1707 if (allow_harmony_do_expressions()) { |
1694 BindingPatternUnexpectedToken(classifier); | 1708 BindingPatternUnexpectedToken(); |
1695 return impl()->ParseDoExpression(ok); | 1709 return impl()->ParseDoExpression(ok); |
1696 } | 1710 } |
1697 break; | 1711 break; |
1698 | 1712 |
1699 default: | 1713 default: |
1700 break; | 1714 break; |
1701 } | 1715 } |
1702 | 1716 |
1703 ReportUnexpectedToken(Next()); | 1717 ReportUnexpectedToken(Next()); |
1704 *ok = false; | 1718 *ok = false; |
1705 return impl()->EmptyExpression(); | 1719 return impl()->EmptyExpression(); |
1706 } | 1720 } |
1707 | 1721 |
1708 template <typename Impl> | 1722 template <typename Impl> |
1709 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1723 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1710 bool accept_IN, bool* ok) { | 1724 bool accept_IN, bool* ok) { |
1711 ExpressionClassifier classifier(this); | 1725 ExpressionClassifier classifier(this); |
1712 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1726 ExpressionT result = ParseExpressionNoWrap(accept_IN, CHECK_OK); |
1713 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 1727 impl()->RewriteNonPattern(CHECK_OK); |
1714 return result; | 1728 return result; |
1715 } | 1729 } |
1716 | 1730 |
1717 template <typename Impl> | 1731 template <typename Impl> |
1718 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1732 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpressionNoWrap( |
1719 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1733 bool accept_IN, bool* ok) { |
1720 // Expression :: | 1734 // Expression :: |
1721 // AssignmentExpression | 1735 // AssignmentExpression |
1722 // Expression ',' AssignmentExpression | 1736 // Expression ',' AssignmentExpression |
1723 | 1737 |
1724 ExpressionT result; | 1738 ExpressionT result; |
1725 | 1739 |
1726 // No need to accumulate binding pattern-related errors, since | 1740 // No need to accumulate binding pattern-related errors, since |
1727 // an Expression can't be a binding pattern anyway. | 1741 // an Expression can't be a binding pattern anyway. |
1728 static const unsigned kExpressionProductions = | 1742 static const unsigned kExpressionProductions = |
1729 ExpressionClassifier::AllProductions & | 1743 ExpressionClassifier::AllProductions & |
1730 ~(ExpressionClassifier::BindingPatternProduction | | 1744 ~(ExpressionClassifier::BindingPatternProduction | |
1731 ExpressionClassifier::LetPatternProduction); | 1745 ExpressionClassifier::LetPatternProduction); |
1732 { | 1746 { |
1733 ExpressionClassifier binding_classifier(this); | 1747 ExpressionClassifier binding_classifier(this); |
1734 result = | 1748 result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
1735 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1749 impl()->Accumulate(kExpressionProductions); |
1736 classifier->Accumulate(&binding_classifier, kExpressionProductions); | |
1737 } | 1750 } |
1738 bool is_simple_parameter_list = impl()->IsIdentifier(result); | 1751 bool is_simple_parameter_list = impl()->IsIdentifier(result); |
1739 bool seen_rest = false; | 1752 bool seen_rest = false; |
1740 while (peek() == Token::COMMA) { | 1753 while (peek() == Token::COMMA) { |
1741 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1754 CheckNoTailCallExpressions(CHECK_OK); |
1742 if (seen_rest) { | 1755 if (seen_rest) { |
1743 // At this point the production can't possibly be valid, but we don't know | 1756 // At this point the production can't possibly be valid, but we don't know |
1744 // which error to signal. | 1757 // which error to signal. |
1745 classifier->RecordArrowFormalParametersError( | 1758 classifier()->RecordArrowFormalParametersError( |
1746 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1759 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1747 } | 1760 } |
1748 Consume(Token::COMMA); | 1761 Consume(Token::COMMA); |
1749 bool is_rest = false; | 1762 bool is_rest = false; |
1750 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && | 1763 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && |
1751 PeekAhead() == Token::ARROW) { | 1764 PeekAhead() == Token::ARROW) { |
1752 // a trailing comma is allowed at the end of an arrow parameter list | 1765 // a trailing comma is allowed at the end of an arrow parameter list |
1753 break; | 1766 break; |
1754 } else if (peek() == Token::ELLIPSIS) { | 1767 } else if (peek() == Token::ELLIPSIS) { |
1755 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1768 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1756 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1769 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1757 // valid expression or binding pattern. | 1770 // valid expression or binding pattern. |
1758 ExpressionUnexpectedToken(classifier); | 1771 ExpressionUnexpectedToken(); |
1759 BindingPatternUnexpectedToken(classifier); | 1772 BindingPatternUnexpectedToken(); |
1760 Consume(Token::ELLIPSIS); | 1773 Consume(Token::ELLIPSIS); |
1761 // TODO(adamk): If is_rest is true we don't need to parse an assignment | 1774 // TODO(adamk): If is_rest is true we don't need to parse an assignment |
1762 // expression, the grammar is BindingIdentifier | BindingPattern. | 1775 // expression, the grammar is BindingIdentifier | BindingPattern. |
1763 seen_rest = is_rest = true; | 1776 seen_rest = is_rest = true; |
1764 } | 1777 } |
1765 int pos = position(), expr_pos = peek_position(); | 1778 int pos = position(), expr_pos = peek_position(); |
1766 ExpressionClassifier binding_classifier(this); | 1779 ExpressionClassifier binding_classifier(this); |
1767 ExpressionT right = | 1780 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
1768 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1781 impl()->Accumulate(kExpressionProductions); |
1769 classifier->Accumulate(&binding_classifier, kExpressionProductions); | |
1770 if (is_rest) { | 1782 if (is_rest) { |
1771 if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) { | 1783 if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) { |
1772 classifier->RecordArrowFormalParametersError( | 1784 classifier()->RecordArrowFormalParametersError( |
1773 Scanner::Location(pos, scanner()->location().end_pos), | 1785 Scanner::Location(pos, scanner()->location().end_pos), |
1774 MessageTemplate::kInvalidRestParameter); | 1786 MessageTemplate::kInvalidRestParameter); |
1775 } | 1787 } |
1776 right = factory()->NewSpread(right, pos, expr_pos); | 1788 right = factory()->NewSpread(right, pos, expr_pos); |
1777 } | 1789 } |
1778 is_simple_parameter_list = | 1790 is_simple_parameter_list = |
1779 is_simple_parameter_list && impl()->IsIdentifier(right); | 1791 is_simple_parameter_list && impl()->IsIdentifier(right); |
1780 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1792 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1781 } | 1793 } |
1782 if (!is_simple_parameter_list || seen_rest) { | 1794 if (!is_simple_parameter_list || seen_rest) { |
1783 classifier->RecordNonSimpleParameter(); | 1795 classifier()->RecordNonSimpleParameter(); |
1784 } | 1796 } |
1785 | 1797 |
1786 return result; | 1798 return result; |
1787 } | 1799 } |
1788 | 1800 |
1789 template <typename Impl> | 1801 template <typename Impl> |
1790 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( | 1802 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( |
1791 ExpressionClassifier* classifier, bool* ok) { | 1803 bool* ok) { |
1792 // ArrayLiteral :: | 1804 // ArrayLiteral :: |
1793 // '[' Expression? (',' Expression?)* ']' | 1805 // '[' Expression? (',' Expression?)* ']' |
1794 | 1806 |
1795 int pos = peek_position(); | 1807 int pos = peek_position(); |
1796 typename Types::ExpressionList values = impl()->NewExpressionList(4); | 1808 typename Types::ExpressionList values = impl()->NewExpressionList(4); |
1797 int first_spread_index = -1; | 1809 int first_spread_index = -1; |
1798 Expect(Token::LBRACK, CHECK_OK); | 1810 Expect(Token::LBRACK, CHECK_OK); |
1799 while (peek() != Token::RBRACK) { | 1811 while (peek() != Token::RBRACK) { |
1800 ExpressionT elem; | 1812 ExpressionT elem; |
1801 if (peek() == Token::COMMA) { | 1813 if (peek() == Token::COMMA) { |
1802 elem = impl()->GetLiteralTheHole(peek_position()); | 1814 elem = impl()->GetLiteralTheHole(peek_position()); |
1803 } else if (peek() == Token::ELLIPSIS) { | 1815 } else if (peek() == Token::ELLIPSIS) { |
1804 int start_pos = peek_position(); | 1816 int start_pos = peek_position(); |
1805 Consume(Token::ELLIPSIS); | 1817 Consume(Token::ELLIPSIS); |
1806 int expr_pos = peek_position(); | 1818 int expr_pos = peek_position(); |
1807 ExpressionT argument = | 1819 ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK); |
1808 ParseAssignmentExpression(true, classifier, CHECK_OK); | 1820 CheckNoTailCallExpressions(CHECK_OK); |
1809 CheckNoTailCallExpressions(classifier, CHECK_OK); | |
1810 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1821 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
1811 | 1822 |
1812 if (first_spread_index < 0) { | 1823 if (first_spread_index < 0) { |
1813 first_spread_index = values->length(); | 1824 first_spread_index = values->length(); |
1814 } | 1825 } |
1815 | 1826 |
1816 if (argument->IsAssignment()) { | 1827 if (argument->IsAssignment()) { |
1817 classifier->RecordPatternError( | 1828 classifier()->RecordPatternError( |
1818 Scanner::Location(start_pos, scanner()->location().end_pos), | 1829 Scanner::Location(start_pos, scanner()->location().end_pos), |
1819 MessageTemplate::kInvalidDestructuringTarget); | 1830 MessageTemplate::kInvalidDestructuringTarget); |
1820 } else { | 1831 } else { |
1821 CheckDestructuringElement(argument, classifier, start_pos, | 1832 CheckDestructuringElement(argument, start_pos, |
1822 scanner()->location().end_pos); | 1833 scanner()->location().end_pos); |
1823 } | 1834 } |
1824 | 1835 |
1825 if (peek() == Token::COMMA) { | 1836 if (peek() == Token::COMMA) { |
1826 classifier->RecordPatternError( | 1837 classifier()->RecordPatternError( |
1827 Scanner::Location(start_pos, scanner()->location().end_pos), | 1838 Scanner::Location(start_pos, scanner()->location().end_pos), |
1828 MessageTemplate::kElementAfterRest); | 1839 MessageTemplate::kElementAfterRest); |
1829 } | 1840 } |
1830 } else { | 1841 } else { |
1831 int beg_pos = peek_position(); | 1842 int beg_pos = peek_position(); |
1832 elem = ParseAssignmentExpression(true, classifier, CHECK_OK); | 1843 elem = ParseAssignmentExpression(true, CHECK_OK); |
1833 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1844 CheckNoTailCallExpressions(CHECK_OK); |
1834 CheckDestructuringElement(elem, classifier, beg_pos, | 1845 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos); |
1835 scanner()->location().end_pos); | |
1836 } | 1846 } |
1837 values->Add(elem, zone_); | 1847 values->Add(elem, zone_); |
1838 if (peek() != Token::RBRACK) { | 1848 if (peek() != Token::RBRACK) { |
1839 Expect(Token::COMMA, CHECK_OK); | 1849 Expect(Token::COMMA, CHECK_OK); |
1840 } | 1850 } |
1841 } | 1851 } |
1842 Expect(Token::RBRACK, CHECK_OK); | 1852 Expect(Token::RBRACK, CHECK_OK); |
1843 | 1853 |
1844 // Update the scope information before the pre-parsing bailout. | 1854 // Update the scope information before the pre-parsing bailout. |
1845 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1855 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
(...skipping 11 matching lines...) Expand all Loading... | |
1857 ReportMessage(MessageTemplate::kTooManySpreads); | 1867 ReportMessage(MessageTemplate::kTooManySpreads); |
1858 return impl()->EmptyExpression(); | 1868 return impl()->EmptyExpression(); |
1859 } | 1869 } |
1860 } | 1870 } |
1861 return result; | 1871 return result; |
1862 } | 1872 } |
1863 | 1873 |
1864 template <class Impl> | 1874 template <class Impl> |
1865 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 1875 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
1866 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1876 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, |
1867 ExpressionClassifier* classifier, bool* ok) { | 1877 bool* ok) { |
1868 Token::Value token = peek(); | 1878 Token::Value token = peek(); |
1869 int pos = peek_position(); | 1879 int pos = peek_position(); |
1870 | 1880 |
1871 // For non computed property names we normalize the name a bit: | 1881 // For non computed property names we normalize the name a bit: |
1872 // | 1882 // |
1873 // "12" -> 12 | 1883 // "12" -> 12 |
1874 // 12.3 -> "12.3" | 1884 // 12.3 -> "12.3" |
1875 // 12.30 -> "12.3" | 1885 // 12.30 -> "12.3" |
1876 // identifier -> "identifier" | 1886 // identifier -> "identifier" |
1877 // | 1887 // |
(...skipping 12 matching lines...) Expand all Loading... | |
1890 | 1900 |
1891 case Token::NUMBER: | 1901 case Token::NUMBER: |
1892 Consume(Token::NUMBER); | 1902 Consume(Token::NUMBER); |
1893 *name = impl()->GetNumberAsSymbol(); | 1903 *name = impl()->GetNumberAsSymbol(); |
1894 break; | 1904 break; |
1895 | 1905 |
1896 case Token::LBRACK: { | 1906 case Token::LBRACK: { |
1897 *is_computed_name = true; | 1907 *is_computed_name = true; |
1898 Consume(Token::LBRACK); | 1908 Consume(Token::LBRACK); |
1899 ExpressionClassifier computed_name_classifier(this); | 1909 ExpressionClassifier computed_name_classifier(this); |
1900 ExpressionT expression = | 1910 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
1901 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1911 impl()->RewriteNonPattern(CHECK_OK); |
1902 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1912 impl()->AccumulateFormalParameterContainmentErrors(); |
1903 classifier->AccumulateFormalParameterContainmentErrors( | |
1904 &computed_name_classifier); | |
1905 Expect(Token::RBRACK, CHECK_OK); | 1913 Expect(Token::RBRACK, CHECK_OK); |
1906 return expression; | 1914 return expression; |
1907 } | 1915 } |
1908 | 1916 |
1909 default: | 1917 default: |
1910 *name = ParseIdentifierName(CHECK_OK); | 1918 *name = ParseIdentifierName(CHECK_OK); |
1911 scanner()->IsGetOrSet(is_get, is_set); | 1919 scanner()->IsGetOrSet(is_get, is_set); |
1912 break; | 1920 break; |
1913 } | 1921 } |
1914 | 1922 |
1915 uint32_t index; | 1923 uint32_t index; |
1916 return impl()->IsArrayIndex(*name, &index) | 1924 return impl()->IsArrayIndex(*name, &index) |
1917 ? factory()->NewNumberLiteral(index, pos) | 1925 ? factory()->NewNumberLiteral(index, pos) |
1918 : factory()->NewStringLiteral(*name, pos); | 1926 : factory()->NewStringLiteral(*name, pos); |
1919 } | 1927 } |
1920 | 1928 |
1921 template <typename Impl> | 1929 template <typename Impl> |
1922 typename ParserBase<Impl>::ObjectLiteralPropertyT | 1930 typename ParserBase<Impl>::ObjectLiteralPropertyT |
1923 ParserBase<Impl>::ParsePropertyDefinition( | 1931 ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
1924 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1932 bool in_class, bool has_extends, |
1925 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, | 1933 MethodKind method_kind, |
1926 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1934 bool* is_computed_name, |
1935 bool* has_seen_constructor, | |
1936 IdentifierT* name, bool* ok) { | |
1927 DCHECK(!in_class || IsStaticMethod(method_kind) || | 1937 DCHECK(!in_class || IsStaticMethod(method_kind) || |
1928 has_seen_constructor != nullptr); | 1938 has_seen_constructor != nullptr); |
1929 bool is_get = false; | 1939 bool is_get = false; |
1930 bool is_set = false; | 1940 bool is_set = false; |
1931 bool is_generator = Check(Token::MUL); | 1941 bool is_generator = Check(Token::MUL); |
1932 bool is_async = false; | 1942 bool is_async = false; |
1933 const bool is_static = IsStaticMethod(method_kind); | 1943 const bool is_static = IsStaticMethod(method_kind); |
1934 | 1944 |
1935 Token::Value name_token = peek(); | 1945 Token::Value name_token = peek(); |
1936 | 1946 |
1937 if (is_generator) { | 1947 if (is_generator) { |
1938 method_kind |= MethodKind::kGenerator; | 1948 method_kind |= MethodKind::kGenerator; |
1939 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && | 1949 } else if (allow_harmony_async_await() && name_token == Token::ASYNC && |
1940 !scanner()->HasAnyLineTerminatorAfterNext() && | 1950 !scanner()->HasAnyLineTerminatorAfterNext() && |
1941 PeekAhead() != Token::LPAREN && PeekAhead()) { | 1951 PeekAhead() != Token::LPAREN && PeekAhead()) { |
1942 is_async = true; | 1952 is_async = true; |
1943 } | 1953 } |
1944 | 1954 |
1945 int next_beg_pos = scanner()->peek_location().beg_pos; | 1955 int next_beg_pos = scanner()->peek_location().beg_pos; |
1946 int next_end_pos = scanner()->peek_location().end_pos; | 1956 int next_end_pos = scanner()->peek_location().end_pos; |
1947 ExpressionT name_expression = | 1957 ExpressionT name_expression = |
1948 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, | 1958 ParsePropertyName(name, &is_get, &is_set, is_computed_name, |
1949 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1959 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1950 | 1960 |
1951 if (fni_ != nullptr && !*is_computed_name) { | 1961 if (fni_ != nullptr && !*is_computed_name) { |
1952 impl()->PushLiteralName(fni_, *name); | 1962 impl()->PushLiteralName(fni_, *name); |
1953 } | 1963 } |
1954 | 1964 |
1955 if (!in_class && !is_generator) { | 1965 if (!in_class && !is_generator) { |
1956 DCHECK(!IsStaticMethod(method_kind)); | 1966 DCHECK(!IsStaticMethod(method_kind)); |
1957 if (peek() == Token::COLON) { | 1967 if (peek() == Token::COLON) { |
1958 // PropertyDefinition | 1968 // PropertyDefinition |
1959 // PropertyName ':' AssignmentExpression | 1969 // PropertyName ':' AssignmentExpression |
1960 if (!*is_computed_name) { | 1970 if (!*is_computed_name) { |
1961 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal, | 1971 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal, |
1962 classifier, | |
1963 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1972 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1964 } | 1973 } |
1965 Consume(Token::COLON); | 1974 Consume(Token::COLON); |
1966 int beg_pos = peek_position(); | 1975 int beg_pos = peek_position(); |
1967 ExpressionT value = ParseAssignmentExpression( | 1976 ExpressionT value = ParseAssignmentExpression( |
1968 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1977 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1969 CheckDestructuringElement(value, classifier, beg_pos, | 1978 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos); |
1970 scanner()->location().end_pos); | |
1971 | 1979 |
1972 return factory()->NewObjectLiteralProperty(name_expression, value, | 1980 return factory()->NewObjectLiteralProperty(name_expression, value, |
1973 is_static, *is_computed_name); | 1981 is_static, *is_computed_name); |
1974 } | 1982 } |
1975 | 1983 |
1976 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), | 1984 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
1977 parsing_module_ || is_async_function()) && | 1985 parsing_module_ || is_async_function()) && |
1978 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1986 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1979 peek() == Token::ASSIGN)) { | 1987 peek() == Token::ASSIGN)) { |
1980 // PropertyDefinition | 1988 // PropertyDefinition |
1981 // IdentifierReference | 1989 // IdentifierReference |
1982 // CoverInitializedName | 1990 // CoverInitializedName |
1983 // | 1991 // |
1984 // CoverInitializedName | 1992 // CoverInitializedName |
1985 // IdentifierReference Initializer? | 1993 // IdentifierReference Initializer? |
1986 if (classifier->duplicate_finder() != nullptr && | 1994 if (classifier()->duplicate_finder() != nullptr && |
1987 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1995 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { |
1988 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1996 classifier()->RecordDuplicateFormalParameterError( |
1997 scanner()->location()); | |
1989 } | 1998 } |
1990 | 1999 |
1991 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { | 2000 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { |
1992 classifier->RecordBindingPatternError( | 2001 classifier()->RecordBindingPatternError( |
1993 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 2002 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1994 } | 2003 } |
1995 | 2004 |
1996 if (name_token == Token::LET) { | 2005 if (name_token == Token::LET) { |
1997 classifier->RecordLetPatternError( | 2006 classifier()->RecordLetPatternError( |
1998 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2007 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1999 } | 2008 } |
2000 if (name_token == Token::AWAIT) { | 2009 if (name_token == Token::AWAIT) { |
2001 DCHECK(!is_async_function()); | 2010 DCHECK(!is_async_function()); |
2002 classifier->RecordAsyncArrowFormalParametersError( | 2011 classifier()->RecordAsyncArrowFormalParametersError( |
2003 Scanner::Location(next_beg_pos, next_end_pos), | 2012 Scanner::Location(next_beg_pos, next_end_pos), |
2004 MessageTemplate::kAwaitBindingIdentifier); | 2013 MessageTemplate::kAwaitBindingIdentifier); |
2005 } | 2014 } |
2006 ExpressionT lhs = | 2015 ExpressionT lhs = |
2007 impl()->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); | 2016 impl()->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); |
2008 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 2017 CheckDestructuringElement(lhs, next_beg_pos, next_end_pos); |
2009 | 2018 |
2010 ExpressionT value; | 2019 ExpressionT value; |
2011 if (peek() == Token::ASSIGN) { | 2020 if (peek() == Token::ASSIGN) { |
2012 Consume(Token::ASSIGN); | 2021 Consume(Token::ASSIGN); |
2013 ExpressionClassifier rhs_classifier(this); | 2022 ExpressionClassifier rhs_classifier(this); |
2014 ExpressionT rhs = ParseAssignmentExpression( | 2023 ExpressionT rhs = ParseAssignmentExpression( |
2015 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2024 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2016 impl()->RewriteNonPattern(&rhs_classifier, | 2025 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2017 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2026 impl()->AccumulateFormalParameterContainmentErrors(); |
2018 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); | |
2019 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2027 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2020 kNoSourcePosition); | 2028 kNoSourcePosition); |
2021 classifier->RecordExpressionError( | 2029 classifier()->RecordExpressionError( |
2022 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2030 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2023 MessageTemplate::kInvalidCoverInitializedName); | 2031 MessageTemplate::kInvalidCoverInitializedName); |
2024 | 2032 |
2025 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); | 2033 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); |
2026 } else { | 2034 } else { |
2027 value = lhs; | 2035 value = lhs; |
2028 } | 2036 } |
2029 | 2037 |
2030 return factory()->NewObjectLiteralProperty( | 2038 return factory()->NewObjectLiteralProperty( |
2031 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, | 2039 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, |
2032 false); | 2040 false); |
2033 } | 2041 } |
2034 } | 2042 } |
2035 | 2043 |
2036 // Method definitions are never valid in patterns. | 2044 // Method definitions are never valid in patterns. |
2037 classifier->RecordPatternError( | 2045 classifier()->RecordPatternError( |
2038 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2046 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2039 MessageTemplate::kInvalidDestructuringTarget); | 2047 MessageTemplate::kInvalidDestructuringTarget); |
2040 | 2048 |
2041 if (is_async && !IsSpecialMethod(method_kind)) { | 2049 if (is_async && !IsSpecialMethod(method_kind)) { |
2042 DCHECK(!is_get); | 2050 DCHECK(!is_get); |
2043 DCHECK(!is_set); | 2051 DCHECK(!is_set); |
2044 bool dont_care; | 2052 bool dont_care; |
2045 name_expression = ParsePropertyName( | 2053 name_expression = |
2046 name, &dont_care, &dont_care, is_computed_name, classifier, | 2054 ParsePropertyName(name, &dont_care, &dont_care, is_computed_name, |
2047 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2055 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2048 method_kind |= MethodKind::kAsync; | 2056 method_kind |= MethodKind::kAsync; |
2049 } | 2057 } |
2050 | 2058 |
2051 if (is_generator || peek() == Token::LPAREN) { | 2059 if (is_generator || peek() == Token::LPAREN) { |
2052 // MethodDefinition | 2060 // MethodDefinition |
2053 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2061 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2054 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2062 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2055 if (!*is_computed_name) { | 2063 if (!*is_computed_name) { |
2056 checker->CheckProperty(name_token, kMethodProperty, method_kind, | 2064 checker->CheckProperty(name_token, kMethodProperty, method_kind, |
2057 classifier, | |
2058 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2065 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2059 } | 2066 } |
2060 | 2067 |
2061 FunctionKind kind = is_generator | 2068 FunctionKind kind = is_generator |
2062 ? FunctionKind::kConciseGeneratorMethod | 2069 ? FunctionKind::kConciseGeneratorMethod |
2063 : is_async ? FunctionKind::kAsyncConciseMethod | 2070 : is_async ? FunctionKind::kAsyncConciseMethod |
2064 : FunctionKind::kConciseMethod; | 2071 : FunctionKind::kConciseMethod; |
2065 | 2072 |
2066 if (in_class && !IsStaticMethod(method_kind) && | 2073 if (in_class && !IsStaticMethod(method_kind) && |
2067 impl()->IsConstructor(*name)) { | 2074 impl()->IsConstructor(*name)) { |
2068 *has_seen_constructor = true; | 2075 *has_seen_constructor = true; |
2069 kind = has_extends ? FunctionKind::kSubclassConstructor | 2076 kind = has_extends ? FunctionKind::kSubclassConstructor |
2070 : FunctionKind::kBaseConstructor; | 2077 : FunctionKind::kBaseConstructor; |
2071 } | 2078 } |
2072 | 2079 |
2073 ExpressionT value = impl()->ParseFunctionLiteral( | 2080 ExpressionT value = impl()->ParseFunctionLiteral( |
2074 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2081 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2075 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), | 2082 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), |
2076 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2083 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2077 | 2084 |
2078 return factory()->NewObjectLiteralProperty(name_expression, value, | 2085 return factory()->NewObjectLiteralProperty(name_expression, value, |
2079 ObjectLiteralProperty::COMPUTED, | 2086 ObjectLiteralProperty::COMPUTED, |
2080 is_static, *is_computed_name); | 2087 is_static, *is_computed_name); |
2081 } | 2088 } |
2082 | 2089 |
2083 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { | 2090 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { |
2084 // ClassElement (static) | 2091 // ClassElement (static) |
2085 // 'static' MethodDefinition | 2092 // 'static' MethodDefinition |
2086 *name = impl()->EmptyIdentifier(); | 2093 *name = impl()->EmptyIdentifier(); |
2087 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2094 ObjectLiteralPropertyT property = |
2088 checker, true, has_extends, MethodKind::kStatic, is_computed_name, | 2095 ParsePropertyDefinition(checker, true, has_extends, MethodKind::kStatic, |
2089 nullptr, classifier, name, ok); | 2096 is_computed_name, nullptr, name, ok); |
2090 impl()->RewriteNonPattern(classifier, ok); | 2097 impl()->RewriteNonPattern(ok); |
2091 return property; | 2098 return property; |
2092 } | 2099 } |
2093 | 2100 |
2094 if (is_get || is_set) { | 2101 if (is_get || is_set) { |
2095 // MethodDefinition (Accessors) | 2102 // MethodDefinition (Accessors) |
2096 // get PropertyName '(' ')' '{' FunctionBody '}' | 2103 // get PropertyName '(' ')' '{' FunctionBody '}' |
2097 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2104 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
2098 *name = impl()->EmptyIdentifier(); | 2105 *name = impl()->EmptyIdentifier(); |
2099 bool dont_care = false; | 2106 bool dont_care = false; |
2100 name_token = peek(); | 2107 name_token = peek(); |
2101 | 2108 |
2102 name_expression = ParsePropertyName( | 2109 name_expression = |
2103 name, &dont_care, &dont_care, is_computed_name, classifier, | 2110 ParsePropertyName(name, &dont_care, &dont_care, is_computed_name, |
2104 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2111 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2105 | 2112 |
2106 if (!*is_computed_name) { | 2113 if (!*is_computed_name) { |
2107 checker->CheckProperty(name_token, kAccessorProperty, method_kind, | 2114 checker->CheckProperty(name_token, kAccessorProperty, method_kind, |
2108 classifier, | |
2109 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2115 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2110 } | 2116 } |
2111 | 2117 |
2112 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2118 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2113 *name, scanner()->location(), kSkipFunctionNameCheck, | 2119 *name, scanner()->location(), kSkipFunctionNameCheck, |
2114 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, | 2120 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, |
2115 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), | 2121 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), |
2116 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2122 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2117 | 2123 |
2118 // Make sure the name expression is a string since we need a Name for | 2124 // Make sure the name expression is a string since we need a Name for |
(...skipping 11 matching lines...) Expand all Loading... | |
2130 } | 2136 } |
2131 | 2137 |
2132 Token::Value next = Next(); | 2138 Token::Value next = Next(); |
2133 ReportUnexpectedToken(next); | 2139 ReportUnexpectedToken(next); |
2134 *ok = false; | 2140 *ok = false; |
2135 return impl()->EmptyObjectLiteralProperty(); | 2141 return impl()->EmptyObjectLiteralProperty(); |
2136 } | 2142 } |
2137 | 2143 |
2138 template <typename Impl> | 2144 template <typename Impl> |
2139 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2145 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
2140 ExpressionClassifier* classifier, bool* ok) { | 2146 bool* ok) { |
2141 // ObjectLiteral :: | 2147 // ObjectLiteral :: |
2142 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2148 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2143 | 2149 |
2144 int pos = peek_position(); | 2150 int pos = peek_position(); |
2145 typename Types::PropertyList properties = impl()->NewPropertyList(4); | 2151 typename Types::PropertyList properties = impl()->NewPropertyList(4); |
2146 int number_of_boilerplate_properties = 0; | 2152 int number_of_boilerplate_properties = 0; |
2147 bool has_computed_names = false; | 2153 bool has_computed_names = false; |
2148 ObjectLiteralChecker checker(this); | 2154 ObjectLiteralChecker checker(this); |
2149 | 2155 |
2150 Expect(Token::LBRACE, CHECK_OK); | 2156 Expect(Token::LBRACE, CHECK_OK); |
2151 | 2157 |
2152 while (peek() != Token::RBRACE) { | 2158 while (peek() != Token::RBRACE) { |
2153 FuncNameInferrer::State fni_state(fni_); | 2159 FuncNameInferrer::State fni_state(fni_); |
2154 | 2160 |
2155 const bool in_class = false; | 2161 const bool in_class = false; |
2156 const bool has_extends = false; | 2162 const bool has_extends = false; |
2157 bool is_computed_name = false; | 2163 bool is_computed_name = false; |
2158 IdentifierT name = impl()->EmptyIdentifier(); | 2164 IdentifierT name = impl()->EmptyIdentifier(); |
2159 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2165 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
2160 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name, | 2166 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name, |
2161 NULL, classifier, &name, CHECK_OK); | 2167 NULL, &name, CHECK_OK); |
2162 | 2168 |
2163 if (is_computed_name) { | 2169 if (is_computed_name) { |
2164 has_computed_names = true; | 2170 has_computed_names = true; |
2165 } | 2171 } |
2166 | 2172 |
2167 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2173 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2168 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2174 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
2169 number_of_boilerplate_properties++; | 2175 number_of_boilerplate_properties++; |
2170 } | 2176 } |
2171 properties->Add(property, zone()); | 2177 properties->Add(property, zone()); |
(...skipping 14 matching lines...) Expand all Loading... | |
2186 | 2192 |
2187 return factory()->NewObjectLiteral(properties, | 2193 return factory()->NewObjectLiteral(properties, |
2188 literal_index, | 2194 literal_index, |
2189 number_of_boilerplate_properties, | 2195 number_of_boilerplate_properties, |
2190 pos); | 2196 pos); |
2191 } | 2197 } |
2192 | 2198 |
2193 template <typename Impl> | 2199 template <typename Impl> |
2194 typename ParserBase<Impl>::Types::ExpressionList | 2200 typename ParserBase<Impl>::Types::ExpressionList |
2195 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, | 2201 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, |
2196 bool maybe_arrow, | 2202 bool maybe_arrow, bool* ok) { |
2197 ExpressionClassifier* classifier, bool* ok) { | |
2198 // Arguments :: | 2203 // Arguments :: |
2199 // '(' (AssignmentExpression)*[','] ')' | 2204 // '(' (AssignmentExpression)*[','] ')' |
2200 | 2205 |
2201 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2206 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2202 typename Types::ExpressionList result = impl()->NewExpressionList(4); | 2207 typename Types::ExpressionList result = impl()->NewExpressionList(4); |
2203 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2208 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2204 bool done = (peek() == Token::RPAREN); | 2209 bool done = (peek() == Token::RPAREN); |
2205 bool was_unspread = false; | 2210 bool was_unspread = false; |
2206 int unspread_sequences_count = 0; | 2211 int unspread_sequences_count = 0; |
2207 while (!done) { | 2212 while (!done) { |
2208 int start_pos = peek_position(); | 2213 int start_pos = peek_position(); |
2209 bool is_spread = Check(Token::ELLIPSIS); | 2214 bool is_spread = Check(Token::ELLIPSIS); |
2210 int expr_pos = peek_position(); | 2215 int expr_pos = peek_position(); |
2211 | 2216 |
2212 ExpressionT argument = ParseAssignmentExpression( | 2217 ExpressionT argument = |
2213 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2218 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); |
2214 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2219 CheckNoTailCallExpressions(CHECK_OK_CUSTOM(NullExpressionList)); |
2215 if (!maybe_arrow) { | 2220 if (!maybe_arrow) { |
2216 impl()->RewriteNonPattern(classifier, | 2221 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
2217 CHECK_OK_CUSTOM(NullExpressionList)); | |
2218 } | 2222 } |
2219 if (is_spread) { | 2223 if (is_spread) { |
2220 if (!spread_arg.IsValid()) { | 2224 if (!spread_arg.IsValid()) { |
2221 spread_arg.beg_pos = start_pos; | 2225 spread_arg.beg_pos = start_pos; |
2222 spread_arg.end_pos = peek_position(); | 2226 spread_arg.end_pos = peek_position(); |
2223 } | 2227 } |
2224 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 2228 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
2225 } | 2229 } |
2226 result->Add(argument, zone_); | 2230 result->Add(argument, zone_); |
2227 | 2231 |
(...skipping 23 matching lines...) Expand all Loading... | |
2251 Scanner::Location location = scanner_->location(); | 2255 Scanner::Location location = scanner_->location(); |
2252 if (Token::RPAREN != Next()) { | 2256 if (Token::RPAREN != Next()) { |
2253 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2257 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
2254 *ok = false; | 2258 *ok = false; |
2255 return impl()->NullExpressionList(); | 2259 return impl()->NullExpressionList(); |
2256 } | 2260 } |
2257 *first_spread_arg_loc = spread_arg; | 2261 *first_spread_arg_loc = spread_arg; |
2258 | 2262 |
2259 if (!maybe_arrow || peek() != Token::ARROW) { | 2263 if (!maybe_arrow || peek() != Token::ARROW) { |
2260 if (maybe_arrow) { | 2264 if (maybe_arrow) { |
2261 impl()->RewriteNonPattern(classifier, | 2265 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
2262 CHECK_OK_CUSTOM(NullExpressionList)); | |
2263 } | 2266 } |
2264 if (spread_arg.IsValid()) { | 2267 if (spread_arg.IsValid()) { |
2265 // Unspread parameter sequences are translated into array literals in the | 2268 // Unspread parameter sequences are translated into array literals in the |
2266 // parser. Ensure that the number of materialized literals matches between | 2269 // parser. Ensure that the number of materialized literals matches between |
2267 // the parser and preparser | 2270 // the parser and preparser |
2268 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2271 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2269 } | 2272 } |
2270 } | 2273 } |
2271 | 2274 |
2272 return result; | 2275 return result; |
2273 } | 2276 } |
2274 | 2277 |
2275 // Precedence = 2 | 2278 // Precedence = 2 |
2276 template <typename Impl> | 2279 template <typename Impl> |
2277 typename ParserBase<Impl>::ExpressionT | 2280 typename ParserBase<Impl>::ExpressionT |
2278 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, | 2281 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2279 ExpressionClassifier* classifier, | |
2280 bool* ok) { | |
2281 // AssignmentExpression :: | 2282 // AssignmentExpression :: |
2282 // ConditionalExpression | 2283 // ConditionalExpression |
2283 // ArrowFunction | 2284 // ArrowFunction |
2284 // YieldExpression | 2285 // YieldExpression |
2285 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2286 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2286 int lhs_beg_pos = peek_position(); | 2287 int lhs_beg_pos = peek_position(); |
2287 | 2288 |
2288 if (peek() == Token::YIELD && is_generator()) { | 2289 if (peek() == Token::YIELD && is_generator()) { |
2289 return ParseYieldExpression(accept_IN, classifier, ok); | 2290 return ParseYieldExpression(accept_IN, ok); |
2290 } | 2291 } |
2291 | 2292 |
2292 FuncNameInferrer::State fni_state(fni_); | 2293 FuncNameInferrer::State fni_state(fni_); |
2293 Checkpoint checkpoint(this); | 2294 Checkpoint checkpoint(this); |
2294 ExpressionClassifier arrow_formals_classifier(this, | 2295 ExpressionClassifier arrow_formals_classifier( |
2295 classifier->duplicate_finder()); | 2296 this, classifier()->duplicate_finder()); |
2296 | 2297 |
2297 Scope::Snapshot scope_snapshot(scope()); | 2298 Scope::Snapshot scope_snapshot(scope()); |
2298 | 2299 |
2299 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | 2300 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && |
2300 !scanner()->HasAnyLineTerminatorAfterNext() && | 2301 !scanner()->HasAnyLineTerminatorAfterNext() && |
2301 IsValidArrowFormalParametersStart(PeekAhead()); | 2302 IsValidArrowFormalParametersStart(PeekAhead()); |
2302 | 2303 |
2303 bool parenthesized_formals = peek() == Token::LPAREN; | 2304 bool parenthesized_formals = peek() == Token::LPAREN; |
2304 if (!is_async && !parenthesized_formals) { | 2305 if (!is_async && !parenthesized_formals) { |
2305 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2306 ArrowFormalParametersUnexpectedToken(); |
2306 } | 2307 } |
2307 | 2308 |
2308 // Parse a simple, faster sub-grammar (primary expression) if it's evident | 2309 // Parse a simple, faster sub-grammar (primary expression) if it's evident |
2309 // that we have only a trivial expression to parse. | 2310 // that we have only a trivial expression to parse. |
2310 ExpressionT expression; | 2311 ExpressionT expression; |
2311 if (IsTrivialExpression()) { | 2312 if (IsTrivialExpression()) { |
2312 expression = | 2313 expression = ParsePrimaryExpression(&is_async, CHECK_OK); |
2313 ParsePrimaryExpression(&arrow_formals_classifier, &is_async, CHECK_OK); | |
2314 } else { | 2314 } else { |
2315 expression = ParseConditionalExpression( | 2315 expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
2316 accept_IN, &arrow_formals_classifier, CHECK_OK); | |
2317 } | 2316 } |
2318 | 2317 |
2319 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && | 2318 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && |
2320 PeekAhead() == Token::ARROW) { | 2319 PeekAhead() == Token::ARROW) { |
2321 // async Identifier => AsyncConciseBody | 2320 // async Identifier => AsyncConciseBody |
2322 IdentifierT name = | 2321 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); |
2323 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | |
2324 expression = impl()->ExpressionFromIdentifier( | 2322 expression = impl()->ExpressionFromIdentifier( |
2325 name, position(), scanner()->location().end_pos, InferName::kNo); | 2323 name, position(), scanner()->location().end_pos, InferName::kNo); |
2326 if (fni_) { | 2324 if (fni_) { |
2327 // Remove `async` keyword from inferred name stack. | 2325 // Remove `async` keyword from inferred name stack. |
2328 fni_->RemoveAsyncKeywordFromEnd(); | 2326 fni_->RemoveAsyncKeywordFromEnd(); |
2329 } | 2327 } |
2330 } | 2328 } |
2331 | 2329 |
2332 if (peek() == Token::ARROW) { | 2330 if (peek() == Token::ARROW) { |
2333 Scanner::Location arrow_loc = scanner()->peek_location(); | 2331 Scanner::Location arrow_loc = scanner()->peek_location(); |
2334 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2332 ValidateArrowFormalParameters(expression, parenthesized_formals, is_async, |
2335 parenthesized_formals, is_async, CHECK_OK); | 2333 CHECK_OK); |
2336 // This reads strangely, but is correct: it checks whether any | 2334 // This reads strangely, but is correct: it checks whether any |
2337 // sub-expression of the parameter list failed to be a valid formal | 2335 // sub-expression of the parameter list failed to be a valid formal |
2338 // parameter initializer. Since YieldExpressions are banned anywhere | 2336 // parameter initializer. Since YieldExpressions are banned anywhere |
2339 // in an arrow parameter list, this is correct. | 2337 // in an arrow parameter list, this is correct. |
2340 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2338 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
2341 // "YieldExpression", which is its only use. | 2339 // "YieldExpression", which is its only use. |
2342 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2340 ValidateFormalParameterInitializer(ok); |
2343 | 2341 |
2344 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2342 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2345 DeclarationScope* scope = | 2343 DeclarationScope* scope = |
2346 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction | 2344 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction |
2347 : FunctionKind::kArrowFunction); | 2345 : FunctionKind::kArrowFunction); |
2348 // Because the arrow's parameters were parsed in the outer scope, any | 2346 // Because the arrow's parameters were parsed in the outer scope, any |
2349 // usage flags that might have been triggered there need to be copied | 2347 // usage flags that might have been triggered there need to be copied |
2350 // to the arrow scope. | 2348 // to the arrow scope. |
2351 this->scope()->PropagateUsageFlagsToScope(scope); | 2349 this->scope()->PropagateUsageFlagsToScope(scope); |
2352 FormalParametersT parameters(scope); | 2350 FormalParametersT parameters(scope); |
2353 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2351 if (!classifier()->is_simple_parameter_list()) { |
2354 scope->SetHasNonSimpleParameters(); | 2352 scope->SetHasNonSimpleParameters(); |
2355 parameters.is_simple = false; | 2353 parameters.is_simple = false; |
2356 } | 2354 } |
2357 | 2355 |
2358 checkpoint.Restore(¶meters.materialized_literals_count); | 2356 checkpoint.Restore(¶meters.materialized_literals_count); |
2359 | 2357 |
2360 scope->set_start_position(lhs_beg_pos); | 2358 scope->set_start_position(lhs_beg_pos); |
2361 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2359 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
2362 impl()->ParseArrowFunctionFormalParameterList( | 2360 impl()->ParseArrowFunctionFormalParameterList( |
2363 ¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK); | 2361 ¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK); |
2364 if (duplicate_loc.IsValid()) { | 2362 if (duplicate_loc.IsValid()) { |
2365 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2363 classifier()->RecordDuplicateFormalParameterError(duplicate_loc); |
2366 duplicate_loc); | |
2367 } | 2364 } |
2368 expression = ParseArrowFunctionLiteral(accept_IN, parameters, is_async, | 2365 expression = |
2369 arrow_formals_classifier, CHECK_OK); | 2366 ParseArrowFunctionLiteral(accept_IN, parameters, is_async, CHECK_OK); |
2370 arrow_formals_classifier.Discard(); | 2367 impl()->Discard(); |
2371 classifier->RecordPatternError(arrow_loc, | 2368 classifier()->RecordPatternError(arrow_loc, |
2372 MessageTemplate::kUnexpectedToken, | 2369 MessageTemplate::kUnexpectedToken, |
2373 Token::String(Token::ARROW)); | 2370 Token::String(Token::ARROW)); |
2374 | 2371 |
2375 if (fni_ != nullptr) fni_->Infer(); | 2372 if (fni_ != nullptr) fni_->Infer(); |
2376 | 2373 |
2377 return expression; | 2374 return expression; |
2378 } | 2375 } |
2379 | 2376 |
2380 // "expression" was not itself an arrow function parameter list, but it might | 2377 // "expression" was not itself an arrow function parameter list, but it might |
2381 // form part of one. Propagate speculative formal parameter error locations | 2378 // form part of one. Propagate speculative formal parameter error locations |
2382 // (including those for binding patterns, since formal parameters can | 2379 // (including those for binding patterns, since formal parameters can |
2383 // themselves contain binding patterns). | 2380 // themselves contain binding patterns). |
(...skipping 13 matching lines...) Expand all Loading... | |
2397 if (is_destructuring_assignment) { | 2394 if (is_destructuring_assignment) { |
2398 // This is definitely not an expression so don't accumulate | 2395 // This is definitely not an expression so don't accumulate |
2399 // expression-related errors. | 2396 // expression-related errors. |
2400 productions &= ~(ExpressionClassifier::ExpressionProduction | | 2397 productions &= ~(ExpressionClassifier::ExpressionProduction | |
2401 ExpressionClassifier::TailCallExpressionProduction); | 2398 ExpressionClassifier::TailCallExpressionProduction); |
2402 } | 2399 } |
2403 | 2400 |
2404 if (!Token::IsAssignmentOp(peek())) { | 2401 if (!Token::IsAssignmentOp(peek())) { |
2405 // Parsed conditional expression only (no assignment). | 2402 // Parsed conditional expression only (no assignment). |
2406 // Pending non-pattern expressions must be merged. | 2403 // Pending non-pattern expressions must be merged. |
2407 classifier->Accumulate(&arrow_formals_classifier, productions); | 2404 impl()->Accumulate(productions); |
2408 return expression; | 2405 return expression; |
2409 } else { | 2406 } else { |
2410 // Pending non-pattern expressions must be discarded. | 2407 // Pending non-pattern expressions must be discarded. |
2411 classifier->Accumulate(&arrow_formals_classifier, productions, false); | 2408 impl()->Accumulate(productions, false); |
2412 } | 2409 } |
2413 | 2410 |
2414 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2411 CheckNoTailCallExpressions(CHECK_OK); |
2415 | 2412 |
2416 if (is_destructuring_assignment) { | 2413 if (is_destructuring_assignment) { |
2417 ValidateAssignmentPattern(classifier, CHECK_OK); | 2414 ValidateAssignmentPattern(CHECK_OK); |
2418 } else { | 2415 } else { |
2419 expression = CheckAndRewriteReferenceExpression( | 2416 expression = CheckAndRewriteReferenceExpression( |
2420 expression, lhs_beg_pos, scanner()->location().end_pos, | 2417 expression, lhs_beg_pos, scanner()->location().end_pos, |
2421 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2418 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
2422 } | 2419 } |
2423 | 2420 |
2424 expression = impl()->MarkExpressionAsAssigned(expression); | 2421 expression = impl()->MarkExpressionAsAssigned(expression); |
2425 | 2422 |
2426 Token::Value op = Next(); // Get assignment operator. | 2423 Token::Value op = Next(); // Get assignment operator. |
2427 if (op != Token::ASSIGN) { | 2424 if (op != Token::ASSIGN) { |
2428 classifier->RecordPatternError(scanner()->location(), | 2425 classifier()->RecordPatternError(scanner()->location(), |
2429 MessageTemplate::kUnexpectedToken, | 2426 MessageTemplate::kUnexpectedToken, |
2430 Token::String(op)); | 2427 Token::String(op)); |
2431 } | 2428 } |
2432 int pos = position(); | 2429 int pos = position(); |
2433 | 2430 |
2434 ExpressionClassifier rhs_classifier(this); | 2431 ExpressionClassifier rhs_classifier(this); |
2435 | 2432 |
2436 ExpressionT right = | 2433 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2437 ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2434 CheckNoTailCallExpressions(CHECK_OK); |
2438 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); | 2435 impl()->RewriteNonPattern(CHECK_OK); |
2439 impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2436 impl()->AccumulateFormalParameterContainmentErrors(); |
2440 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); | |
2441 | 2437 |
2442 // TODO(1231235): We try to estimate the set of properties set by | 2438 // TODO(1231235): We try to estimate the set of properties set by |
2443 // constructors. We define a new property whenever there is an | 2439 // constructors. We define a new property whenever there is an |
2444 // assignment to a property of 'this'. We should probably only add | 2440 // assignment to a property of 'this'. We should probably only add |
2445 // properties if we haven't seen them before. Otherwise we'll | 2441 // properties if we haven't seen them before. Otherwise we'll |
2446 // probably overestimate the number of properties. | 2442 // probably overestimate the number of properties. |
2447 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { | 2443 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { |
2448 function_state_->AddProperty(); | 2444 function_state_->AddProperty(); |
2449 } | 2445 } |
2450 | 2446 |
(...skipping 25 matching lines...) Expand all Loading... | |
2476 if (is_destructuring_assignment) { | 2472 if (is_destructuring_assignment) { |
2477 result = factory()->NewRewritableExpression(result); | 2473 result = factory()->NewRewritableExpression(result); |
2478 impl()->QueueDestructuringAssignmentForRewriting(result); | 2474 impl()->QueueDestructuringAssignmentForRewriting(result); |
2479 } | 2475 } |
2480 | 2476 |
2481 return result; | 2477 return result; |
2482 } | 2478 } |
2483 | 2479 |
2484 template <typename Impl> | 2480 template <typename Impl> |
2485 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( | 2481 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
2486 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2482 bool accept_IN, bool* ok) { |
2487 // YieldExpression :: | 2483 // YieldExpression :: |
2488 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2484 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2489 int pos = peek_position(); | 2485 int pos = peek_position(); |
2490 classifier->RecordPatternError(scanner()->peek_location(), | 2486 classifier()->RecordPatternError( |
2491 MessageTemplate::kInvalidDestructuringTarget); | 2487 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget); |
2492 classifier->RecordFormalParameterInitializerError( | 2488 classifier()->RecordFormalParameterInitializerError( |
2493 scanner()->peek_location(), MessageTemplate::kYieldInParameter); | 2489 scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
2494 Expect(Token::YIELD, CHECK_OK); | 2490 Expect(Token::YIELD, CHECK_OK); |
2495 ExpressionT generator_object = | 2491 ExpressionT generator_object = |
2496 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2492 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
2497 // The following initialization is necessary. | 2493 // The following initialization is necessary. |
2498 ExpressionT expression = impl()->EmptyExpression(); | 2494 ExpressionT expression = impl()->EmptyExpression(); |
2499 bool delegating = false; // yield* | 2495 bool delegating = false; // yield* |
2500 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2496 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2501 if (Check(Token::MUL)) delegating = true; | 2497 if (Check(Token::MUL)) delegating = true; |
2502 switch (peek()) { | 2498 switch (peek()) { |
2503 case Token::EOS: | 2499 case Token::EOS: |
2504 case Token::SEMICOLON: | 2500 case Token::SEMICOLON: |
2505 case Token::RBRACE: | 2501 case Token::RBRACE: |
2506 case Token::RBRACK: | 2502 case Token::RBRACK: |
2507 case Token::RPAREN: | 2503 case Token::RPAREN: |
2508 case Token::COLON: | 2504 case Token::COLON: |
2509 case Token::COMMA: | 2505 case Token::COMMA: |
2510 // The above set of tokens is the complete set of tokens that can appear | 2506 // The above set of tokens is the complete set of tokens that can appear |
2511 // after an AssignmentExpression, and none of them can start an | 2507 // after an AssignmentExpression, and none of them can start an |
2512 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2508 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2513 // a regular yield, given only one look-ahead token. | 2509 // a regular yield, given only one look-ahead token. |
2514 if (!delegating) break; | 2510 if (!delegating) break; |
2515 // Delegating yields require an RHS; fall through. | 2511 // Delegating yields require an RHS; fall through. |
2516 default: | 2512 default: |
2517 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2513 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2518 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2514 impl()->RewriteNonPattern(CHECK_OK); |
2519 break; | 2515 break; |
2520 } | 2516 } |
2521 } | 2517 } |
2522 | 2518 |
2523 if (delegating) { | 2519 if (delegating) { |
2524 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2520 return impl()->RewriteYieldStar(generator_object, expression, pos); |
2525 } | 2521 } |
2526 | 2522 |
2527 expression = impl()->BuildIteratorResult(expression, false); | 2523 expression = impl()->BuildIteratorResult(expression, false); |
2528 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2524 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2529 // TODO(verwaest): Come up with a better solution. | 2525 // TODO(verwaest): Come up with a better solution. |
2530 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, | 2526 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
2531 Yield::kOnExceptionThrow); | 2527 Yield::kOnExceptionThrow); |
2532 return yield; | 2528 return yield; |
2533 } | 2529 } |
2534 | 2530 |
2535 template <typename Impl> | 2531 template <typename Impl> |
2536 typename ParserBase<Impl>::ExpressionT | 2532 typename ParserBase<Impl>::ExpressionT |
2537 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, | 2533 ParserBase<Impl>::ParseTailCallExpression(bool* ok) { |
2538 bool* ok) { | |
2539 // TailCallExpression:: | 2534 // TailCallExpression:: |
2540 // 'continue' MemberExpression Arguments | 2535 // 'continue' MemberExpression Arguments |
2541 // 'continue' CallExpression Arguments | 2536 // 'continue' CallExpression Arguments |
2542 // 'continue' MemberExpression TemplateLiteral | 2537 // 'continue' MemberExpression TemplateLiteral |
2543 // 'continue' CallExpression TemplateLiteral | 2538 // 'continue' CallExpression TemplateLiteral |
2544 Expect(Token::CONTINUE, CHECK_OK); | 2539 Expect(Token::CONTINUE, CHECK_OK); |
2545 int pos = position(); | 2540 int pos = position(); |
2546 int sub_expression_pos = peek_position(); | 2541 int sub_expression_pos = peek_position(); |
2547 ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK); | 2542 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK); |
2548 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2543 CheckNoTailCallExpressions(CHECK_OK); |
2549 | 2544 |
2550 Scanner::Location loc(pos, scanner()->location().end_pos); | 2545 Scanner::Location loc(pos, scanner()->location().end_pos); |
2551 if (!expression->IsCall()) { | 2546 if (!expression->IsCall()) { |
2552 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); | 2547 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
2553 impl()->ReportMessageAt(sub_loc, | 2548 impl()->ReportMessageAt(sub_loc, |
2554 MessageTemplate::kUnexpectedInsideTailCall); | 2549 MessageTemplate::kUnexpectedInsideTailCall); |
2555 *ok = false; | 2550 *ok = false; |
2556 return impl()->EmptyExpression(); | 2551 return impl()->EmptyExpression(); |
2557 } | 2552 } |
2558 if (impl()->IsDirectEvalCall(expression)) { | 2553 if (impl()->IsDirectEvalCall(expression)) { |
(...skipping 23 matching lines...) Expand all Loading... | |
2582 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; | 2577 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; |
2583 break; | 2578 break; |
2584 case ReturnExprContext::kInsideForInOfBody: | 2579 case ReturnExprContext::kInsideForInOfBody: |
2585 msg = MessageTemplate::kUnexpectedTailCallInForInOf; | 2580 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
2586 break; | 2581 break; |
2587 } | 2582 } |
2588 impl()->ReportMessageAt(loc, msg); | 2583 impl()->ReportMessageAt(loc, msg); |
2589 *ok = false; | 2584 *ok = false; |
2590 return impl()->EmptyExpression(); | 2585 return impl()->EmptyExpression(); |
2591 } | 2586 } |
2592 classifier->RecordTailCallExpressionError( | 2587 classifier()->RecordTailCallExpressionError( |
2593 loc, MessageTemplate::kUnexpectedTailCall); | 2588 loc, MessageTemplate::kUnexpectedTailCall); |
2594 function_state_->AddExplicitTailCallExpression(expression, loc); | 2589 function_state_->AddExplicitTailCallExpression(expression, loc); |
2595 return expression; | 2590 return expression; |
2596 } | 2591 } |
2597 | 2592 |
2598 // Precedence = 3 | 2593 // Precedence = 3 |
2599 template <typename Impl> | 2594 template <typename Impl> |
2600 typename ParserBase<Impl>::ExpressionT | 2595 typename ParserBase<Impl>::ExpressionT |
2601 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, | 2596 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, |
2602 ExpressionClassifier* classifier, | |
2603 bool* ok) { | 2597 bool* ok) { |
2604 // ConditionalExpression :: | 2598 // ConditionalExpression :: |
2605 // LogicalOrExpression | 2599 // LogicalOrExpression |
2606 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2600 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2607 | 2601 |
2608 int pos = peek_position(); | 2602 int pos = peek_position(); |
2609 // We start using the binary expression parser for prec >= 4 only! | 2603 // We start using the binary expression parser for prec >= 4 only! |
2610 ExpressionT expression = | 2604 ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
2611 ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | |
2612 if (peek() != Token::CONDITIONAL) return expression; | 2605 if (peek() != Token::CONDITIONAL) return expression; |
2613 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2606 CheckNoTailCallExpressions(CHECK_OK); |
2614 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2607 impl()->RewriteNonPattern(CHECK_OK); |
2615 BindingPatternUnexpectedToken(classifier); | 2608 BindingPatternUnexpectedToken(); |
2616 ArrowFormalParametersUnexpectedToken(classifier); | 2609 ArrowFormalParametersUnexpectedToken(); |
2617 Consume(Token::CONDITIONAL); | 2610 Consume(Token::CONDITIONAL); |
2618 // In parsing the first assignment expression in conditional | 2611 // In parsing the first assignment expression in conditional |
2619 // expressions we always accept the 'in' keyword; see ECMA-262, | 2612 // expressions we always accept the 'in' keyword; see ECMA-262, |
2620 // section 11.12, page 58. | 2613 // section 11.12, page 58. |
2621 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2614 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); |
2622 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2615 impl()->RewriteNonPattern(CHECK_OK); |
2623 Expect(Token::COLON, CHECK_OK); | 2616 Expect(Token::COLON, CHECK_OK); |
2624 ExpressionT right = | 2617 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2625 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2618 impl()->RewriteNonPattern(CHECK_OK); |
2626 impl()->RewriteNonPattern(classifier, CHECK_OK); | |
2627 return factory()->NewConditional(expression, left, right, pos); | 2619 return factory()->NewConditional(expression, left, right, pos); |
2628 } | 2620 } |
2629 | 2621 |
2630 | 2622 |
2631 // Precedence >= 4 | 2623 // Precedence >= 4 |
2632 template <typename Impl> | 2624 template <typename Impl> |
2633 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( | 2625 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( |
2634 int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2626 int prec, bool accept_IN, bool* ok) { |
2635 DCHECK(prec >= 4); | 2627 DCHECK(prec >= 4); |
2636 ExpressionT x = ParseUnaryExpression(classifier, CHECK_OK); | 2628 ExpressionT x = ParseUnaryExpression(CHECK_OK); |
2637 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2629 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2638 // prec1 >= 4 | 2630 // prec1 >= 4 |
2639 while (Precedence(peek(), accept_IN) == prec1) { | 2631 while (Precedence(peek(), accept_IN) == prec1) { |
2640 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2632 CheckNoTailCallExpressions(CHECK_OK); |
2641 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2633 impl()->RewriteNonPattern(CHECK_OK); |
2642 BindingPatternUnexpectedToken(classifier); | 2634 BindingPatternUnexpectedToken(); |
2643 ArrowFormalParametersUnexpectedToken(classifier); | 2635 ArrowFormalParametersUnexpectedToken(); |
2644 Token::Value op = Next(); | 2636 Token::Value op = Next(); |
2645 int pos = position(); | 2637 int pos = position(); |
2646 | 2638 |
2647 const bool is_right_associative = op == Token::EXP; | 2639 const bool is_right_associative = op == Token::EXP; |
2648 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2640 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
2649 ExpressionT y = | 2641 ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK); |
2650 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | |
2651 if (op != Token::OR && op != Token::AND) { | 2642 if (op != Token::OR && op != Token::AND) { |
2652 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2643 CheckNoTailCallExpressions(CHECK_OK); |
2653 } | 2644 } |
2654 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2645 impl()->RewriteNonPattern(CHECK_OK); |
2655 | 2646 |
2656 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { | 2647 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { |
2657 continue; | 2648 continue; |
2658 } | 2649 } |
2659 | 2650 |
2660 // For now we distinguish between comparisons and other binary | 2651 // For now we distinguish between comparisons and other binary |
2661 // operations. (We could combine the two and get rid of this | 2652 // operations. (We could combine the two and get rid of this |
2662 // code and AST node eventually.) | 2653 // code and AST node eventually.) |
2663 if (Token::IsCompareOp(op)) { | 2654 if (Token::IsCompareOp(op)) { |
2664 // We have a comparison. | 2655 // We have a comparison. |
(...skipping 14 matching lines...) Expand all Loading... | |
2679 // We have a "normal" binary operation. | 2670 // We have a "normal" binary operation. |
2680 x = factory()->NewBinaryOperation(op, x, y, pos); | 2671 x = factory()->NewBinaryOperation(op, x, y, pos); |
2681 } | 2672 } |
2682 } | 2673 } |
2683 } | 2674 } |
2684 return x; | 2675 return x; |
2685 } | 2676 } |
2686 | 2677 |
2687 template <typename Impl> | 2678 template <typename Impl> |
2688 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( | 2679 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( |
2689 ExpressionClassifier* classifier, bool* ok) { | 2680 bool* ok) { |
2690 // UnaryExpression :: | 2681 // UnaryExpression :: |
2691 // PostfixExpression | 2682 // PostfixExpression |
2692 // 'delete' UnaryExpression | 2683 // 'delete' UnaryExpression |
2693 // 'void' UnaryExpression | 2684 // 'void' UnaryExpression |
2694 // 'typeof' UnaryExpression | 2685 // 'typeof' UnaryExpression |
2695 // '++' UnaryExpression | 2686 // '++' UnaryExpression |
2696 // '--' UnaryExpression | 2687 // '--' UnaryExpression |
2697 // '+' UnaryExpression | 2688 // '+' UnaryExpression |
2698 // '-' UnaryExpression | 2689 // '-' UnaryExpression |
2699 // '~' UnaryExpression | 2690 // '~' UnaryExpression |
2700 // '!' UnaryExpression | 2691 // '!' UnaryExpression |
2701 // [+Await] AwaitExpression[?Yield] | 2692 // [+Await] AwaitExpression[?Yield] |
2702 | 2693 |
2703 Token::Value op = peek(); | 2694 Token::Value op = peek(); |
2704 if (Token::IsUnaryOp(op)) { | 2695 if (Token::IsUnaryOp(op)) { |
2705 BindingPatternUnexpectedToken(classifier); | 2696 BindingPatternUnexpectedToken(); |
2706 ArrowFormalParametersUnexpectedToken(classifier); | 2697 ArrowFormalParametersUnexpectedToken(); |
2707 | 2698 |
2708 op = Next(); | 2699 op = Next(); |
2709 int pos = position(); | 2700 int pos = position(); |
2710 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2701 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
2711 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2702 CheckNoTailCallExpressions(CHECK_OK); |
2712 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2703 impl()->RewriteNonPattern(CHECK_OK); |
2713 | 2704 |
2714 if (op == Token::DELETE && is_strict(language_mode())) { | 2705 if (op == Token::DELETE && is_strict(language_mode())) { |
2715 if (impl()->IsIdentifier(expression)) { | 2706 if (impl()->IsIdentifier(expression)) { |
2716 // "delete identifier" is a syntax error in strict mode. | 2707 // "delete identifier" is a syntax error in strict mode. |
2717 ReportMessage(MessageTemplate::kStrictDelete); | 2708 ReportMessage(MessageTemplate::kStrictDelete); |
2718 *ok = false; | 2709 *ok = false; |
2719 return impl()->EmptyExpression(); | 2710 return impl()->EmptyExpression(); |
2720 } | 2711 } |
2721 } | 2712 } |
2722 | 2713 |
2723 if (peek() == Token::EXP) { | 2714 if (peek() == Token::EXP) { |
2724 ReportUnexpectedToken(Next()); | 2715 ReportUnexpectedToken(Next()); |
2725 *ok = false; | 2716 *ok = false; |
2726 return impl()->EmptyExpression(); | 2717 return impl()->EmptyExpression(); |
2727 } | 2718 } |
2728 | 2719 |
2729 // Allow the parser's implementation to rewrite the expression. | 2720 // Allow the parser's implementation to rewrite the expression. |
2730 return impl()->BuildUnaryExpression(expression, op, pos); | 2721 return impl()->BuildUnaryExpression(expression, op, pos); |
2731 } else if (Token::IsCountOp(op)) { | 2722 } else if (Token::IsCountOp(op)) { |
2732 BindingPatternUnexpectedToken(classifier); | 2723 BindingPatternUnexpectedToken(); |
2733 ArrowFormalParametersUnexpectedToken(classifier); | 2724 ArrowFormalParametersUnexpectedToken(); |
2734 op = Next(); | 2725 op = Next(); |
2735 int beg_pos = peek_position(); | 2726 int beg_pos = peek_position(); |
2736 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2727 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
2737 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2728 CheckNoTailCallExpressions(CHECK_OK); |
2738 expression = CheckAndRewriteReferenceExpression( | 2729 expression = CheckAndRewriteReferenceExpression( |
2739 expression, beg_pos, scanner()->location().end_pos, | 2730 expression, beg_pos, scanner()->location().end_pos, |
2740 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2731 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
2741 expression = impl()->MarkExpressionAsAssigned(expression); | 2732 expression = impl()->MarkExpressionAsAssigned(expression); |
2742 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2733 impl()->RewriteNonPattern(CHECK_OK); |
2743 | 2734 |
2744 return factory()->NewCountOperation(op, | 2735 return factory()->NewCountOperation(op, |
2745 true /* prefix */, | 2736 true /* prefix */, |
2746 expression, | 2737 expression, |
2747 position()); | 2738 position()); |
2748 | 2739 |
2749 } else if (is_async_function() && peek() == Token::AWAIT) { | 2740 } else if (is_async_function() && peek() == Token::AWAIT) { |
2750 classifier->RecordFormalParameterInitializerError( | 2741 classifier()->RecordFormalParameterInitializerError( |
2751 scanner()->peek_location(), | 2742 scanner()->peek_location(), |
2752 MessageTemplate::kAwaitExpressionFormalParameter); | 2743 MessageTemplate::kAwaitExpressionFormalParameter); |
2753 | 2744 |
2754 int await_pos = peek_position(); | 2745 int await_pos = peek_position(); |
2755 Consume(Token::AWAIT); | 2746 Consume(Token::AWAIT); |
2756 | 2747 |
2757 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2748 ExpressionT value = ParseUnaryExpression(CHECK_OK); |
2758 | 2749 |
2759 return impl()->RewriteAwaitExpression(value, await_pos); | 2750 return impl()->RewriteAwaitExpression(value, await_pos); |
2760 } else { | 2751 } else { |
2761 return ParsePostfixExpression(classifier, ok); | 2752 return ParsePostfixExpression(ok); |
2762 } | 2753 } |
2763 } | 2754 } |
2764 | 2755 |
2765 template <typename Impl> | 2756 template <typename Impl> |
2766 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( | 2757 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( |
2767 ExpressionClassifier* classifier, bool* ok) { | 2758 bool* ok) { |
2768 // PostfixExpression :: | 2759 // PostfixExpression :: |
2769 // LeftHandSideExpression ('++' | '--')? | 2760 // LeftHandSideExpression ('++' | '--')? |
2770 | 2761 |
2771 int lhs_beg_pos = peek_position(); | 2762 int lhs_beg_pos = peek_position(); |
2772 ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK); | 2763 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK); |
2773 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2764 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2774 Token::IsCountOp(peek())) { | 2765 Token::IsCountOp(peek())) { |
2775 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2766 CheckNoTailCallExpressions(CHECK_OK); |
2776 BindingPatternUnexpectedToken(classifier); | 2767 BindingPatternUnexpectedToken(); |
2777 ArrowFormalParametersUnexpectedToken(classifier); | 2768 ArrowFormalParametersUnexpectedToken(); |
2778 | 2769 |
2779 expression = CheckAndRewriteReferenceExpression( | 2770 expression = CheckAndRewriteReferenceExpression( |
2780 expression, lhs_beg_pos, scanner()->location().end_pos, | 2771 expression, lhs_beg_pos, scanner()->location().end_pos, |
2781 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2772 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2782 expression = impl()->MarkExpressionAsAssigned(expression); | 2773 expression = impl()->MarkExpressionAsAssigned(expression); |
2783 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2774 impl()->RewriteNonPattern(CHECK_OK); |
2784 | 2775 |
2785 Token::Value next = Next(); | 2776 Token::Value next = Next(); |
2786 expression = | 2777 expression = |
2787 factory()->NewCountOperation(next, | 2778 factory()->NewCountOperation(next, |
2788 false /* postfix */, | 2779 false /* postfix */, |
2789 expression, | 2780 expression, |
2790 position()); | 2781 position()); |
2791 } | 2782 } |
2792 return expression; | 2783 return expression; |
2793 } | 2784 } |
2794 | 2785 |
2795 template <typename Impl> | 2786 template <typename Impl> |
2796 typename ParserBase<Impl>::ExpressionT | 2787 typename ParserBase<Impl>::ExpressionT |
2797 ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 2788 ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { |
2798 bool* ok) { | |
2799 // LeftHandSideExpression :: | 2789 // LeftHandSideExpression :: |
2800 // (NewExpression | MemberExpression) ... | 2790 // (NewExpression | MemberExpression) ... |
2801 | 2791 |
2802 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { | 2792 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
2803 return ParseTailCallExpression(classifier, ok); | 2793 return ParseTailCallExpression(ok); |
2804 } | 2794 } |
2805 | 2795 |
2806 bool is_async = false; | 2796 bool is_async = false; |
2807 ExpressionT result = | 2797 ExpressionT result = |
2808 ParseMemberWithNewPrefixesExpression(classifier, &is_async, CHECK_OK); | 2798 ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK); |
2809 | 2799 |
2810 while (true) { | 2800 while (true) { |
2811 switch (peek()) { | 2801 switch (peek()) { |
2812 case Token::LBRACK: { | 2802 case Token::LBRACK: { |
2813 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2803 CheckNoTailCallExpressions(CHECK_OK); |
2814 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2804 impl()->RewriteNonPattern(CHECK_OK); |
2815 BindingPatternUnexpectedToken(classifier); | 2805 BindingPatternUnexpectedToken(); |
2816 ArrowFormalParametersUnexpectedToken(classifier); | 2806 ArrowFormalParametersUnexpectedToken(); |
2817 Consume(Token::LBRACK); | 2807 Consume(Token::LBRACK); |
2818 int pos = position(); | 2808 int pos = position(); |
2819 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2809 ExpressionT index = ParseExpressionNoWrap(true, CHECK_OK); |
2820 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2810 impl()->RewriteNonPattern(CHECK_OK); |
2821 result = factory()->NewProperty(result, index, pos); | 2811 result = factory()->NewProperty(result, index, pos); |
2822 Expect(Token::RBRACK, CHECK_OK); | 2812 Expect(Token::RBRACK, CHECK_OK); |
2823 break; | 2813 break; |
2824 } | 2814 } |
2825 | 2815 |
2826 case Token::LPAREN: { | 2816 case Token::LPAREN: { |
2827 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2817 CheckNoTailCallExpressions(CHECK_OK); |
2828 int pos; | 2818 int pos; |
2829 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2819 impl()->RewriteNonPattern(CHECK_OK); |
2830 BindingPatternUnexpectedToken(classifier); | 2820 BindingPatternUnexpectedToken(); |
2831 if (scanner()->current_token() == Token::IDENTIFIER || | 2821 if (scanner()->current_token() == Token::IDENTIFIER || |
2832 scanner()->current_token() == Token::SUPER || | 2822 scanner()->current_token() == Token::SUPER || |
2833 scanner()->current_token() == Token::ASYNC) { | 2823 scanner()->current_token() == Token::ASYNC) { |
2834 // For call of an identifier we want to report position of | 2824 // For call of an identifier we want to report position of |
2835 // the identifier as position of the call in the stack trace. | 2825 // the identifier as position of the call in the stack trace. |
2836 pos = position(); | 2826 pos = position(); |
2837 } else { | 2827 } else { |
2838 // For other kinds of calls we record position of the parenthesis as | 2828 // For other kinds of calls we record position of the parenthesis as |
2839 // position of the call. Note that this is extremely important for | 2829 // position of the call. Note that this is extremely important for |
2840 // expressions of the form function(){...}() for which call position | 2830 // expressions of the form function(){...}() for which call position |
2841 // should not point to the closing brace otherwise it will intersect | 2831 // should not point to the closing brace otherwise it will intersect |
2842 // with positions recorded for function literal and confuse debugger. | 2832 // with positions recorded for function literal and confuse debugger. |
2843 pos = peek_position(); | 2833 pos = peek_position(); |
2844 // Also the trailing parenthesis are a hint that the function will | 2834 // Also the trailing parenthesis are a hint that the function will |
2845 // be called immediately. If we happen to have parsed a preceding | 2835 // be called immediately. If we happen to have parsed a preceding |
2846 // function literal eagerly, we can also compile it eagerly. | 2836 // function literal eagerly, we can also compile it eagerly. |
2847 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2837 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2848 result->AsFunctionLiteral()->set_should_eager_compile(); | 2838 result->AsFunctionLiteral()->set_should_eager_compile(); |
2849 } | 2839 } |
2850 } | 2840 } |
2851 Scanner::Location spread_pos; | 2841 Scanner::Location spread_pos; |
2852 typename Types::ExpressionList args; | 2842 typename Types::ExpressionList args; |
2853 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { | 2843 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { |
2854 ExpressionClassifier async_classifier(this); | 2844 ExpressionClassifier async_classifier(this); |
2855 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); | 2845 args = ParseArguments(&spread_pos, true, CHECK_OK); |
2856 if (peek() == Token::ARROW) { | 2846 if (peek() == Token::ARROW) { |
2857 if (fni_) { | 2847 if (fni_) { |
2858 fni_->RemoveAsyncKeywordFromEnd(); | 2848 fni_->RemoveAsyncKeywordFromEnd(); |
2859 } | 2849 } |
2860 ValidateBindingPattern(&async_classifier, CHECK_OK); | 2850 ValidateBindingPattern(CHECK_OK); |
2861 ValidateFormalParameterInitializer(&async_classifier, CHECK_OK); | 2851 ValidateFormalParameterInitializer(CHECK_OK); |
2862 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { | 2852 if (!classifier()->is_valid_async_arrow_formal_parameters()) { |
2863 ReportClassifierError( | 2853 ReportClassifierError( |
2864 async_classifier.async_arrow_formal_parameters_error()); | 2854 classifier()->async_arrow_formal_parameters_error()); |
2865 *ok = false; | 2855 *ok = false; |
2866 return impl()->EmptyExpression(); | 2856 return impl()->EmptyExpression(); |
2867 } | 2857 } |
2868 if (args->length()) { | 2858 if (args->length()) { |
2869 // async ( Arguments ) => ... | 2859 // async ( Arguments ) => ... |
2870 return impl()->ExpressionListToExpression(args); | 2860 return impl()->ExpressionListToExpression(args); |
2871 } | 2861 } |
2872 // async () => ... | 2862 // async () => ... |
2873 return factory()->NewEmptyParentheses(pos); | 2863 return factory()->NewEmptyParentheses(pos); |
2874 } else { | 2864 } else { |
2875 classifier->AccumulateFormalParameterContainmentErrors( | 2865 impl()->AccumulateFormalParameterContainmentErrors(); |
2876 &async_classifier); | |
2877 } | 2866 } |
2878 } else { | 2867 } else { |
2879 args = ParseArguments(&spread_pos, false, classifier, CHECK_OK); | 2868 args = ParseArguments(&spread_pos, false, CHECK_OK); |
2880 } | 2869 } |
2881 | 2870 |
2882 ArrowFormalParametersUnexpectedToken(classifier); | 2871 ArrowFormalParametersUnexpectedToken(); |
2883 | 2872 |
2884 // Keep track of eval() calls since they disable all local variable | 2873 // Keep track of eval() calls since they disable all local variable |
2885 // optimizations. | 2874 // optimizations. |
2886 // The calls that need special treatment are the | 2875 // The calls that need special treatment are the |
2887 // direct eval calls. These calls are all of the form eval(...), with | 2876 // direct eval calls. These calls are all of the form eval(...), with |
2888 // no explicit receiver. | 2877 // no explicit receiver. |
2889 // These calls are marked as potentially direct eval calls. Whether | 2878 // These calls are marked as potentially direct eval calls. Whether |
2890 // they are actually direct calls to eval is determined at run time. | 2879 // they are actually direct calls to eval is determined at run time. |
2891 Call::PossiblyEval is_possibly_eval = | 2880 Call::PossiblyEval is_possibly_eval = |
2892 CheckPossibleEvalCall(result, scope()); | 2881 CheckPossibleEvalCall(result, scope()); |
(...skipping 12 matching lines...) Expand all Loading... | |
2905 ExpressionT this_expr = impl()->ThisExpression(pos); | 2894 ExpressionT this_expr = impl()->ThisExpression(pos); |
2906 result = | 2895 result = |
2907 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2896 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
2908 } | 2897 } |
2909 | 2898 |
2910 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2899 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2911 break; | 2900 break; |
2912 } | 2901 } |
2913 | 2902 |
2914 case Token::PERIOD: { | 2903 case Token::PERIOD: { |
2915 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2904 CheckNoTailCallExpressions(CHECK_OK); |
2916 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2905 impl()->RewriteNonPattern(CHECK_OK); |
2917 BindingPatternUnexpectedToken(classifier); | 2906 BindingPatternUnexpectedToken(); |
2918 ArrowFormalParametersUnexpectedToken(classifier); | 2907 ArrowFormalParametersUnexpectedToken(); |
2919 Consume(Token::PERIOD); | 2908 Consume(Token::PERIOD); |
2920 int pos = position(); | 2909 int pos = position(); |
2921 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2910 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2922 result = factory()->NewProperty( | 2911 result = factory()->NewProperty( |
2923 result, factory()->NewStringLiteral(name, pos), pos); | 2912 result, factory()->NewStringLiteral(name, pos), pos); |
2924 if (fni_ != NULL) impl()->PushLiteralName(fni_, name); | 2913 if (fni_ != NULL) impl()->PushLiteralName(fni_, name); |
2925 break; | 2914 break; |
2926 } | 2915 } |
2927 | 2916 |
2928 case Token::TEMPLATE_SPAN: | 2917 case Token::TEMPLATE_SPAN: |
2929 case Token::TEMPLATE_TAIL: { | 2918 case Token::TEMPLATE_TAIL: { |
2930 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2919 CheckNoTailCallExpressions(CHECK_OK); |
2931 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2920 impl()->RewriteNonPattern(CHECK_OK); |
2932 BindingPatternUnexpectedToken(classifier); | 2921 BindingPatternUnexpectedToken(); |
2933 ArrowFormalParametersUnexpectedToken(classifier); | 2922 ArrowFormalParametersUnexpectedToken(); |
2934 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2923 result = ParseTemplateLiteral(result, position(), CHECK_OK); |
2935 break; | 2924 break; |
2936 } | 2925 } |
2937 | 2926 |
2938 default: | 2927 default: |
2939 return result; | 2928 return result; |
2940 } | 2929 } |
2941 } | 2930 } |
2942 } | 2931 } |
2943 | 2932 |
2944 template <typename Impl> | 2933 template <typename Impl> |
2945 typename ParserBase<Impl>::ExpressionT | 2934 typename ParserBase<Impl>::ExpressionT |
2946 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression( | 2935 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async, |
2947 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 2936 bool* ok) { |
2948 // NewExpression :: | 2937 // NewExpression :: |
2949 // ('new')+ MemberExpression | 2938 // ('new')+ MemberExpression |
2950 // | 2939 // |
2951 // NewTarget :: | 2940 // NewTarget :: |
2952 // 'new' '.' 'target' | 2941 // 'new' '.' 'target' |
2953 | 2942 |
2954 // The grammar for new expressions is pretty warped. We can have several 'new' | 2943 // The grammar for new expressions is pretty warped. We can have several 'new' |
2955 // keywords following each other, and then a MemberExpression. When we see '(' | 2944 // keywords following each other, and then a MemberExpression. When we see '(' |
2956 // after the MemberExpression, it's associated with the rightmost unassociated | 2945 // after the MemberExpression, it's associated with the rightmost unassociated |
2957 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2946 // 'new' to create a NewExpression with arguments. However, a NewExpression |
2958 // can also occur without arguments. | 2947 // can also occur without arguments. |
2959 | 2948 |
2960 // Examples of new expression: | 2949 // Examples of new expression: |
2961 // new foo.bar().baz means (new (foo.bar)()).baz | 2950 // new foo.bar().baz means (new (foo.bar)()).baz |
2962 // new foo()() means (new foo())() | 2951 // new foo()() means (new foo())() |
2963 // new new foo()() means (new (new foo())()) | 2952 // new new foo()() means (new (new foo())()) |
2964 // new new foo means new (new foo) | 2953 // new new foo means new (new foo) |
2965 // new new foo() means new (new foo()) | 2954 // new new foo() means new (new foo()) |
2966 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2955 // new new foo().bar().baz means (new (new foo()).bar()).baz |
2967 | 2956 |
2968 if (peek() == Token::NEW) { | 2957 if (peek() == Token::NEW) { |
2969 BindingPatternUnexpectedToken(classifier); | 2958 BindingPatternUnexpectedToken(); |
2970 ArrowFormalParametersUnexpectedToken(classifier); | 2959 ArrowFormalParametersUnexpectedToken(); |
2971 Consume(Token::NEW); | 2960 Consume(Token::NEW); |
2972 int new_pos = position(); | 2961 int new_pos = position(); |
2973 ExpressionT result; | 2962 ExpressionT result; |
2974 if (peek() == Token::SUPER) { | 2963 if (peek() == Token::SUPER) { |
2975 const bool is_new = true; | 2964 const bool is_new = true; |
2976 result = ParseSuperExpression(is_new, CHECK_OK); | 2965 result = ParseSuperExpression(is_new, CHECK_OK); |
2977 } else if (peek() == Token::PERIOD) { | 2966 } else if (peek() == Token::PERIOD) { |
2978 return ParseNewTargetExpression(CHECK_OK); | 2967 return ParseNewTargetExpression(CHECK_OK); |
2979 } else { | 2968 } else { |
2980 result = | 2969 result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK); |
2981 ParseMemberWithNewPrefixesExpression(classifier, is_async, CHECK_OK); | |
2982 } | 2970 } |
2983 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2971 impl()->RewriteNonPattern(CHECK_OK); |
2984 if (peek() == Token::LPAREN) { | 2972 if (peek() == Token::LPAREN) { |
2985 // NewExpression with arguments. | 2973 // NewExpression with arguments. |
2986 Scanner::Location spread_pos; | 2974 Scanner::Location spread_pos; |
2987 typename Types::ExpressionList args = | 2975 typename Types::ExpressionList args = |
2988 ParseArguments(&spread_pos, classifier, CHECK_OK); | 2976 ParseArguments(&spread_pos, CHECK_OK); |
2989 | 2977 |
2990 if (spread_pos.IsValid()) { | 2978 if (spread_pos.IsValid()) { |
2991 args = impl()->PrepareSpreadArguments(args); | 2979 args = impl()->PrepareSpreadArguments(args); |
2992 result = impl()->SpreadCallNew(result, args, new_pos); | 2980 result = impl()->SpreadCallNew(result, args, new_pos); |
2993 } else { | 2981 } else { |
2994 result = factory()->NewCallNew(result, args, new_pos); | 2982 result = factory()->NewCallNew(result, args, new_pos); |
2995 } | 2983 } |
2996 // The expression can still continue with . or [ after the arguments. | 2984 // The expression can still continue with . or [ after the arguments. |
2997 result = ParseMemberExpressionContinuation(result, is_async, classifier, | 2985 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); |
2998 CHECK_OK); | |
2999 return result; | 2986 return result; |
3000 } | 2987 } |
3001 // NewExpression without arguments. | 2988 // NewExpression without arguments. |
3002 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); | 2989 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); |
3003 } | 2990 } |
3004 // No 'new' or 'super' keyword. | 2991 // No 'new' or 'super' keyword. |
3005 return ParseMemberExpression(classifier, is_async, ok); | 2992 return ParseMemberExpression(is_async, ok); |
3006 } | 2993 } |
3007 | 2994 |
3008 template <typename Impl> | 2995 template <typename Impl> |
3009 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( | 2996 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( |
3010 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 2997 bool* is_async, bool* ok) { |
3011 // MemberExpression :: | 2998 // MemberExpression :: |
3012 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2999 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
3013 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3000 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
3014 | 3001 |
3015 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3002 // The '[' Expression ']' and '.' Identifier parts are parsed by |
3016 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3003 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
3017 // caller. | 3004 // caller. |
3018 | 3005 |
3019 // Parse the initial primary or function expression. | 3006 // Parse the initial primary or function expression. |
3020 ExpressionT result; | 3007 ExpressionT result; |
3021 if (peek() == Token::FUNCTION) { | 3008 if (peek() == Token::FUNCTION) { |
3022 BindingPatternUnexpectedToken(classifier); | 3009 BindingPatternUnexpectedToken(); |
3023 ArrowFormalParametersUnexpectedToken(classifier); | 3010 ArrowFormalParametersUnexpectedToken(); |
3024 | 3011 |
3025 Consume(Token::FUNCTION); | 3012 Consume(Token::FUNCTION); |
3026 int function_token_position = position(); | 3013 int function_token_position = position(); |
3027 | 3014 |
3028 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { | 3015 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { |
3029 // function.sent | 3016 // function.sent |
3030 int pos = position(); | 3017 int pos = position(); |
3031 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); | 3018 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); |
3032 | 3019 |
3033 if (!is_generator()) { | 3020 if (!is_generator()) { |
(...skipping 24 matching lines...) Expand all Loading... | |
3058 result = impl()->ParseFunctionLiteral( | 3045 result = impl()->ParseFunctionLiteral( |
3059 name, function_name_location, | 3046 name, function_name_location, |
3060 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3047 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3061 : kFunctionNameValidityUnknown, | 3048 : kFunctionNameValidityUnknown, |
3062 function_kind, function_token_position, function_type, language_mode(), | 3049 function_kind, function_token_position, function_type, language_mode(), |
3063 CHECK_OK); | 3050 CHECK_OK); |
3064 } else if (peek() == Token::SUPER) { | 3051 } else if (peek() == Token::SUPER) { |
3065 const bool is_new = false; | 3052 const bool is_new = false; |
3066 result = ParseSuperExpression(is_new, CHECK_OK); | 3053 result = ParseSuperExpression(is_new, CHECK_OK); |
3067 } else { | 3054 } else { |
3068 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); | 3055 result = ParsePrimaryExpression(is_async, CHECK_OK); |
3069 } | 3056 } |
3070 | 3057 |
3071 result = | 3058 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); |
3072 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); | |
3073 return result; | 3059 return result; |
3074 } | 3060 } |
3075 | 3061 |
3076 template <typename Impl> | 3062 template <typename Impl> |
3077 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( | 3063 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( |
3078 bool is_new, bool* ok) { | 3064 bool is_new, bool* ok) { |
3079 Expect(Token::SUPER, CHECK_OK); | 3065 Expect(Token::SUPER, CHECK_OK); |
3080 int pos = position(); | 3066 int pos = position(); |
3081 | 3067 |
3082 DeclarationScope* scope = GetReceiverScope(); | 3068 DeclarationScope* scope = GetReceiverScope(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3127 MessageTemplate::kUnexpectedNewTarget); | 3113 MessageTemplate::kUnexpectedNewTarget); |
3128 *ok = false; | 3114 *ok = false; |
3129 return impl()->EmptyExpression(); | 3115 return impl()->EmptyExpression(); |
3130 } | 3116 } |
3131 | 3117 |
3132 return impl()->NewTargetExpression(pos); | 3118 return impl()->NewTargetExpression(pos); |
3133 } | 3119 } |
3134 | 3120 |
3135 template <typename Impl> | 3121 template <typename Impl> |
3136 typename ParserBase<Impl>::ExpressionT | 3122 typename ParserBase<Impl>::ExpressionT |
3137 ParserBase<Impl>::ParseMemberExpressionContinuation( | 3123 ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, |
3138 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3124 bool* is_async, bool* ok) { |
3139 bool* ok) { | |
3140 // Parses this part of MemberExpression: | 3125 // Parses this part of MemberExpression: |
3141 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3126 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3142 while (true) { | 3127 while (true) { |
3143 switch (peek()) { | 3128 switch (peek()) { |
3144 case Token::LBRACK: { | 3129 case Token::LBRACK: { |
3145 *is_async = false; | 3130 *is_async = false; |
3146 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3131 impl()->RewriteNonPattern(CHECK_OK); |
3147 BindingPatternUnexpectedToken(classifier); | 3132 BindingPatternUnexpectedToken(); |
3148 ArrowFormalParametersUnexpectedToken(classifier); | 3133 ArrowFormalParametersUnexpectedToken(); |
3149 | 3134 |
3150 Consume(Token::LBRACK); | 3135 Consume(Token::LBRACK); |
3151 int pos = position(); | 3136 int pos = position(); |
3152 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3137 ExpressionT index = ParseExpressionNoWrap(true, CHECK_OK); |
3153 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3138 impl()->RewriteNonPattern(CHECK_OK); |
3154 expression = factory()->NewProperty(expression, index, pos); | 3139 expression = factory()->NewProperty(expression, index, pos); |
3155 if (fni_ != NULL) { | 3140 if (fni_ != NULL) { |
3156 impl()->PushPropertyName(fni_, index); | 3141 impl()->PushPropertyName(fni_, index); |
3157 } | 3142 } |
3158 Expect(Token::RBRACK, CHECK_OK); | 3143 Expect(Token::RBRACK, CHECK_OK); |
3159 break; | 3144 break; |
3160 } | 3145 } |
3161 case Token::PERIOD: { | 3146 case Token::PERIOD: { |
3162 *is_async = false; | 3147 *is_async = false; |
3163 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3148 impl()->RewriteNonPattern(CHECK_OK); |
3164 BindingPatternUnexpectedToken(classifier); | 3149 BindingPatternUnexpectedToken(); |
3165 ArrowFormalParametersUnexpectedToken(classifier); | 3150 ArrowFormalParametersUnexpectedToken(); |
3166 | 3151 |
3167 Consume(Token::PERIOD); | 3152 Consume(Token::PERIOD); |
3168 int pos = position(); | 3153 int pos = position(); |
3169 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3154 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3170 expression = factory()->NewProperty( | 3155 expression = factory()->NewProperty( |
3171 expression, factory()->NewStringLiteral(name, pos), pos); | 3156 expression, factory()->NewStringLiteral(name, pos), pos); |
3172 if (fni_ != NULL) { | 3157 if (fni_ != NULL) { |
3173 impl()->PushLiteralName(fni_, name); | 3158 impl()->PushLiteralName(fni_, name); |
3174 } | 3159 } |
3175 break; | 3160 break; |
3176 } | 3161 } |
3177 case Token::TEMPLATE_SPAN: | 3162 case Token::TEMPLATE_SPAN: |
3178 case Token::TEMPLATE_TAIL: { | 3163 case Token::TEMPLATE_TAIL: { |
3179 *is_async = false; | 3164 *is_async = false; |
3180 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3165 impl()->RewriteNonPattern(CHECK_OK); |
3181 BindingPatternUnexpectedToken(classifier); | 3166 BindingPatternUnexpectedToken(); |
3182 ArrowFormalParametersUnexpectedToken(classifier); | 3167 ArrowFormalParametersUnexpectedToken(); |
3183 int pos; | 3168 int pos; |
3184 if (scanner()->current_token() == Token::IDENTIFIER) { | 3169 if (scanner()->current_token() == Token::IDENTIFIER) { |
3185 pos = position(); | 3170 pos = position(); |
3186 } else { | 3171 } else { |
3187 pos = peek_position(); | 3172 pos = peek_position(); |
3188 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3173 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3189 // If the tag function looks like an IIFE, set_parenthesized() to | 3174 // If the tag function looks like an IIFE, set_parenthesized() to |
3190 // force eager compilation. | 3175 // force eager compilation. |
3191 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3176 expression->AsFunctionLiteral()->set_should_eager_compile(); |
3192 } | 3177 } |
3193 } | 3178 } |
3194 expression = | 3179 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); |
3195 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | |
3196 break; | 3180 break; |
3197 } | 3181 } |
3198 case Token::ILLEGAL: { | 3182 case Token::ILLEGAL: { |
3199 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); | 3183 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); |
3200 *ok = false; | 3184 *ok = false; |
3201 return impl()->EmptyExpression(); | 3185 return impl()->EmptyExpression(); |
3202 } | 3186 } |
3203 default: | 3187 default: |
3204 return expression; | 3188 return expression; |
3205 } | 3189 } |
3206 } | 3190 } |
3207 DCHECK(false); | 3191 DCHECK(false); |
3208 return impl()->EmptyExpression(); | 3192 return impl()->EmptyExpression(); |
3209 } | 3193 } |
3210 | 3194 |
3211 template <typename Impl> | 3195 template <typename Impl> |
3212 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, | 3196 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, |
3213 ExpressionClassifier* classifier, | |
3214 bool* ok) { | 3197 bool* ok) { |
3215 // FormalParameter[Yield,GeneratorParameter] : | 3198 // FormalParameter[Yield,GeneratorParameter] : |
3216 // BindingElement[?Yield, ?GeneratorParameter] | 3199 // BindingElement[?Yield, ?GeneratorParameter] |
3217 bool is_rest = parameters->has_rest; | 3200 bool is_rest = parameters->has_rest; |
3218 | 3201 |
3219 ExpressionT pattern = | 3202 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void)); |
3220 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); | 3203 ValidateBindingPattern(CHECK_OK_CUSTOM(Void)); |
3221 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); | |
3222 | 3204 |
3223 if (!impl()->IsIdentifier(pattern)) { | 3205 if (!impl()->IsIdentifier(pattern)) { |
3224 parameters->is_simple = false; | 3206 parameters->is_simple = false; |
3225 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); | 3207 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); |
3226 classifier->RecordNonSimpleParameter(); | 3208 classifier()->RecordNonSimpleParameter(); |
3227 } | 3209 } |
3228 | 3210 |
3229 ExpressionT initializer = impl()->EmptyExpression(); | 3211 ExpressionT initializer = impl()->EmptyExpression(); |
3230 if (!is_rest && Check(Token::ASSIGN)) { | 3212 if (!is_rest && Check(Token::ASSIGN)) { |
3231 ExpressionClassifier init_classifier(this); | 3213 ExpressionClassifier init_classifier(this); |
3232 initializer = ParseAssignmentExpression(true, &init_classifier, | 3214 initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void)); |
3233 CHECK_OK_CUSTOM(Void)); | 3215 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); |
3234 impl()->RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3216 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); |
3235 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); | |
3236 parameters->is_simple = false; | 3217 parameters->is_simple = false; |
3237 init_classifier.Discard(); | 3218 impl()->Discard(); |
3238 classifier->RecordNonSimpleParameter(); | 3219 classifier()->RecordNonSimpleParameter(); |
3239 | 3220 |
3240 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern); | 3221 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern); |
3241 } | 3222 } |
3242 | 3223 |
3243 impl()->AddFormalParameter(parameters, pattern, initializer, | 3224 impl()->AddFormalParameter(parameters, pattern, initializer, |
3244 scanner()->location().end_pos, is_rest); | 3225 scanner()->location().end_pos, is_rest); |
3245 } | 3226 } |
3246 | 3227 |
3247 template <typename Impl> | 3228 template <typename Impl> |
3248 void ParserBase<Impl>::ParseFormalParameterList( | 3229 void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, |
3249 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3230 bool* ok) { |
3250 // FormalParameters[Yield] : | 3231 // FormalParameters[Yield] : |
3251 // [empty] | 3232 // [empty] |
3252 // FunctionRestParameter[?Yield] | 3233 // FunctionRestParameter[?Yield] |
3253 // FormalParameterList[?Yield] | 3234 // FormalParameterList[?Yield] |
3254 // FormalParameterList[?Yield] , | 3235 // FormalParameterList[?Yield] , |
3255 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] | 3236 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] |
3256 // | 3237 // |
3257 // FormalParameterList[Yield] : | 3238 // FormalParameterList[Yield] : |
3258 // FormalParameter[?Yield] | 3239 // FormalParameter[?Yield] |
3259 // FormalParameterList[?Yield] , FormalParameter[?Yield] | 3240 // FormalParameterList[?Yield] , FormalParameter[?Yield] |
3260 | 3241 |
3261 DCHECK_EQ(0, parameters->Arity()); | 3242 DCHECK_EQ(0, parameters->Arity()); |
3262 | 3243 |
3263 if (peek() != Token::RPAREN) { | 3244 if (peek() != Token::RPAREN) { |
3264 while (true) { | 3245 while (true) { |
3265 if (parameters->Arity() > Code::kMaxArguments) { | 3246 if (parameters->Arity() > Code::kMaxArguments) { |
3266 ReportMessage(MessageTemplate::kTooManyParameters); | 3247 ReportMessage(MessageTemplate::kTooManyParameters); |
3267 *ok = false; | 3248 *ok = false; |
3268 return; | 3249 return; |
3269 } | 3250 } |
3270 parameters->has_rest = Check(Token::ELLIPSIS); | 3251 parameters->has_rest = Check(Token::ELLIPSIS); |
3271 ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void)); | 3252 ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void)); |
3272 | 3253 |
3273 if (parameters->has_rest) { | 3254 if (parameters->has_rest) { |
3274 parameters->is_simple = false; | 3255 parameters->is_simple = false; |
3275 classifier->RecordNonSimpleParameter(); | 3256 classifier()->RecordNonSimpleParameter(); |
3276 if (peek() == Token::COMMA) { | 3257 if (peek() == Token::COMMA) { |
3277 impl()->ReportMessageAt(scanner()->peek_location(), | 3258 impl()->ReportMessageAt(scanner()->peek_location(), |
3278 MessageTemplate::kParamAfterRest); | 3259 MessageTemplate::kParamAfterRest); |
3279 *ok = false; | 3260 *ok = false; |
3280 return; | 3261 return; |
3281 } | 3262 } |
3282 break; | 3263 break; |
3283 } | 3264 } |
3284 if (!Check(Token::COMMA)) break; | 3265 if (!Check(Token::COMMA)) break; |
3285 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { | 3266 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { |
3286 // allow the trailing comma | 3267 // allow the trailing comma |
3287 break; | 3268 break; |
3288 } | 3269 } |
3289 } | 3270 } |
3290 } | 3271 } |
3291 | 3272 |
3292 for (int i = 0; i < parameters->Arity(); ++i) { | 3273 for (int i = 0; i < parameters->Arity(); ++i) { |
3293 auto parameter = parameters->at(i); | 3274 auto parameter = parameters->at(i); |
3294 impl()->DeclareFormalParameter(parameters->scope, parameter, classifier); | 3275 impl()->DeclareFormalParameter(parameters->scope, parameter); |
3295 } | 3276 } |
3296 } | 3277 } |
3297 | 3278 |
3298 template <typename Impl> | 3279 template <typename Impl> |
3299 void ParserBase<Impl>::CheckArityRestrictions(int param_count, | 3280 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
3300 FunctionKind function_kind, | 3281 FunctionKind function_kind, |
3301 bool has_rest, | 3282 bool has_rest, |
3302 int formals_start_pos, | 3283 int formals_start_pos, |
3303 int formals_end_pos, bool* ok) { | 3284 int formals_end_pos, bool* ok) { |
3304 if (IsGetterFunction(function_kind)) { | 3285 if (IsGetterFunction(function_kind)) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3364 return true; | 3345 return true; |
3365 } | 3346 } |
3366 } | 3347 } |
3367 return false; | 3348 return false; |
3368 } | 3349 } |
3369 | 3350 |
3370 template <typename Impl> | 3351 template <typename Impl> |
3371 typename ParserBase<Impl>::ExpressionT | 3352 typename ParserBase<Impl>::ExpressionT |
3372 ParserBase<Impl>::ParseArrowFunctionLiteral( | 3353 ParserBase<Impl>::ParseArrowFunctionLiteral( |
3373 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, | 3354 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
3374 const ExpressionClassifier& formals_classifier, bool* ok) { | 3355 bool* ok) { |
3375 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3356 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3376 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3357 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3377 // `=> ...` is never a valid expression, so report as syntax error. | 3358 // `=> ...` is never a valid expression, so report as syntax error. |
3378 // If next token is not `=>`, it's a syntax error anyways. | 3359 // If next token is not `=>`, it's a syntax error anyways. |
3379 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3360 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3380 *ok = false; | 3361 *ok = false; |
3381 return impl()->EmptyExpression(); | 3362 return impl()->EmptyExpression(); |
3382 } | 3363 } |
3383 | 3364 |
3384 typename Types::StatementList body; | 3365 typename Types::StatementList body; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3425 int pos = position(); | 3406 int pos = position(); |
3426 DCHECK(ReturnExprContext::kInsideValidBlock == | 3407 DCHECK(ReturnExprContext::kInsideValidBlock == |
3427 function_state_->return_expr_context()); | 3408 function_state_->return_expr_context()); |
3428 ReturnExprScope allow_tail_calls( | 3409 ReturnExprScope allow_tail_calls( |
3429 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3410 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
3430 body = impl()->NewStatementList(1); | 3411 body = impl()->NewStatementList(1); |
3431 impl()->AddParameterInitializationBlock(formal_parameters, body, is_async, | 3412 impl()->AddParameterInitializationBlock(formal_parameters, body, is_async, |
3432 CHECK_OK); | 3413 CHECK_OK); |
3433 ExpressionClassifier classifier(this); | 3414 ExpressionClassifier classifier(this); |
3434 if (is_async) { | 3415 if (is_async) { |
3435 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, | 3416 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, pos, |
3436 &classifier, pos, CHECK_OK); | 3417 CHECK_OK); |
3437 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 3418 impl()->RewriteNonPattern(CHECK_OK); |
3438 } else { | 3419 } else { |
3439 ExpressionT expression = | 3420 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
3440 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3421 impl()->RewriteNonPattern(CHECK_OK); |
3441 impl()->RewriteNonPattern(&classifier, CHECK_OK); | |
3442 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3422 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3443 if (allow_tailcalls() && !is_sloppy(language_mode())) { | 3423 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
3444 // ES6 14.6.1 Static Semantics: IsInTailPosition | 3424 // ES6 14.6.1 Static Semantics: IsInTailPosition |
3445 impl()->MarkTailPosition(expression); | 3425 impl()->MarkTailPosition(expression); |
3446 } | 3426 } |
3447 } | 3427 } |
3448 materialized_literal_count = function_state.materialized_literal_count(); | 3428 materialized_literal_count = function_state.materialized_literal_count(); |
3449 expected_property_count = function_state.expected_property_count(); | 3429 expected_property_count = function_state.expected_property_count(); |
3450 impl()->MarkCollectedTailCallExpressions(); | 3430 impl()->MarkCollectedTailCallExpressions(); |
3451 } | 3431 } |
3452 | 3432 |
3453 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3433 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3454 | 3434 |
3455 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3435 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3456 // which is not the same as "parameters of a strict function"; it only means | 3436 // which is not the same as "parameters of a strict function"; it only means |
3457 // that duplicates are not allowed. Of course, the arrow function may | 3437 // that duplicates are not allowed. Of course, the arrow function may |
3458 // itself be strict as well. | 3438 // itself be strict as well. |
3459 const bool allow_duplicate_parameters = false; | 3439 const bool allow_duplicate_parameters = false; |
3460 ValidateFormalParameters(&formals_classifier, language_mode(), | 3440 ValidateFormalParameters(language_mode(), allow_duplicate_parameters, |
3461 allow_duplicate_parameters, CHECK_OK); | 3441 CHECK_OK); |
3462 | 3442 |
3463 // Validate strict mode. | 3443 // Validate strict mode. |
3464 if (is_strict(language_mode())) { | 3444 if (is_strict(language_mode())) { |
3465 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3445 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3466 scanner()->location().end_pos, CHECK_OK); | 3446 scanner()->location().end_pos, CHECK_OK); |
3467 } | 3447 } |
3468 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3448 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3469 | 3449 |
3470 impl()->RewriteDestructuringAssignments(); | 3450 impl()->RewriteDestructuringAssignments(); |
3471 } | 3451 } |
3472 | 3452 |
3473 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3453 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3474 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 3454 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
3475 materialized_literal_count, expected_property_count, num_parameters, | 3455 materialized_literal_count, expected_property_count, num_parameters, |
3476 FunctionLiteral::kNoDuplicateParameters, | 3456 FunctionLiteral::kNoDuplicateParameters, |
3477 FunctionLiteral::kAnonymousExpression, | 3457 FunctionLiteral::kAnonymousExpression, |
3478 FunctionLiteral::kShouldLazyCompile, arrow_kind, | 3458 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3479 formal_parameters.scope->start_position()); | 3459 formal_parameters.scope->start_position()); |
3480 | 3460 |
3481 function_literal->set_function_token_position( | 3461 function_literal->set_function_token_position( |
3482 formal_parameters.scope->start_position()); | 3462 formal_parameters.scope->start_position()); |
3483 | 3463 |
3484 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); | 3464 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); |
3485 | 3465 |
3486 return function_literal; | 3466 return function_literal; |
3487 } | 3467 } |
3488 | 3468 |
3489 template <typename Impl> | 3469 template <typename Impl> |
3490 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 3470 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
3491 ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok) { | 3471 ExpressionT tag, int start, bool* ok) { |
3492 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3472 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
3493 // text followed by a substitution expression), finalized by a single | 3473 // text followed by a substitution expression), finalized by a single |
3494 // TEMPLATE_TAIL. | 3474 // TEMPLATE_TAIL. |
3495 // | 3475 // |
3496 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3476 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
3497 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3477 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
3498 // NoSubstitutionTemplate. | 3478 // NoSubstitutionTemplate. |
3499 // | 3479 // |
3500 // When parsing a TemplateLiteral, we must have scanned either an initial | 3480 // When parsing a TemplateLiteral, we must have scanned either an initial |
3501 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3481 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3533 return impl()->EmptyExpression(); | 3513 return impl()->EmptyExpression(); |
3534 } else if (next == Token::ILLEGAL) { | 3514 } else if (next == Token::ILLEGAL) { |
3535 impl()->ReportMessageAt( | 3515 impl()->ReportMessageAt( |
3536 Scanner::Location(position() + 1, peek_position()), | 3516 Scanner::Location(position() + 1, peek_position()), |
3537 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3517 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3538 *ok = false; | 3518 *ok = false; |
3539 return impl()->EmptyExpression(); | 3519 return impl()->EmptyExpression(); |
3540 } | 3520 } |
3541 | 3521 |
3542 int expr_pos = peek_position(); | 3522 int expr_pos = peek_position(); |
3543 ExpressionT expression = ParseExpression(true, classifier, CHECK_OK); | 3523 ExpressionT expression = ParseExpressionNoWrap(true, CHECK_OK); |
3544 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3524 CheckNoTailCallExpressions(CHECK_OK); |
3545 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3525 impl()->RewriteNonPattern(CHECK_OK); |
3546 impl()->AddTemplateExpression(&ts, expression); | 3526 impl()->AddTemplateExpression(&ts, expression); |
3547 | 3527 |
3548 if (peek() != Token::RBRACE) { | 3528 if (peek() != Token::RBRACE) { |
3549 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3529 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3550 MessageTemplate::kUnterminatedTemplateExpr); | 3530 MessageTemplate::kUnterminatedTemplateExpr); |
3551 *ok = false; | 3531 *ok = false; |
3552 return impl()->EmptyExpression(); | 3532 return impl()->EmptyExpression(); |
3553 } | 3533 } |
3554 | 3534 |
3555 // If we didn't die parsing that expression, our next token should be a | 3535 // If we didn't die parsing that expression, our next token should be a |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3614 *ok = false; | 3594 *ok = false; |
3615 return impl()->EmptyExpression(); | 3595 return impl()->EmptyExpression(); |
3616 } | 3596 } |
3617 | 3597 |
3618 template <typename Impl> | 3598 template <typename Impl> |
3619 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { | 3599 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { |
3620 return IsAssignableIdentifier(expression) || expression->IsProperty(); | 3600 return IsAssignableIdentifier(expression) || expression->IsProperty(); |
3621 } | 3601 } |
3622 | 3602 |
3623 template <typename Impl> | 3603 template <typename Impl> |
3624 void ParserBase<Impl>::CheckDestructuringElement( | 3604 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, |
3625 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3605 int begin, int end) { |
3626 int end) { | |
3627 if (!IsValidPattern(expression) && !expression->IsAssignment() && | 3606 if (!IsValidPattern(expression) && !expression->IsAssignment() && |
3628 !IsValidReferenceExpression(expression)) { | 3607 !IsValidReferenceExpression(expression)) { |
3629 classifier->RecordAssignmentPatternError( | 3608 classifier()->RecordAssignmentPatternError( |
3630 Scanner::Location(begin, end), | 3609 Scanner::Location(begin, end), |
3631 MessageTemplate::kInvalidDestructuringTarget); | 3610 MessageTemplate::kInvalidDestructuringTarget); |
3632 } | 3611 } |
3633 } | 3612 } |
3634 | 3613 |
3635 | 3614 |
3636 #undef CHECK_OK | 3615 #undef CHECK_OK |
3637 #undef CHECK_OK_CUSTOM | 3616 #undef CHECK_OK_CUSTOM |
3638 | 3617 |
3639 template <typename Impl> | 3618 template <typename Impl> |
3640 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( | 3619 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( |
3641 Token::Value property, PropertyKind type, MethodKind method_type, | 3620 Token::Value property, PropertyKind type, MethodKind method_type, |
3642 ExpressionClassifier* classifier, bool* ok) { | 3621 bool* ok) { |
3643 DCHECK(!IsStaticMethod(method_type)); | 3622 DCHECK(!IsStaticMethod(method_type)); |
3644 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); | 3623 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); |
3645 | 3624 |
3646 if (property == Token::SMI || property == Token::NUMBER) return; | 3625 if (property == Token::SMI || property == Token::NUMBER) return; |
3647 | 3626 |
3648 if (type == kValueProperty && IsProto()) { | 3627 if (type == kValueProperty && IsProto()) { |
3649 if (has_seen_proto_) { | 3628 if (has_seen_proto_) { |
3650 classifier->RecordExpressionError(this->scanner()->location(), | 3629 this->parser()->classifier()->RecordExpressionError( |
3651 MessageTemplate::kDuplicateProto); | 3630 this->scanner()->location(), MessageTemplate::kDuplicateProto); |
3652 return; | 3631 return; |
3653 } | 3632 } |
3654 has_seen_proto_ = true; | 3633 has_seen_proto_ = true; |
3655 } | 3634 } |
3656 } | 3635 } |
3657 | 3636 |
3658 template <typename Impl> | 3637 template <typename Impl> |
3659 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( | 3638 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( |
3660 Token::Value property, PropertyKind type, MethodKind method_type, | 3639 Token::Value property, PropertyKind type, MethodKind method_type, |
3661 ExpressionClassifier* classifier, bool* ok) { | 3640 bool* ok) { |
3662 DCHECK(type == kMethodProperty || type == kAccessorProperty); | 3641 DCHECK(type == kMethodProperty || type == kAccessorProperty); |
3663 | 3642 |
3664 if (property == Token::SMI || property == Token::NUMBER) return; | 3643 if (property == Token::SMI || property == Token::NUMBER) return; |
3665 | 3644 |
3666 if (IsStaticMethod(method_type)) { | 3645 if (IsStaticMethod(method_type)) { |
3667 if (IsPrototype()) { | 3646 if (IsPrototype()) { |
3668 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); | 3647 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
3669 *ok = false; | 3648 *ok = false; |
3670 return; | 3649 return; |
3671 } | 3650 } |
(...skipping 17 matching lines...) Expand all Loading... | |
3689 has_seen_constructor_ = true; | 3668 has_seen_constructor_ = true; |
3690 return; | 3669 return; |
3691 } | 3670 } |
3692 } | 3671 } |
3693 | 3672 |
3694 | 3673 |
3695 } // namespace internal | 3674 } // namespace internal |
3696 } // namespace v8 | 3675 } // namespace v8 |
3697 | 3676 |
3698 #endif // V8_PARSING_PARSER_BASE_H | 3677 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |