| 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 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 863 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 861 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, | 864 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
| 862 ok); | 865 ok); |
| 863 } | 866 } |
| 864 | 867 |
| 865 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 868 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 866 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, | 869 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
| 867 ok); | 870 ok); |
| 868 } | 871 } |
| 869 | 872 |
| 870 void CheckDestructuringElement(ExpressionT element, | 873 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); |
| 871 ExpressionClassifier* classifier, int beg_pos, | |
| 872 int end_pos); | |
| 873 | 874 |
| 874 // Checking the name of a function literal. This has to be done after parsing | 875 // Checking the name of a function literal. This has to be done after parsing |
| 875 // the function, since the function can declare itself strict. | 876 // the function, since the function can declare itself strict. |
| 876 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 877 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
| 877 FunctionNameValidity function_name_validity, | 878 FunctionNameValidity function_name_validity, |
| 878 const Scanner::Location& function_name_loc, bool* ok) { | 879 const Scanner::Location& function_name_loc, bool* ok) { |
| 879 if (function_name_validity == kSkipFunctionNameCheck) return; | 880 if (function_name_validity == kSkipFunctionNameCheck) return; |
| 880 // The function name needs to be checked in strict mode. | 881 // The function name needs to be checked in strict mode. |
| 881 if (is_sloppy(language_mode)) return; | 882 if (is_sloppy(language_mode)) return; |
| 882 | 883 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 void ReportUnexpectedTokenAt( | 943 void ReportUnexpectedTokenAt( |
| 943 Scanner::Location location, Token::Value token, | 944 Scanner::Location location, Token::Value token, |
| 944 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 945 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
| 945 | 946 |
| 946 void ReportClassifierError( | 947 void ReportClassifierError( |
| 947 const typename ExpressionClassifier::Error& error) { | 948 const typename ExpressionClassifier::Error& error) { |
| 948 impl()->ReportMessageAt(error.location, error.message, error.arg, | 949 impl()->ReportMessageAt(error.location, error.message, error.arg, |
| 949 error.type); | 950 error.type); |
| 950 } | 951 } |
| 951 | 952 |
| 952 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 953 void ValidateExpression(bool* ok) { |
| 953 if (!classifier->is_valid_expression()) { | 954 if (!classifier()->is_valid_expression()) { |
| 954 ReportClassifierError(classifier->expression_error()); | 955 ReportClassifierError(classifier()->expression_error()); |
| 955 *ok = false; | 956 *ok = false; |
| 956 } | 957 } |
| 957 } | 958 } |
| 958 | 959 |
| 959 void ValidateFormalParameterInitializer( | 960 void ValidateFormalParameterInitializer(bool* ok) { |
| 960 const ExpressionClassifier* classifier, bool* ok) { | 961 if (!classifier()->is_valid_formal_parameter_initializer()) { |
| 961 if (!classifier->is_valid_formal_parameter_initializer()) { | 962 ReportClassifierError(classifier()->formal_parameter_initializer_error()); |
| 962 ReportClassifierError(classifier->formal_parameter_initializer_error()); | |
| 963 *ok = false; | 963 *ok = false; |
| 964 } | 964 } |
| 965 } | 965 } |
| 966 | 966 |
| 967 void ValidateBindingPattern(const ExpressionClassifier* classifier, | 967 void ValidateBindingPattern(bool* ok) { |
| 968 bool* ok) { | 968 if (!classifier()->is_valid_binding_pattern()) { |
| 969 if (!classifier->is_valid_binding_pattern()) { | 969 ReportClassifierError(classifier()->binding_pattern_error()); |
| 970 ReportClassifierError(classifier->binding_pattern_error()); | |
| 971 *ok = false; | 970 *ok = false; |
| 972 } | 971 } |
| 973 } | 972 } |
| 974 | 973 |
| 975 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, | 974 void ValidateAssignmentPattern(bool* ok) { |
| 976 bool* ok) { | 975 if (!classifier()->is_valid_assignment_pattern()) { |
| 977 if (!classifier->is_valid_assignment_pattern()) { | 976 ReportClassifierError(classifier()->assignment_pattern_error()); |
| 978 ReportClassifierError(classifier->assignment_pattern_error()); | |
| 979 *ok = false; | 977 *ok = false; |
| 980 } | 978 } |
| 981 } | 979 } |
| 982 | 980 |
| 983 void ValidateFormalParameters(const ExpressionClassifier* classifier, | 981 void ValidateFormalParameters(LanguageMode language_mode, |
| 984 LanguageMode language_mode, | |
| 985 bool allow_duplicates, bool* ok) { | 982 bool allow_duplicates, bool* ok) { |
| 986 if (!allow_duplicates && | 983 if (!allow_duplicates && |
| 987 !classifier->is_valid_formal_parameter_list_without_duplicates()) { | 984 !classifier()->is_valid_formal_parameter_list_without_duplicates()) { |
| 988 ReportClassifierError(classifier->duplicate_formal_parameter_error()); | 985 ReportClassifierError(classifier()->duplicate_formal_parameter_error()); |
| 989 *ok = false; | 986 *ok = false; |
| 990 } else if (is_strict(language_mode) && | 987 } else if (is_strict(language_mode) && |
| 991 !classifier->is_valid_strict_mode_formal_parameters()) { | 988 !classifier()->is_valid_strict_mode_formal_parameters()) { |
| 992 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 989 ReportClassifierError(classifier()->strict_mode_formal_parameter_error()); |
| 993 *ok = false; | 990 *ok = false; |
| 994 } | 991 } |
| 995 } | 992 } |
| 996 | 993 |
| 997 bool IsValidArrowFormalParametersStart(Token::Value token) { | 994 bool IsValidArrowFormalParametersStart(Token::Value token) { |
| 998 return is_any_identifier(token) || token == Token::LPAREN; | 995 return is_any_identifier(token) || token == Token::LPAREN; |
| 999 } | 996 } |
| 1000 | 997 |
| 1001 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 998 void ValidateArrowFormalParameters(ExpressionT expr, |
| 1002 ExpressionT expr, | |
| 1003 bool parenthesized_formals, bool is_async, | 999 bool parenthesized_formals, bool is_async, |
| 1004 bool* ok) { | 1000 bool* ok) { |
| 1005 if (classifier->is_valid_binding_pattern()) { | 1001 if (classifier()->is_valid_binding_pattern()) { |
| 1006 // A simple arrow formal parameter: IDENTIFIER => BODY. | 1002 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 1007 if (!impl()->IsIdentifier(expr)) { | 1003 if (!impl()->IsIdentifier(expr)) { |
| 1008 impl()->ReportMessageAt(scanner()->location(), | 1004 impl()->ReportMessageAt(scanner()->location(), |
| 1009 MessageTemplate::kUnexpectedToken, | 1005 MessageTemplate::kUnexpectedToken, |
| 1010 Token::String(scanner()->current_token())); | 1006 Token::String(scanner()->current_token())); |
| 1011 *ok = false; | 1007 *ok = false; |
| 1012 } | 1008 } |
| 1013 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 1009 } else if (!classifier()->is_valid_arrow_formal_parameters()) { |
| 1014 // If after parsing the expr, we see an error but the expression is | 1010 // If after parsing the expr, we see an error but the expression is |
| 1015 // neither a valid binding pattern nor a valid parenthesized formal | 1011 // neither a valid binding pattern nor a valid parenthesized formal |
| 1016 // parameter list, show the "arrow formal parameters" error if the formals | 1012 // parameter list, show the "arrow formal parameters" error if the formals |
| 1017 // started with a parenthesis, and the binding pattern error otherwise. | 1013 // started with a parenthesis, and the binding pattern error otherwise. |
| 1018 const typename ExpressionClassifier::Error& error = | 1014 const typename ExpressionClassifier::Error& error = |
| 1019 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 1015 parenthesized_formals ? classifier()->arrow_formal_parameters_error() |
| 1020 : classifier->binding_pattern_error(); | 1016 : classifier()->binding_pattern_error(); |
| 1021 ReportClassifierError(error); | 1017 ReportClassifierError(error); |
| 1022 *ok = false; | 1018 *ok = false; |
| 1023 } | 1019 } |
| 1024 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | 1020 if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) { |
| 1025 const typename ExpressionClassifier::Error& error = | 1021 const typename ExpressionClassifier::Error& error = |
| 1026 classifier->async_arrow_formal_parameters_error(); | 1022 classifier()->async_arrow_formal_parameters_error(); |
| 1027 ReportClassifierError(error); | 1023 ReportClassifierError(error); |
| 1028 *ok = false; | 1024 *ok = false; |
| 1029 } | 1025 } |
| 1030 } | 1026 } |
| 1031 | 1027 |
| 1032 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 1028 void ValidateLetPattern(bool* ok) { |
| 1033 if (!classifier->is_valid_let_pattern()) { | 1029 if (!classifier()->is_valid_let_pattern()) { |
| 1034 ReportClassifierError(classifier->let_pattern_error()); | 1030 ReportClassifierError(classifier()->let_pattern_error()); |
| 1035 *ok = false; | 1031 *ok = false; |
| 1036 } | 1032 } |
| 1037 } | 1033 } |
| 1038 | 1034 |
| 1039 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, | 1035 void CheckNoTailCallExpressions(bool* ok) { |
| 1040 bool* ok) { | |
| 1041 if (FLAG_harmony_explicit_tailcalls && | 1036 if (FLAG_harmony_explicit_tailcalls && |
| 1042 classifier->has_tail_call_expression()) { | 1037 classifier()->has_tail_call_expression()) { |
| 1043 ReportClassifierError(classifier->tail_call_expression_error()); | 1038 ReportClassifierError(classifier()->tail_call_expression_error()); |
| 1044 *ok = false; | 1039 *ok = false; |
| 1045 } | 1040 } |
| 1046 } | 1041 } |
| 1047 | 1042 |
| 1048 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 1043 void ExpressionUnexpectedToken() { |
| 1049 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1044 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| 1050 const char* arg; | 1045 const char* arg; |
| 1051 Scanner::Location location = scanner()->peek_location(); | 1046 Scanner::Location location = scanner()->peek_location(); |
| 1052 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1047 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
| 1053 classifier->RecordExpressionError(location, message, arg); | 1048 classifier()->RecordExpressionError(location, message, arg); |
| 1054 } | 1049 } |
| 1055 | 1050 |
| 1056 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 1051 void BindingPatternUnexpectedToken() { |
| 1057 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1052 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| 1058 const char* arg; | 1053 const char* arg; |
| 1059 Scanner::Location location = scanner()->peek_location(); | 1054 Scanner::Location location = scanner()->peek_location(); |
| 1060 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1055 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
| 1061 classifier->RecordBindingPatternError(location, message, arg); | 1056 classifier()->RecordBindingPatternError(location, message, arg); |
| 1062 } | 1057 } |
| 1063 | 1058 |
| 1064 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { | 1059 void ArrowFormalParametersUnexpectedToken() { |
| 1065 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1060 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| 1066 const char* arg; | 1061 const char* arg; |
| 1067 Scanner::Location location = scanner()->peek_location(); | 1062 Scanner::Location location = scanner()->peek_location(); |
| 1068 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1063 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
| 1069 classifier->RecordArrowFormalParametersError(location, message, arg); | 1064 classifier()->RecordArrowFormalParametersError(location, message, arg); |
| 1070 } | 1065 } |
| 1071 | 1066 |
| 1072 // Recursive descent functions: | 1067 // Recursive descent functions: |
| 1073 | 1068 |
| 1074 // Parses an identifier that is valid for the current scope, in particular it | 1069 // Parses an identifier that is valid for the current scope, in particular it |
| 1075 // fails on strict mode future reserved keywords in a strict scope. If | 1070 // fails on strict mode future reserved keywords in a strict scope. If |
| 1076 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 1071 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 1077 // "arguments" as identifier even in strict mode (this is needed in cases like | 1072 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 1078 // "var foo = eval;"). | 1073 // "var foo = eval;"). |
| 1079 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 1074 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
| 1080 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1075 IdentifierT ParseAndClassifyIdentifier(bool* ok); |
| 1081 bool* ok); | |
| 1082 // Parses an identifier or a strict mode future reserved word, and indicate | 1076 // Parses an identifier or a strict mode future reserved word, and indicate |
| 1083 // whether it is strict mode future reserved. Allows passing in function_kind | 1077 // whether it is strict mode future reserved. Allows passing in function_kind |
| 1084 // for the case of parsing the identifier in a function expression, where the | 1078 // for the case of parsing the identifier in a function expression, where the |
| 1085 // relevant "function_kind" bit is of the function being parsed, not the | 1079 // relevant "function_kind" bit is of the function being parsed, not the |
| 1086 // containing function. | 1080 // containing function. |
| 1087 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind, | 1081 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind, |
| 1088 bool* is_strict_reserved, | 1082 bool* is_strict_reserved, |
| 1089 bool* ok); | 1083 bool* ok); |
| 1090 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 1084 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
| 1091 bool* ok) { | 1085 bool* ok) { |
| 1092 return ParseIdentifierOrStrictReservedWord(function_state_->kind(), | 1086 return ParseIdentifierOrStrictReservedWord(function_state_->kind(), |
| 1093 is_strict_reserved, ok); | 1087 is_strict_reserved, ok); |
| 1094 } | 1088 } |
| 1095 | 1089 |
| 1096 IdentifierT ParseIdentifierName(bool* ok); | 1090 IdentifierT ParseIdentifierName(bool* ok); |
| 1097 | 1091 |
| 1098 ExpressionT ParseRegExpLiteral(bool* ok); | 1092 ExpressionT ParseRegExpLiteral(bool* ok); |
| 1099 | 1093 |
| 1100 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 1094 ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok); |
| 1101 bool* is_async, bool* ok); | 1095 ExpressionT ParsePrimaryExpression(bool* ok) { |
| 1102 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
| 1103 bool* ok) { | |
| 1104 bool is_async; | 1096 bool is_async; |
| 1105 return ParsePrimaryExpression(classifier, &is_async, ok); | 1097 return ParsePrimaryExpression(&is_async, ok); |
| 1106 } | 1098 } |
| 1107 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 1099 |
| 1108 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 1100 // This method wraps the parsing of the expression inside a new expression |
| 1109 bool* ok); | 1101 // classifier and calls RewriteNonPattern if parsing is successful. |
| 1110 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 1102 // It should be used whenever we're parsing an expression that will be |
| 1103 // used as a non-pattern (i.e., in most cases). |
| 1104 V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 1105 |
| 1106 // This method does not wrap the parsing of the expression inside a |
| 1107 // new expression classifier; it uses the top-level classifier instead. |
| 1108 // It should be used whenever we're parsing something with the "cover" |
| 1109 // grammar that recognizes both patterns and non-patterns (which roughly |
| 1110 // corresponds to what's inside the parentheses generated by the symbol |
| 1111 // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017 |
| 1112 // specification). |
| 1113 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); |
| 1114 |
| 1115 ExpressionT ParseArrayLiteral(bool* ok); |
| 1111 | 1116 |
| 1112 enum class PropertyKind { | 1117 enum class PropertyKind { |
| 1113 kAccessorProperty, | 1118 kAccessorProperty, |
| 1114 kValueProperty, | 1119 kValueProperty, |
| 1115 kShorthandProperty, | 1120 kShorthandProperty, |
| 1116 kMethodProperty, | 1121 kMethodProperty, |
| 1117 kNotSet | 1122 kNotSet |
| 1118 }; | 1123 }; |
| 1119 | 1124 |
| 1120 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1125 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
| 1121 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1126 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
| 1122 bool in_class, bool* is_generator, bool* is_get, | 1127 bool in_class, bool* is_generator, bool* is_get, |
| 1123 bool* is_set, bool* is_async, bool* is_static, | 1128 bool* is_set, bool* is_async, bool* is_static, |
| 1124 bool* is_computed_name, | 1129 bool* is_computed_name, bool* ok); |
| 1125 ExpressionClassifier* classifier, bool* ok); | 1130 |
| 1126 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 1131 ExpressionT ParseObjectLiteral(bool* ok); |
| 1127 ObjectLiteralPropertyT ParsePropertyDefinition( | 1132 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 1128 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1133 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 1129 bool* is_computed_name, bool* has_seen_constructor, | 1134 bool* is_computed_name, bool* has_seen_constructor, IdentifierT* name, |
| 1130 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 1135 bool* ok); |
| 1131 typename Types::ExpressionList ParseArguments( | 1136 typename Types::ExpressionList ParseArguments( |
| 1132 Scanner::Location* first_spread_pos, bool maybe_arrow, | 1137 Scanner::Location* first_spread_pos, bool maybe_arrow, bool* ok); |
| 1133 ExpressionClassifier* classifier, bool* ok); | |
| 1134 typename Types::ExpressionList ParseArguments( | 1138 typename Types::ExpressionList ParseArguments( |
| 1135 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1139 Scanner::Location* first_spread_pos, bool* ok) { |
| 1136 bool* ok) { | 1140 return ParseArguments(first_spread_pos, false, ok); |
| 1137 return ParseArguments(first_spread_pos, false, classifier, ok); | |
| 1138 } | 1141 } |
| 1139 | 1142 |
| 1140 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1143 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 1141 ExpressionClassifier* classifier, | 1144 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
| 1142 bool* ok); | 1145 ExpressionT ParseTailCallExpression(bool* ok); |
| 1143 ExpressionT ParseYieldExpression(bool accept_IN, | 1146 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 1144 ExpressionClassifier* classifier, bool* ok); | 1147 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 1145 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 1148 ExpressionT ParseUnaryExpression(bool* ok); |
| 1146 bool* ok); | 1149 ExpressionT ParsePostfixExpression(bool* ok); |
| 1147 ExpressionT ParseConditionalExpression(bool accept_IN, | 1150 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 1148 ExpressionClassifier* classifier, | 1151 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); |
| 1149 bool* ok); | 1152 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); |
| 1150 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1153 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 1151 ExpressionClassifier* classifier, bool* ok); | 1154 bool* is_async, bool* ok); |
| 1152 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | |
| 1153 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | |
| 1154 bool* ok); | |
| 1155 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | |
| 1156 bool* ok); | |
| 1157 ExpressionT ParseMemberWithNewPrefixesExpression( | |
| 1158 ExpressionClassifier* classifier, bool* is_async, bool* ok); | |
| 1159 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, | |
| 1160 bool* is_async, bool* ok); | |
| 1161 ExpressionT ParseMemberExpressionContinuation( | |
| 1162 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | |
| 1163 bool* ok); | |
| 1164 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1155 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
| 1165 const FormalParametersT& parameters, | 1156 const FormalParametersT& parameters, |
| 1166 bool is_async, | 1157 bool is_async, |
| 1167 const ExpressionClassifier& classifier, | |
| 1168 bool* ok); | 1158 bool* ok); |
| 1169 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 1159 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 1170 ExpressionClassifier* classifier, bool* ok); | |
| 1171 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1160 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 1172 ExpressionT ParseNewTargetExpression(bool* ok); | 1161 ExpressionT ParseNewTargetExpression(bool* ok); |
| 1173 | 1162 |
| 1174 void ParseFormalParameter(FormalParametersT* parameters, | 1163 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); |
| 1175 ExpressionClassifier* classifier, bool* ok); | 1164 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); |
| 1176 void ParseFormalParameterList(FormalParametersT* parameters, | |
| 1177 ExpressionClassifier* classifier, bool* ok); | |
| 1178 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1165 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
| 1179 bool has_rest, int formals_start_pos, | 1166 bool has_rest, int formals_start_pos, |
| 1180 int formals_end_pos, bool* ok); | 1167 int formals_end_pos, bool* ok); |
| 1181 | 1168 |
| 1182 bool IsNextLetKeyword(); | 1169 bool IsNextLetKeyword(); |
| 1183 bool IsTrivialExpression(); | 1170 bool IsTrivialExpression(); |
| 1184 | 1171 |
| 1185 // Checks if the expression is a valid reference expression (e.g., on the | 1172 // Checks if the expression is a valid reference expression (e.g., on the |
| 1186 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1173 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 1187 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1174 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 return Call::IS_POSSIBLY_EVAL; | 1210 return Call::IS_POSSIBLY_EVAL; |
| 1224 } | 1211 } |
| 1225 return Call::NOT_EVAL; | 1212 return Call::NOT_EVAL; |
| 1226 } | 1213 } |
| 1227 | 1214 |
| 1228 class ObjectLiteralCheckerBase { | 1215 class ObjectLiteralCheckerBase { |
| 1229 public: | 1216 public: |
| 1230 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} | 1217 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} |
| 1231 | 1218 |
| 1232 virtual void CheckProperty(Token::Value property, PropertyKind type, | 1219 virtual void CheckProperty(Token::Value property, PropertyKind type, |
| 1233 MethodKind method_type, | 1220 MethodKind method_type, bool* ok) = 0; |
| 1234 ExpressionClassifier* classifier, bool* ok) = 0; | |
| 1235 | 1221 |
| 1236 virtual ~ObjectLiteralCheckerBase() {} | 1222 virtual ~ObjectLiteralCheckerBase() {} |
| 1237 | 1223 |
| 1238 protected: | 1224 protected: |
| 1239 ParserBase* parser() const { return parser_; } | 1225 ParserBase* parser() const { return parser_; } |
| 1240 Scanner* scanner() const { return parser_->scanner(); } | 1226 Scanner* scanner() const { return parser_->scanner(); } |
| 1241 | 1227 |
| 1242 private: | 1228 private: |
| 1243 ParserBase* parser_; | 1229 ParserBase* parser_; |
| 1244 }; | 1230 }; |
| 1245 | 1231 |
| 1246 // Validation per ES6 object literals. | 1232 // Validation per ES6 object literals. |
| 1247 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { | 1233 class ObjectLiteralChecker : public ObjectLiteralCheckerBase { |
| 1248 public: | 1234 public: |
| 1249 explicit ObjectLiteralChecker(ParserBase* parser) | 1235 explicit ObjectLiteralChecker(ParserBase* parser) |
| 1250 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} | 1236 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {} |
| 1251 | 1237 |
| 1252 void CheckProperty(Token::Value property, PropertyKind type, | 1238 void CheckProperty(Token::Value property, PropertyKind type, |
| 1253 MethodKind method_type, ExpressionClassifier* classifier, | 1239 MethodKind method_type, bool* ok) override; |
| 1254 bool* ok) override; | |
| 1255 | 1240 |
| 1256 private: | 1241 private: |
| 1257 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } | 1242 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } |
| 1258 | 1243 |
| 1259 bool has_seen_proto_; | 1244 bool has_seen_proto_; |
| 1260 }; | 1245 }; |
| 1261 | 1246 |
| 1262 // Validation per ES6 class literals. | 1247 // Validation per ES6 class literals. |
| 1263 class ClassLiteralChecker : public ObjectLiteralCheckerBase { | 1248 class ClassLiteralChecker : public ObjectLiteralCheckerBase { |
| 1264 public: | 1249 public: |
| 1265 explicit ClassLiteralChecker(ParserBase* parser) | 1250 explicit ClassLiteralChecker(ParserBase* parser) |
| 1266 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} | 1251 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {} |
| 1267 | 1252 |
| 1268 void CheckProperty(Token::Value property, PropertyKind type, | 1253 void CheckProperty(Token::Value property, PropertyKind type, |
| 1269 MethodKind method_type, ExpressionClassifier* classifier, | 1254 MethodKind method_type, bool* ok) override; |
| 1270 bool* ok) override; | |
| 1271 | 1255 |
| 1272 private: | 1256 private: |
| 1273 bool IsConstructor() { | 1257 bool IsConstructor() { |
| 1274 return this->scanner()->LiteralMatches("constructor", 11); | 1258 return this->scanner()->LiteralMatches("constructor", 11); |
| 1275 } | 1259 } |
| 1276 bool IsPrototype() { | 1260 bool IsPrototype() { |
| 1277 return this->scanner()->LiteralMatches("prototype", 9); | 1261 return this->scanner()->LiteralMatches("prototype", 9); |
| 1278 } | 1262 } |
| 1279 | 1263 |
| 1280 bool has_seen_constructor_; | 1264 bool has_seen_constructor_; |
| 1281 }; | 1265 }; |
| 1282 | 1266 |
| 1283 ModuleDescriptor* module() const { | 1267 ModuleDescriptor* module() const { |
| 1284 return scope()->AsModuleScope()->module(); | 1268 return scope()->AsModuleScope()->module(); |
| 1285 } | 1269 } |
| 1286 Scope* scope() const { return scope_state_->scope(); } | 1270 Scope* scope() const { return scope_state_->scope(); } |
| 1287 | 1271 |
| 1272 // Stack of expression classifiers. |
| 1273 // The top of the stack is always pointed to by classifier(). |
| 1274 V8_INLINE ExpressionClassifier* classifier() const { |
| 1275 DCHECK_NOT_NULL(classifier_); |
| 1276 return classifier_; |
| 1277 } |
| 1278 |
| 1279 // Accumulates the classifier that is on top of the stack (inner) to |
| 1280 // the one that is right below (outer) and pops the inner. |
| 1281 V8_INLINE void Accumulate(unsigned productions, |
| 1282 bool merge_non_patterns = true) { |
| 1283 DCHECK_NOT_NULL(classifier_); |
| 1284 ExpressionClassifier* previous = classifier_->previous(); |
| 1285 DCHECK_NOT_NULL(previous); |
| 1286 previous->Accumulate(classifier_, productions, merge_non_patterns); |
| 1287 classifier_ = previous; |
| 1288 } |
| 1289 |
| 1290 // Pops and discards the classifier that is on top of the stack |
| 1291 // without accumulating. |
| 1292 V8_INLINE void Discard() { |
| 1293 DCHECK_NOT_NULL(classifier_); |
| 1294 classifier_->Discard(); |
| 1295 classifier_ = classifier_->previous(); |
| 1296 } |
| 1297 |
| 1298 // Accumulate errors that can be arbitrarily deep in an expression. |
| 1299 // These correspond to the ECMAScript spec's 'Contains' operation |
| 1300 // on productions. This includes: |
| 1301 // |
| 1302 // - YieldExpression is disallowed in arrow parameters in a generator. |
| 1303 // - AwaitExpression is disallowed in arrow parameters in an async function. |
| 1304 // - AwaitExpression is disallowed in async arrow parameters. |
| 1305 // |
| 1306 V8_INLINE void AccumulateFormalParameterContainmentErrors() { |
| 1307 Accumulate(ExpressionClassifier::FormalParameterInitializerProduction | |
| 1308 ExpressionClassifier::AsyncArrowFormalParametersProduction); |
| 1309 } |
| 1310 |
| 1311 // Parser base's protected field members. |
| 1312 |
| 1288 ScopeState* scope_state_; // Scope stack. | 1313 ScopeState* scope_state_; // Scope stack. |
| 1289 FunctionState* function_state_; // Function state stack. | 1314 FunctionState* function_state_; // Function state stack. |
| 1290 v8::Extension* extension_; | 1315 v8::Extension* extension_; |
| 1291 FuncNameInferrer* fni_; | 1316 FuncNameInferrer* fni_; |
| 1292 AstValueFactory* ast_value_factory_; // Not owned. | 1317 AstValueFactory* ast_value_factory_; // Not owned. |
| 1293 typename Types::Factory ast_node_factory_; | 1318 typename Types::Factory ast_node_factory_; |
| 1294 ParserRecorder* log_; | 1319 ParserRecorder* log_; |
| 1295 Mode mode_; | 1320 Mode mode_; |
| 1296 bool parsing_module_; | 1321 bool parsing_module_; |
| 1297 uintptr_t stack_limit_; | 1322 uintptr_t stack_limit_; |
| 1298 | 1323 |
| 1324 // Parser base's private field members. |
| 1325 |
| 1299 private: | 1326 private: |
| 1300 Zone* zone_; | 1327 Zone* zone_; |
| 1328 ExpressionClassifier* classifier_; |
| 1301 | 1329 |
| 1302 Scanner* scanner_; | 1330 Scanner* scanner_; |
| 1303 bool stack_overflow_; | 1331 bool stack_overflow_; |
| 1304 | 1332 |
| 1305 bool allow_lazy_; | 1333 bool allow_lazy_; |
| 1306 bool allow_natives_; | 1334 bool allow_natives_; |
| 1307 bool allow_tailcalls_; | 1335 bool allow_tailcalls_; |
| 1308 bool allow_harmony_restrictive_declarations_; | 1336 bool allow_harmony_restrictive_declarations_; |
| 1309 bool allow_harmony_do_expressions_; | 1337 bool allow_harmony_do_expressions_; |
| 1310 bool allow_harmony_for_in_; | 1338 bool allow_harmony_for_in_; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 MessageTemplate::Template message) { | 1445 MessageTemplate::Template message) { |
| 1418 const char* arg; | 1446 const char* arg; |
| 1419 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); | 1447 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); |
| 1420 impl()->ReportMessageAt(source_location, message, arg); | 1448 impl()->ReportMessageAt(source_location, message, arg); |
| 1421 } | 1449 } |
| 1422 | 1450 |
| 1423 template <typename Impl> | 1451 template <typename Impl> |
| 1424 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( | 1452 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( |
| 1425 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 1453 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
| 1426 ExpressionClassifier classifier(this); | 1454 ExpressionClassifier classifier(this); |
| 1427 auto result = | 1455 auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(EmptyIdentifier)); |
| 1428 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | |
| 1429 | 1456 |
| 1430 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { | 1457 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
| 1431 ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1458 ValidateAssignmentPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); |
| 1432 ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1459 ValidateBindingPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); |
| 1433 } | 1460 } |
| 1434 | 1461 |
| 1435 return result; | 1462 return result; |
| 1436 } | 1463 } |
| 1437 | 1464 |
| 1438 template <typename Impl> | 1465 template <typename Impl> |
| 1439 typename ParserBase<Impl>::IdentifierT | 1466 typename ParserBase<Impl>::IdentifierT |
| 1440 ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1467 ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) { |
| 1441 bool* ok) { | |
| 1442 Token::Value next = Next(); | 1468 Token::Value next = Next(); |
| 1443 if (next == Token::IDENTIFIER || next == Token::ASYNC || | 1469 if (next == Token::IDENTIFIER || next == Token::ASYNC || |
| 1444 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { | 1470 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { |
| 1445 IdentifierT name = impl()->GetSymbol(); | 1471 IdentifierT name = impl()->GetSymbol(); |
| 1446 // When this function is used to read a formal parameter, we don't always | 1472 // When this function is used to read a formal parameter, we don't always |
| 1447 // know whether the function is going to be strict or sloppy. Indeed for | 1473 // know whether the function is going to be strict or sloppy. Indeed for |
| 1448 // arrow functions we don't always know that the identifier we are reading | 1474 // arrow functions we don't always know that the identifier we are reading |
| 1449 // is actually a formal parameter. Therefore besides the errors that we | 1475 // is actually a formal parameter. Therefore besides the errors that we |
| 1450 // must detect because we know we're in strict mode, we also record any | 1476 // must detect because we know we're in strict mode, we also record any |
| 1451 // error that we might make in the future once we know the language mode. | 1477 // error that we might make in the future once we know the language mode. |
| 1452 if (impl()->IsEvalOrArguments(name)) { | 1478 if (impl()->IsEvalOrArguments(name)) { |
| 1453 classifier->RecordStrictModeFormalParameterError( | 1479 classifier()->RecordStrictModeFormalParameterError( |
| 1454 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1480 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1455 if (is_strict(language_mode())) { | 1481 if (is_strict(language_mode())) { |
| 1456 classifier->RecordBindingPatternError( | 1482 classifier()->RecordBindingPatternError( |
| 1457 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1483 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1458 } | 1484 } |
| 1459 } else if (next == Token::AWAIT) { | 1485 } else if (next == Token::AWAIT) { |
| 1460 classifier->RecordAsyncArrowFormalParametersError( | 1486 classifier()->RecordAsyncArrowFormalParametersError( |
| 1461 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); | 1487 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); |
| 1462 } | 1488 } |
| 1463 | 1489 |
| 1464 if (classifier->duplicate_finder() != nullptr && | 1490 if (classifier()->duplicate_finder() != nullptr && |
| 1465 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1491 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { |
| 1466 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1492 classifier()->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1467 } | 1493 } |
| 1468 return name; | 1494 return name; |
| 1469 } else if (is_sloppy(language_mode()) && | 1495 } else if (is_sloppy(language_mode()) && |
| 1470 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1496 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1471 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1497 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
| 1472 next == Token::LET || next == Token::STATIC || | 1498 next == Token::LET || next == Token::STATIC || |
| 1473 (next == Token::YIELD && !is_generator()))) { | 1499 (next == Token::YIELD && !is_generator()))) { |
| 1474 classifier->RecordStrictModeFormalParameterError( | 1500 classifier()->RecordStrictModeFormalParameterError( |
| 1475 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); | 1501 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
| 1476 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1502 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1477 is_strict(language_mode())) { | 1503 is_strict(language_mode())) { |
| 1478 ReportUnexpectedToken(next); | 1504 ReportUnexpectedToken(next); |
| 1479 *ok = false; | 1505 *ok = false; |
| 1480 return impl()->EmptyIdentifier(); | 1506 return impl()->EmptyIdentifier(); |
| 1481 } | 1507 } |
| 1482 if (next == Token::LET || | 1508 if (next == Token::LET || |
| 1483 (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1509 (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1484 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { | 1510 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { |
| 1485 classifier->RecordLetPatternError(scanner()->location(), | 1511 classifier()->RecordLetPatternError( |
| 1486 MessageTemplate::kLetInLexicalBinding); | 1512 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 1487 } | 1513 } |
| 1488 return impl()->GetSymbol(); | 1514 return impl()->GetSymbol(); |
| 1489 } else { | 1515 } else { |
| 1490 ReportUnexpectedToken(next); | 1516 ReportUnexpectedToken(next); |
| 1491 *ok = false; | 1517 *ok = false; |
| 1492 return impl()->EmptyIdentifier(); | 1518 return impl()->EmptyIdentifier(); |
| 1493 } | 1519 } |
| 1494 } | 1520 } |
| 1495 | 1521 |
| 1496 template <class Impl> | 1522 template <class Impl> |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1554 *ok = false; | 1580 *ok = false; |
| 1555 return impl()->EmptyExpression(); | 1581 return impl()->EmptyExpression(); |
| 1556 } | 1582 } |
| 1557 int js_flags = flags.FromJust(); | 1583 int js_flags = flags.FromJust(); |
| 1558 Next(); | 1584 Next(); |
| 1559 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1585 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 1560 } | 1586 } |
| 1561 | 1587 |
| 1562 template <typename Impl> | 1588 template <typename Impl> |
| 1563 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( | 1589 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( |
| 1564 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 1590 bool* is_async, bool* ok) { |
| 1565 // PrimaryExpression :: | 1591 // PrimaryExpression :: |
| 1566 // 'this' | 1592 // 'this' |
| 1567 // 'null' | 1593 // 'null' |
| 1568 // 'true' | 1594 // 'true' |
| 1569 // 'false' | 1595 // 'false' |
| 1570 // Identifier | 1596 // Identifier |
| 1571 // Number | 1597 // Number |
| 1572 // String | 1598 // String |
| 1573 // ArrayLiteral | 1599 // ArrayLiteral |
| 1574 // ObjectLiteral | 1600 // ObjectLiteral |
| 1575 // RegExpLiteral | 1601 // RegExpLiteral |
| 1576 // ClassLiteral | 1602 // ClassLiteral |
| 1577 // '(' Expression ')' | 1603 // '(' Expression ')' |
| 1578 // TemplateLiteral | 1604 // TemplateLiteral |
| 1579 // do Block | 1605 // do Block |
| 1580 // AsyncFunctionExpression | 1606 // AsyncFunctionExpression |
| 1581 | 1607 |
| 1582 int beg_pos = peek_position(); | 1608 int beg_pos = peek_position(); |
| 1583 switch (peek()) { | 1609 switch (peek()) { |
| 1584 case Token::THIS: { | 1610 case Token::THIS: { |
| 1585 BindingPatternUnexpectedToken(classifier); | 1611 BindingPatternUnexpectedToken(); |
| 1586 Consume(Token::THIS); | 1612 Consume(Token::THIS); |
| 1587 return impl()->ThisExpression(beg_pos); | 1613 return impl()->ThisExpression(beg_pos); |
| 1588 } | 1614 } |
| 1589 | 1615 |
| 1590 case Token::NULL_LITERAL: | 1616 case Token::NULL_LITERAL: |
| 1591 case Token::TRUE_LITERAL: | 1617 case Token::TRUE_LITERAL: |
| 1592 case Token::FALSE_LITERAL: | 1618 case Token::FALSE_LITERAL: |
| 1593 case Token::SMI: | 1619 case Token::SMI: |
| 1594 case Token::NUMBER: | 1620 case Token::NUMBER: |
| 1595 BindingPatternUnexpectedToken(classifier); | 1621 BindingPatternUnexpectedToken(); |
| 1596 return impl()->ExpressionFromLiteral(Next(), beg_pos); | 1622 return impl()->ExpressionFromLiteral(Next(), beg_pos); |
| 1597 | 1623 |
| 1598 case Token::ASYNC: | 1624 case Token::ASYNC: |
| 1599 if (allow_harmony_async_await() && | 1625 if (allow_harmony_async_await() && |
| 1600 !scanner()->HasAnyLineTerminatorAfterNext() && | 1626 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 1601 PeekAhead() == Token::FUNCTION) { | 1627 PeekAhead() == Token::FUNCTION) { |
| 1602 Consume(Token::ASYNC); | 1628 Consume(Token::ASYNC); |
| 1603 return impl()->ParseAsyncFunctionExpression(CHECK_OK); | 1629 return impl()->ParseAsyncFunctionExpression(CHECK_OK); |
| 1604 } | 1630 } |
| 1605 // CoverCallExpressionAndAsyncArrowHead | 1631 // CoverCallExpressionAndAsyncArrowHead |
| 1606 *is_async = true; | 1632 *is_async = true; |
| 1607 /* falls through */ | 1633 /* falls through */ |
| 1608 case Token::IDENTIFIER: | 1634 case Token::IDENTIFIER: |
| 1609 case Token::LET: | 1635 case Token::LET: |
| 1610 case Token::STATIC: | 1636 case Token::STATIC: |
| 1611 case Token::YIELD: | 1637 case Token::YIELD: |
| 1612 case Token::AWAIT: | 1638 case Token::AWAIT: |
| 1613 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1639 case Token::ESCAPED_STRICT_RESERVED_WORD: |
| 1614 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1640 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1615 // Using eval or arguments in this context is OK even in strict mode. | 1641 // Using eval or arguments in this context is OK even in strict mode. |
| 1616 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1642 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); |
| 1617 return impl()->ExpressionFromIdentifier(name, beg_pos, | 1643 return impl()->ExpressionFromIdentifier(name, beg_pos, |
| 1618 scanner()->location().end_pos); | 1644 scanner()->location().end_pos); |
| 1619 } | 1645 } |
| 1620 | 1646 |
| 1621 case Token::STRING: { | 1647 case Token::STRING: { |
| 1622 BindingPatternUnexpectedToken(classifier); | 1648 BindingPatternUnexpectedToken(); |
| 1623 Consume(Token::STRING); | 1649 Consume(Token::STRING); |
| 1624 return impl()->ExpressionFromString(beg_pos); | 1650 return impl()->ExpressionFromString(beg_pos); |
| 1625 } | 1651 } |
| 1626 | 1652 |
| 1627 case Token::ASSIGN_DIV: | 1653 case Token::ASSIGN_DIV: |
| 1628 case Token::DIV: | 1654 case Token::DIV: |
| 1629 classifier->RecordBindingPatternError( | 1655 classifier()->RecordBindingPatternError( |
| 1630 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); | 1656 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); |
| 1631 return ParseRegExpLiteral(ok); | 1657 return ParseRegExpLiteral(ok); |
| 1632 | 1658 |
| 1633 case Token::LBRACK: | 1659 case Token::LBRACK: |
| 1634 return ParseArrayLiteral(classifier, ok); | 1660 return ParseArrayLiteral(ok); |
| 1635 | 1661 |
| 1636 case Token::LBRACE: | 1662 case Token::LBRACE: |
| 1637 return ParseObjectLiteral(classifier, ok); | 1663 return ParseObjectLiteral(ok); |
| 1638 | 1664 |
| 1639 case Token::LPAREN: { | 1665 case Token::LPAREN: { |
| 1640 // Arrow function formal parameters are either a single identifier or a | 1666 // Arrow function formal parameters are either a single identifier or a |
| 1641 // list of BindingPattern productions enclosed in parentheses. | 1667 // list of BindingPattern productions enclosed in parentheses. |
| 1642 // Parentheses are not valid on the LHS of a BindingPattern, so we use the | 1668 // Parentheses are not valid on the LHS of a BindingPattern, so we use the |
| 1643 // is_valid_binding_pattern() check to detect multiple levels of | 1669 // is_valid_binding_pattern() check to detect multiple levels of |
| 1644 // parenthesization. | 1670 // parenthesization. |
| 1645 bool pattern_error = !classifier->is_valid_binding_pattern(); | 1671 bool pattern_error = !classifier()->is_valid_binding_pattern(); |
| 1646 classifier->RecordPatternError(scanner()->peek_location(), | 1672 classifier()->RecordPatternError(scanner()->peek_location(), |
| 1647 MessageTemplate::kUnexpectedToken, | 1673 MessageTemplate::kUnexpectedToken, |
| 1648 Token::String(Token::LPAREN)); | 1674 Token::String(Token::LPAREN)); |
| 1649 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); | 1675 if (pattern_error) ArrowFormalParametersUnexpectedToken(); |
| 1650 Consume(Token::LPAREN); | 1676 Consume(Token::LPAREN); |
| 1651 if (Check(Token::RPAREN)) { | 1677 if (Check(Token::RPAREN)) { |
| 1652 // ()=>x. The continuation that looks for the => is in | 1678 // ()=>x. The continuation that looks for the => is in |
| 1653 // ParseAssignmentExpression. | 1679 // ParseAssignmentExpression. |
| 1654 classifier->RecordExpressionError(scanner()->location(), | 1680 classifier()->RecordExpressionError(scanner()->location(), |
| 1655 MessageTemplate::kUnexpectedToken, | 1681 MessageTemplate::kUnexpectedToken, |
| 1656 Token::String(Token::RPAREN)); | 1682 Token::String(Token::RPAREN)); |
| 1657 return factory()->NewEmptyParentheses(beg_pos); | 1683 return factory()->NewEmptyParentheses(beg_pos); |
| 1658 } | 1684 } |
| 1659 // Heuristically try to detect immediately called functions before | 1685 // Heuristically try to detect immediately called functions before |
| 1660 // seeing the call parentheses. | 1686 // seeing the call parentheses. |
| 1661 function_state_->set_next_function_is_parenthesized(peek() == | 1687 function_state_->set_next_function_is_parenthesized(peek() == |
| 1662 Token::FUNCTION); | 1688 Token::FUNCTION); |
| 1663 ExpressionT expr = ParseExpression(true, classifier, CHECK_OK); | 1689 ExpressionT expr = ParseExpressionCoverGrammar(true, CHECK_OK); |
| 1664 Expect(Token::RPAREN, CHECK_OK); | 1690 Expect(Token::RPAREN, CHECK_OK); |
| 1665 return expr; | 1691 return expr; |
| 1666 } | 1692 } |
| 1667 | 1693 |
| 1668 case Token::CLASS: { | 1694 case Token::CLASS: { |
| 1669 BindingPatternUnexpectedToken(classifier); | 1695 BindingPatternUnexpectedToken(); |
| 1670 Consume(Token::CLASS); | 1696 Consume(Token::CLASS); |
| 1671 int class_token_position = position(); | 1697 int class_token_position = position(); |
| 1672 IdentifierT name = impl()->EmptyIdentifier(); | 1698 IdentifierT name = impl()->EmptyIdentifier(); |
| 1673 bool is_strict_reserved_name = false; | 1699 bool is_strict_reserved_name = false; |
| 1674 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1700 Scanner::Location class_name_location = Scanner::Location::invalid(); |
| 1675 if (peek_any_identifier()) { | 1701 if (peek_any_identifier()) { |
| 1676 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1702 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 1677 CHECK_OK); | 1703 CHECK_OK); |
| 1678 class_name_location = scanner()->location(); | 1704 class_name_location = scanner()->location(); |
| 1679 } | 1705 } |
| 1680 return impl()->ParseClassLiteral(classifier, name, class_name_location, | 1706 return impl()->ParseClassLiteral(name, class_name_location, |
| 1681 is_strict_reserved_name, | 1707 is_strict_reserved_name, |
| 1682 class_token_position, ok); | 1708 class_token_position, ok); |
| 1683 } | 1709 } |
| 1684 | 1710 |
| 1685 case Token::TEMPLATE_SPAN: | 1711 case Token::TEMPLATE_SPAN: |
| 1686 case Token::TEMPLATE_TAIL: | 1712 case Token::TEMPLATE_TAIL: |
| 1687 BindingPatternUnexpectedToken(classifier); | 1713 BindingPatternUnexpectedToken(); |
| 1688 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, classifier, | 1714 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok); |
| 1689 ok); | |
| 1690 | 1715 |
| 1691 case Token::MOD: | 1716 case Token::MOD: |
| 1692 if (allow_natives() || extension_ != NULL) { | 1717 if (allow_natives() || extension_ != NULL) { |
| 1693 BindingPatternUnexpectedToken(classifier); | 1718 BindingPatternUnexpectedToken(); |
| 1694 return impl()->ParseV8Intrinsic(ok); | 1719 return impl()->ParseV8Intrinsic(ok); |
| 1695 } | 1720 } |
| 1696 break; | 1721 break; |
| 1697 | 1722 |
| 1698 case Token::DO: | 1723 case Token::DO: |
| 1699 if (allow_harmony_do_expressions()) { | 1724 if (allow_harmony_do_expressions()) { |
| 1700 BindingPatternUnexpectedToken(classifier); | 1725 BindingPatternUnexpectedToken(); |
| 1701 return impl()->ParseDoExpression(ok); | 1726 return impl()->ParseDoExpression(ok); |
| 1702 } | 1727 } |
| 1703 break; | 1728 break; |
| 1704 | 1729 |
| 1705 default: | 1730 default: |
| 1706 break; | 1731 break; |
| 1707 } | 1732 } |
| 1708 | 1733 |
| 1709 ReportUnexpectedToken(Next()); | 1734 ReportUnexpectedToken(Next()); |
| 1710 *ok = false; | 1735 *ok = false; |
| 1711 return impl()->EmptyExpression(); | 1736 return impl()->EmptyExpression(); |
| 1712 } | 1737 } |
| 1713 | 1738 |
| 1714 template <typename Impl> | 1739 template <typename Impl> |
| 1715 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1740 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
| 1716 bool accept_IN, bool* ok) { | 1741 bool accept_IN, bool* ok) { |
| 1717 ExpressionClassifier classifier(this); | 1742 ExpressionClassifier classifier(this); |
| 1718 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1743 ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK); |
| 1719 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 1744 impl()->RewriteNonPattern(CHECK_OK); |
| 1720 return result; | 1745 return result; |
| 1721 } | 1746 } |
| 1722 | 1747 |
| 1723 template <typename Impl> | 1748 template <typename Impl> |
| 1724 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1749 typename ParserBase<Impl>::ExpressionT |
| 1725 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1750 ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) { |
| 1726 // Expression :: | 1751 // Expression :: |
| 1727 // AssignmentExpression | 1752 // AssignmentExpression |
| 1728 // Expression ',' AssignmentExpression | 1753 // Expression ',' AssignmentExpression |
| 1729 | 1754 |
| 1730 ExpressionT result = impl()->EmptyExpression(); | 1755 ExpressionT result = impl()->EmptyExpression(); |
| 1731 while (true) { | 1756 while (true) { |
| 1732 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1757 CheckNoTailCallExpressions(CHECK_OK); |
| 1733 int comma_pos = position(); | 1758 int comma_pos = position(); |
| 1734 ExpressionClassifier binding_classifier(this); | 1759 ExpressionClassifier binding_classifier(this); |
| 1735 ExpressionT right; | 1760 ExpressionT right; |
| 1736 if (Check(Token::ELLIPSIS)) { | 1761 if (Check(Token::ELLIPSIS)) { |
| 1737 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1762 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
| 1738 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1763 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
| 1739 // valid expression. | 1764 // valid expression. |
| 1740 binding_classifier.RecordExpressionError( | 1765 classifier()->RecordExpressionError(scanner()->location(), |
| 1741 scanner()->location(), MessageTemplate::kUnexpectedToken, | 1766 MessageTemplate::kUnexpectedToken, |
| 1742 Token::String(Token::ELLIPSIS)); | 1767 Token::String(Token::ELLIPSIS)); |
| 1743 int ellipsis_pos = position(); | 1768 int ellipsis_pos = position(); |
| 1744 int pattern_pos = peek_position(); | 1769 int pattern_pos = peek_position(); |
| 1745 ExpressionT pattern = | 1770 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK); |
| 1746 ParsePrimaryExpression(&binding_classifier, CHECK_OK); | 1771 ValidateBindingPattern(CHECK_OK); |
| 1747 ValidateBindingPattern(&binding_classifier, CHECK_OK); | |
| 1748 right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos); | 1772 right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos); |
| 1749 } else { | 1773 } else { |
| 1750 right = | 1774 right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 1751 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | |
| 1752 } | 1775 } |
| 1753 // No need to accumulate binding pattern-related errors, since | 1776 // No need to accumulate binding pattern-related errors, since |
| 1754 // an Expression can't be a binding pattern anyway. | 1777 // an Expression can't be a binding pattern anyway. |
| 1755 classifier->Accumulate( | 1778 impl()->Accumulate(ExpressionClassifier::AllProductions & |
| 1756 &binding_classifier, | 1779 ~(ExpressionClassifier::BindingPatternProduction | |
| 1757 ExpressionClassifier::AllProductions & | 1780 ExpressionClassifier::LetPatternProduction)); |
| 1758 ~(ExpressionClassifier::BindingPatternProduction | | 1781 if (!impl()->IsIdentifier(right)) classifier()->RecordNonSimpleParameter(); |
| 1759 ExpressionClassifier::LetPatternProduction)); | |
| 1760 if (!impl()->IsIdentifier(right)) classifier->RecordNonSimpleParameter(); | |
| 1761 if (impl()->IsEmptyExpression(result)) { | 1782 if (impl()->IsEmptyExpression(result)) { |
| 1762 // First time through the loop. | 1783 // First time through the loop. |
| 1763 result = right; | 1784 result = right; |
| 1764 } else { | 1785 } else { |
| 1765 result = | 1786 result = |
| 1766 factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos); | 1787 factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos); |
| 1767 } | 1788 } |
| 1768 | 1789 |
| 1769 if (!Check(Token::COMMA)) break; | 1790 if (!Check(Token::COMMA)) break; |
| 1770 | 1791 |
| 1771 if (right->IsSpread()) { | 1792 if (right->IsSpread()) { |
| 1772 classifier->RecordArrowFormalParametersError( | 1793 classifier()->RecordArrowFormalParametersError( |
| 1773 scanner()->location(), MessageTemplate::kParamAfterRest); | 1794 scanner()->location(), MessageTemplate::kParamAfterRest); |
| 1774 } | 1795 } |
| 1775 | 1796 |
| 1776 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && | 1797 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && |
| 1777 PeekAhead() == Token::ARROW) { | 1798 PeekAhead() == Token::ARROW) { |
| 1778 // a trailing comma is allowed at the end of an arrow parameter list | 1799 // a trailing comma is allowed at the end of an arrow parameter list |
| 1779 break; | 1800 break; |
| 1780 } | 1801 } |
| 1781 } | 1802 } |
| 1782 | 1803 |
| 1783 return result; | 1804 return result; |
| 1784 } | 1805 } |
| 1785 | 1806 |
| 1786 template <typename Impl> | 1807 template <typename Impl> |
| 1787 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( | 1808 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( |
| 1788 ExpressionClassifier* classifier, bool* ok) { | 1809 bool* ok) { |
| 1789 // ArrayLiteral :: | 1810 // ArrayLiteral :: |
| 1790 // '[' Expression? (',' Expression?)* ']' | 1811 // '[' Expression? (',' Expression?)* ']' |
| 1791 | 1812 |
| 1792 int pos = peek_position(); | 1813 int pos = peek_position(); |
| 1793 typename Types::ExpressionList values = impl()->NewExpressionList(4); | 1814 typename Types::ExpressionList values = impl()->NewExpressionList(4); |
| 1794 int first_spread_index = -1; | 1815 int first_spread_index = -1; |
| 1795 Expect(Token::LBRACK, CHECK_OK); | 1816 Expect(Token::LBRACK, CHECK_OK); |
| 1796 while (peek() != Token::RBRACK) { | 1817 while (peek() != Token::RBRACK) { |
| 1797 ExpressionT elem; | 1818 ExpressionT elem; |
| 1798 if (peek() == Token::COMMA) { | 1819 if (peek() == Token::COMMA) { |
| 1799 elem = impl()->GetLiteralTheHole(peek_position()); | 1820 elem = impl()->GetLiteralTheHole(peek_position()); |
| 1800 } else if (peek() == Token::ELLIPSIS) { | 1821 } else if (peek() == Token::ELLIPSIS) { |
| 1801 int start_pos = peek_position(); | 1822 int start_pos = peek_position(); |
| 1802 Consume(Token::ELLIPSIS); | 1823 Consume(Token::ELLIPSIS); |
| 1803 int expr_pos = peek_position(); | 1824 int expr_pos = peek_position(); |
| 1804 ExpressionT argument = | 1825 ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK); |
| 1805 ParseAssignmentExpression(true, classifier, CHECK_OK); | 1826 CheckNoTailCallExpressions(CHECK_OK); |
| 1806 CheckNoTailCallExpressions(classifier, CHECK_OK); | |
| 1807 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1827 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
| 1808 | 1828 |
| 1809 if (first_spread_index < 0) { | 1829 if (first_spread_index < 0) { |
| 1810 first_spread_index = values->length(); | 1830 first_spread_index = values->length(); |
| 1811 } | 1831 } |
| 1812 | 1832 |
| 1813 if (argument->IsAssignment()) { | 1833 if (argument->IsAssignment()) { |
| 1814 classifier->RecordPatternError( | 1834 classifier()->RecordPatternError( |
| 1815 Scanner::Location(start_pos, scanner()->location().end_pos), | 1835 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 1816 MessageTemplate::kInvalidDestructuringTarget); | 1836 MessageTemplate::kInvalidDestructuringTarget); |
| 1817 } else { | 1837 } else { |
| 1818 CheckDestructuringElement(argument, classifier, start_pos, | 1838 CheckDestructuringElement(argument, start_pos, |
| 1819 scanner()->location().end_pos); | 1839 scanner()->location().end_pos); |
| 1820 } | 1840 } |
| 1821 | 1841 |
| 1822 if (peek() == Token::COMMA) { | 1842 if (peek() == Token::COMMA) { |
| 1823 classifier->RecordPatternError( | 1843 classifier()->RecordPatternError( |
| 1824 Scanner::Location(start_pos, scanner()->location().end_pos), | 1844 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 1825 MessageTemplate::kElementAfterRest); | 1845 MessageTemplate::kElementAfterRest); |
| 1826 } | 1846 } |
| 1827 } else { | 1847 } else { |
| 1828 int beg_pos = peek_position(); | 1848 int beg_pos = peek_position(); |
| 1829 elem = ParseAssignmentExpression(true, classifier, CHECK_OK); | 1849 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 1830 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1850 CheckNoTailCallExpressions(CHECK_OK); |
| 1831 CheckDestructuringElement(elem, classifier, beg_pos, | 1851 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos); |
| 1832 scanner()->location().end_pos); | |
| 1833 } | 1852 } |
| 1834 values->Add(elem, zone_); | 1853 values->Add(elem, zone_); |
| 1835 if (peek() != Token::RBRACK) { | 1854 if (peek() != Token::RBRACK) { |
| 1836 Expect(Token::COMMA, CHECK_OK); | 1855 Expect(Token::COMMA, CHECK_OK); |
| 1837 } | 1856 } |
| 1838 } | 1857 } |
| 1839 Expect(Token::RBRACK, CHECK_OK); | 1858 Expect(Token::RBRACK, CHECK_OK); |
| 1840 | 1859 |
| 1841 // Update the scope information before the pre-parsing bailout. | 1860 // Update the scope information before the pre-parsing bailout. |
| 1842 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1861 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 default: | 1898 default: |
| 1880 break; | 1899 break; |
| 1881 } | 1900 } |
| 1882 return false; | 1901 return false; |
| 1883 } | 1902 } |
| 1884 | 1903 |
| 1885 template <class Impl> | 1904 template <class Impl> |
| 1886 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 1905 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
| 1887 IdentifierT* name, PropertyKind* kind, bool in_class, bool* is_generator, | 1906 IdentifierT* name, PropertyKind* kind, bool in_class, bool* is_generator, |
| 1888 bool* is_get, bool* is_set, bool* is_async, bool* is_static, | 1907 bool* is_get, bool* is_set, bool* is_async, bool* is_static, |
| 1889 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { | 1908 bool* is_computed_name, bool* ok) { |
| 1890 DCHECK(*kind == PropertyKind::kNotSet); | 1909 DCHECK(*kind == PropertyKind::kNotSet); |
| 1891 DCHECK(!*is_generator); | 1910 DCHECK(!*is_generator); |
| 1892 DCHECK(!*is_get); | 1911 DCHECK(!*is_get); |
| 1893 DCHECK(!*is_set); | 1912 DCHECK(!*is_set); |
| 1894 DCHECK(!*is_async); | 1913 DCHECK(!*is_async); |
| 1895 DCHECK(!*is_static); | 1914 DCHECK(!*is_static); |
| 1896 DCHECK(!*is_computed_name); | 1915 DCHECK(!*is_computed_name); |
| 1897 | 1916 |
| 1898 *is_generator = Check(Token::MUL); | 1917 *is_generator = Check(Token::MUL); |
| 1899 if (*is_generator) { | 1918 if (*is_generator) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 case Token::NUMBER: | 1999 case Token::NUMBER: |
| 1981 Consume(Token::NUMBER); | 2000 Consume(Token::NUMBER); |
| 1982 *name = impl()->GetNumberAsSymbol(); | 2001 *name = impl()->GetNumberAsSymbol(); |
| 1983 break; | 2002 break; |
| 1984 | 2003 |
| 1985 case Token::LBRACK: { | 2004 case Token::LBRACK: { |
| 1986 *name = impl()->EmptyIdentifier(); | 2005 *name = impl()->EmptyIdentifier(); |
| 1987 *is_computed_name = true; | 2006 *is_computed_name = true; |
| 1988 Consume(Token::LBRACK); | 2007 Consume(Token::LBRACK); |
| 1989 ExpressionClassifier computed_name_classifier(this); | 2008 ExpressionClassifier computed_name_classifier(this); |
| 1990 expression = | 2009 expression = ParseAssignmentExpression(true, CHECK_OK); |
| 1991 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 2010 impl()->RewriteNonPattern(CHECK_OK); |
| 1992 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 2011 impl()->AccumulateFormalParameterContainmentErrors(); |
| 1993 classifier->AccumulateFormalParameterContainmentErrors( | |
| 1994 &computed_name_classifier); | |
| 1995 Expect(Token::RBRACK, CHECK_OK); | 2012 Expect(Token::RBRACK, CHECK_OK); |
| 1996 break; | 2013 break; |
| 1997 } | 2014 } |
| 1998 | 2015 |
| 1999 default: | 2016 default: |
| 2000 *name = ParseIdentifierName(CHECK_OK); | 2017 *name = ParseIdentifierName(CHECK_OK); |
| 2001 break; | 2018 break; |
| 2002 } | 2019 } |
| 2003 | 2020 |
| 2004 if (*kind == PropertyKind::kNotSet) { | 2021 if (*kind == PropertyKind::kNotSet) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2027 ? factory()->NewNumberLiteral(index, pos) | 2044 ? factory()->NewNumberLiteral(index, pos) |
| 2028 : factory()->NewStringLiteral(*name, pos); | 2045 : factory()->NewStringLiteral(*name, pos); |
| 2029 } | 2046 } |
| 2030 | 2047 |
| 2031 template <typename Impl> | 2048 template <typename Impl> |
| 2032 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2049 typename ParserBase<Impl>::ObjectLiteralPropertyT |
| 2033 ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, | 2050 ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| 2034 bool in_class, bool has_extends, | 2051 bool in_class, bool has_extends, |
| 2035 bool* is_computed_name, | 2052 bool* is_computed_name, |
| 2036 bool* has_seen_constructor, | 2053 bool* has_seen_constructor, |
| 2037 ExpressionClassifier* classifier, | |
| 2038 IdentifierT* name, bool* ok) { | 2054 IdentifierT* name, bool* ok) { |
| 2039 DCHECK(!in_class || has_seen_constructor != nullptr); | 2055 DCHECK(!in_class || has_seen_constructor != nullptr); |
| 2040 bool is_get = false; | 2056 bool is_get = false; |
| 2041 bool is_set = false; | 2057 bool is_set = false; |
| 2042 bool is_generator = false; | 2058 bool is_generator = false; |
| 2043 bool is_async = false; | 2059 bool is_async = false; |
| 2044 bool is_static = false; | 2060 bool is_static = false; |
| 2045 PropertyKind kind = PropertyKind::kNotSet; | 2061 PropertyKind kind = PropertyKind::kNotSet; |
| 2046 | 2062 |
| 2047 Token::Value name_token = peek(); | 2063 Token::Value name_token = peek(); |
| 2048 int next_beg_pos = scanner()->peek_location().beg_pos; | 2064 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2049 int next_end_pos = scanner()->peek_location().end_pos; | 2065 int next_end_pos = scanner()->peek_location().end_pos; |
| 2050 | 2066 |
| 2051 ExpressionT name_expression = | 2067 ExpressionT name_expression = |
| 2052 ParsePropertyName(name, &kind, in_class, &is_generator, &is_get, &is_set, | 2068 ParsePropertyName(name, &kind, in_class, &is_generator, &is_get, &is_set, |
| 2053 &is_async, &is_static, is_computed_name, classifier, | 2069 &is_async, &is_static, is_computed_name, |
| 2054 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2070 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2055 | 2071 |
| 2056 switch (kind) { | 2072 switch (kind) { |
| 2057 case PropertyKind::kValueProperty: { | 2073 case PropertyKind::kValueProperty: { |
| 2058 if (in_class) { | 2074 if (in_class) { |
| 2059 Token::Value next = Next(); | 2075 Token::Value next = Next(); |
| 2060 ReportUnexpectedToken(next); | 2076 ReportUnexpectedToken(next); |
| 2061 *ok = false; | 2077 *ok = false; |
| 2062 return impl()->EmptyObjectLiteralProperty(); | 2078 return impl()->EmptyObjectLiteralProperty(); |
| 2063 } | 2079 } |
| 2064 | 2080 |
| 2065 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static); | 2081 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static); |
| 2066 | 2082 |
| 2067 if (!*is_computed_name) { | 2083 if (!*is_computed_name) { |
| 2068 checker->CheckProperty(name_token, PropertyKind::kValueProperty, | 2084 checker->CheckProperty(name_token, PropertyKind::kValueProperty, |
| 2069 MethodKind::kNormal, classifier, | 2085 MethodKind::kNormal, |
| 2070 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2086 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2071 } | 2087 } |
| 2072 Consume(Token::COLON); | 2088 Consume(Token::COLON); |
| 2073 int beg_pos = peek_position(); | 2089 int beg_pos = peek_position(); |
| 2074 ExpressionT value = ParseAssignmentExpression( | 2090 ExpressionT value = ParseAssignmentExpression( |
| 2075 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2091 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2076 CheckDestructuringElement(value, classifier, beg_pos, | 2092 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos); |
| 2077 scanner()->location().end_pos); | |
| 2078 | 2093 |
| 2079 return factory()->NewObjectLiteralProperty(name_expression, value, | 2094 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 2080 is_static, *is_computed_name); | 2095 is_static, *is_computed_name); |
| 2081 } | 2096 } |
| 2082 | 2097 |
| 2083 case PropertyKind::kShorthandProperty: { | 2098 case PropertyKind::kShorthandProperty: { |
| 2084 // PropertyDefinition | 2099 // PropertyDefinition |
| 2085 // IdentifierReference | 2100 // IdentifierReference |
| 2086 // CoverInitializedName | 2101 // CoverInitializedName |
| 2087 // | 2102 // |
| 2088 // CoverInitializedName | 2103 // CoverInitializedName |
| 2089 // IdentifierReference Initializer? | 2104 // IdentifierReference Initializer? |
| 2090 if (in_class) { | 2105 if (in_class) { |
| 2091 Token::Value next = Next(); | 2106 Token::Value next = Next(); |
| 2092 ReportUnexpectedToken(next); | 2107 ReportUnexpectedToken(next); |
| 2093 *ok = false; | 2108 *ok = false; |
| 2094 return impl()->EmptyObjectLiteralProperty(); | 2109 return impl()->EmptyObjectLiteralProperty(); |
| 2095 } | 2110 } |
| 2096 | 2111 |
| 2097 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static && | 2112 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static && |
| 2098 !*is_computed_name); | 2113 !*is_computed_name); |
| 2099 | 2114 |
| 2100 if (classifier->duplicate_finder() != nullptr && | 2115 if (classifier()->duplicate_finder() != nullptr && |
| 2101 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 2116 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) { |
| 2102 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 2117 classifier()->RecordDuplicateFormalParameterError( |
| 2118 scanner()->location()); |
| 2103 } | 2119 } |
| 2104 | 2120 |
| 2105 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { | 2121 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { |
| 2106 classifier->RecordBindingPatternError( | 2122 classifier()->RecordBindingPatternError( |
| 2107 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 2123 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 2108 } | 2124 } |
| 2109 | 2125 |
| 2110 if (name_token == Token::LET) { | 2126 if (name_token == Token::LET) { |
| 2111 classifier->RecordLetPatternError( | 2127 classifier()->RecordLetPatternError( |
| 2112 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2128 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 2113 } | 2129 } |
| 2114 if (name_token == Token::AWAIT) { | 2130 if (name_token == Token::AWAIT) { |
| 2115 DCHECK(!is_async_function()); | 2131 DCHECK(!is_async_function()); |
| 2116 classifier->RecordAsyncArrowFormalParametersError( | 2132 classifier()->RecordAsyncArrowFormalParametersError( |
| 2117 Scanner::Location(next_beg_pos, next_end_pos), | 2133 Scanner::Location(next_beg_pos, next_end_pos), |
| 2118 MessageTemplate::kAwaitBindingIdentifier); | 2134 MessageTemplate::kAwaitBindingIdentifier); |
| 2119 } | 2135 } |
| 2120 ExpressionT lhs = | 2136 ExpressionT lhs = |
| 2121 impl()->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); | 2137 impl()->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); |
| 2122 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 2138 CheckDestructuringElement(lhs, next_beg_pos, next_end_pos); |
| 2123 | 2139 |
| 2124 ExpressionT value; | 2140 ExpressionT value; |
| 2125 if (peek() == Token::ASSIGN) { | 2141 if (peek() == Token::ASSIGN) { |
| 2126 Consume(Token::ASSIGN); | 2142 Consume(Token::ASSIGN); |
| 2127 ExpressionClassifier rhs_classifier(this); | 2143 ExpressionClassifier rhs_classifier(this); |
| 2128 ExpressionT rhs = ParseAssignmentExpression( | 2144 ExpressionT rhs = ParseAssignmentExpression( |
| 2129 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2145 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2130 impl()->RewriteNonPattern(&rhs_classifier, | 2146 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2131 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2147 impl()->AccumulateFormalParameterContainmentErrors(); |
| 2132 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); | |
| 2133 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2148 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2134 kNoSourcePosition); | 2149 kNoSourcePosition); |
| 2135 classifier->RecordExpressionError( | 2150 classifier()->RecordExpressionError( |
| 2136 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2151 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2137 MessageTemplate::kInvalidCoverInitializedName); | 2152 MessageTemplate::kInvalidCoverInitializedName); |
| 2138 | 2153 |
| 2139 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); | 2154 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); |
| 2140 } else { | 2155 } else { |
| 2141 value = lhs; | 2156 value = lhs; |
| 2142 } | 2157 } |
| 2143 | 2158 |
| 2144 return factory()->NewObjectLiteralProperty( | 2159 return factory()->NewObjectLiteralProperty( |
| 2145 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, | 2160 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2157 method_kind |= MethodKind::kAsync; | 2172 method_kind |= MethodKind::kAsync; |
| 2158 } | 2173 } |
| 2159 if (is_static) { | 2174 if (is_static) { |
| 2160 method_kind |= MethodKind::kStatic; | 2175 method_kind |= MethodKind::kStatic; |
| 2161 } | 2176 } |
| 2162 | 2177 |
| 2163 // MethodDefinition | 2178 // MethodDefinition |
| 2164 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2179 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2165 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2180 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2166 | 2181 |
| 2167 classifier->RecordPatternError( | 2182 classifier()->RecordPatternError( |
| 2168 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2183 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2169 MessageTemplate::kInvalidDestructuringTarget); | 2184 MessageTemplate::kInvalidDestructuringTarget); |
| 2170 | 2185 |
| 2171 if (!*is_computed_name) { | 2186 if (!*is_computed_name) { |
| 2172 checker->CheckProperty(name_token, PropertyKind::kMethodProperty, | 2187 checker->CheckProperty(name_token, PropertyKind::kMethodProperty, |
| 2173 method_kind, classifier, | 2188 method_kind, |
| 2174 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2189 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2175 } | 2190 } |
| 2176 | 2191 |
| 2177 FunctionKind kind = is_generator | 2192 FunctionKind kind = is_generator |
| 2178 ? FunctionKind::kConciseGeneratorMethod | 2193 ? FunctionKind::kConciseGeneratorMethod |
| 2179 : is_async ? FunctionKind::kAsyncConciseMethod | 2194 : is_async ? FunctionKind::kAsyncConciseMethod |
| 2180 : FunctionKind::kConciseMethod; | 2195 : FunctionKind::kConciseMethod; |
| 2181 | 2196 |
| 2182 if (in_class && !is_static && impl()->IsConstructor(*name)) { | 2197 if (in_class && !is_static && impl()->IsConstructor(*name)) { |
| 2183 *has_seen_constructor = true; | 2198 *has_seen_constructor = true; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2197 | 2212 |
| 2198 case PropertyKind::kAccessorProperty: { | 2213 case PropertyKind::kAccessorProperty: { |
| 2199 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2214 DCHECK((is_get || is_set) && !is_generator && !is_async); |
| 2200 | 2215 |
| 2201 MethodKind method_kind = MethodKind::kNormal; | 2216 MethodKind method_kind = MethodKind::kNormal; |
| 2202 if (is_static) { | 2217 if (is_static) { |
| 2203 DCHECK(in_class); | 2218 DCHECK(in_class); |
| 2204 method_kind |= MethodKind::kStatic; | 2219 method_kind |= MethodKind::kStatic; |
| 2205 } | 2220 } |
| 2206 | 2221 |
| 2207 classifier->RecordPatternError( | 2222 classifier()->RecordPatternError( |
| 2208 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2223 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2209 MessageTemplate::kInvalidDestructuringTarget); | 2224 MessageTemplate::kInvalidDestructuringTarget); |
| 2210 if (!*is_computed_name) { | 2225 if (!*is_computed_name) { |
| 2211 checker->CheckProperty(name_token, PropertyKind::kAccessorProperty, | 2226 checker->CheckProperty(name_token, PropertyKind::kAccessorProperty, |
| 2212 method_kind, classifier, | 2227 method_kind, |
| 2213 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2228 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2214 } | 2229 } |
| 2215 | 2230 |
| 2216 typename Types::FunctionLiteral value = impl()->ParseFunctionLiteral( | 2231 typename Types::FunctionLiteral value = impl()->ParseFunctionLiteral( |
| 2217 *name, scanner()->location(), kSkipFunctionNameCheck, | 2232 *name, scanner()->location(), kSkipFunctionNameCheck, |
| 2218 is_get ? FunctionKind::kGetterFunction | 2233 is_get ? FunctionKind::kGetterFunction |
| 2219 : FunctionKind::kSetterFunction, | 2234 : FunctionKind::kSetterFunction, |
| 2220 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2235 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2221 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2236 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2222 | 2237 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2236 | 2251 |
| 2237 case PropertyKind::kNotSet: | 2252 case PropertyKind::kNotSet: |
| 2238 UNREACHABLE(); | 2253 UNREACHABLE(); |
| 2239 } | 2254 } |
| 2240 UNREACHABLE(); | 2255 UNREACHABLE(); |
| 2241 return impl()->EmptyObjectLiteralProperty(); | 2256 return impl()->EmptyObjectLiteralProperty(); |
| 2242 } | 2257 } |
| 2243 | 2258 |
| 2244 template <typename Impl> | 2259 template <typename Impl> |
| 2245 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2260 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
| 2246 ExpressionClassifier* classifier, bool* ok) { | 2261 bool* ok) { |
| 2247 // ObjectLiteral :: | 2262 // ObjectLiteral :: |
| 2248 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2263 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| 2249 | 2264 |
| 2250 int pos = peek_position(); | 2265 int pos = peek_position(); |
| 2251 typename Types::PropertyList properties = impl()->NewPropertyList(4); | 2266 typename Types::PropertyList properties = impl()->NewPropertyList(4); |
| 2252 int number_of_boilerplate_properties = 0; | 2267 int number_of_boilerplate_properties = 0; |
| 2253 bool has_computed_names = false; | 2268 bool has_computed_names = false; |
| 2254 ObjectLiteralChecker checker(this); | 2269 ObjectLiteralChecker checker(this); |
| 2255 | 2270 |
| 2256 Expect(Token::LBRACE, CHECK_OK); | 2271 Expect(Token::LBRACE, CHECK_OK); |
| 2257 | 2272 |
| 2258 while (peek() != Token::RBRACE) { | 2273 while (peek() != Token::RBRACE) { |
| 2259 FuncNameInferrer::State fni_state(fni_); | 2274 FuncNameInferrer::State fni_state(fni_); |
| 2260 | 2275 |
| 2261 const bool in_class = false; | 2276 const bool in_class = false; |
| 2262 const bool has_extends = false; | 2277 const bool has_extends = false; |
| 2263 bool is_computed_name = false; | 2278 bool is_computed_name = false; |
| 2264 IdentifierT name = impl()->EmptyIdentifier(); | 2279 IdentifierT name = impl()->EmptyIdentifier(); |
| 2265 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2280 ObjectLiteralPropertyT property = |
| 2266 &checker, in_class, has_extends, &is_computed_name, nullptr, classifier, | 2281 ParsePropertyDefinition(&checker, in_class, has_extends, |
| 2267 &name, CHECK_OK); | 2282 &is_computed_name, nullptr, &name, CHECK_OK); |
| 2268 | 2283 |
| 2269 if (is_computed_name) { | 2284 if (is_computed_name) { |
| 2270 has_computed_names = true; | 2285 has_computed_names = true; |
| 2271 } | 2286 } |
| 2272 | 2287 |
| 2273 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2288 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 2274 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2289 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
| 2275 number_of_boilerplate_properties++; | 2290 number_of_boilerplate_properties++; |
| 2276 } | 2291 } |
| 2277 properties->Add(property, zone()); | 2292 properties->Add(property, zone()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2292 | 2307 |
| 2293 return factory()->NewObjectLiteral(properties, | 2308 return factory()->NewObjectLiteral(properties, |
| 2294 literal_index, | 2309 literal_index, |
| 2295 number_of_boilerplate_properties, | 2310 number_of_boilerplate_properties, |
| 2296 pos); | 2311 pos); |
| 2297 } | 2312 } |
| 2298 | 2313 |
| 2299 template <typename Impl> | 2314 template <typename Impl> |
| 2300 typename ParserBase<Impl>::Types::ExpressionList | 2315 typename ParserBase<Impl>::Types::ExpressionList |
| 2301 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, | 2316 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, |
| 2302 bool maybe_arrow, | 2317 bool maybe_arrow, bool* ok) { |
| 2303 ExpressionClassifier* classifier, bool* ok) { | |
| 2304 // Arguments :: | 2318 // Arguments :: |
| 2305 // '(' (AssignmentExpression)*[','] ')' | 2319 // '(' (AssignmentExpression)*[','] ')' |
| 2306 | 2320 |
| 2307 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2321 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2308 typename Types::ExpressionList result = impl()->NewExpressionList(4); | 2322 typename Types::ExpressionList result = impl()->NewExpressionList(4); |
| 2309 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2323 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2310 bool done = (peek() == Token::RPAREN); | 2324 bool done = (peek() == Token::RPAREN); |
| 2311 bool was_unspread = false; | 2325 bool was_unspread = false; |
| 2312 int unspread_sequences_count = 0; | 2326 int unspread_sequences_count = 0; |
| 2313 while (!done) { | 2327 while (!done) { |
| 2314 int start_pos = peek_position(); | 2328 int start_pos = peek_position(); |
| 2315 bool is_spread = Check(Token::ELLIPSIS); | 2329 bool is_spread = Check(Token::ELLIPSIS); |
| 2316 int expr_pos = peek_position(); | 2330 int expr_pos = peek_position(); |
| 2317 | 2331 |
| 2318 ExpressionT argument = ParseAssignmentExpression( | 2332 ExpressionT argument = |
| 2319 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2333 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2320 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2334 CheckNoTailCallExpressions(CHECK_OK_CUSTOM(NullExpressionList)); |
| 2321 if (!maybe_arrow) { | 2335 if (!maybe_arrow) { |
| 2322 impl()->RewriteNonPattern(classifier, | 2336 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
| 2323 CHECK_OK_CUSTOM(NullExpressionList)); | |
| 2324 } | 2337 } |
| 2325 if (is_spread) { | 2338 if (is_spread) { |
| 2326 if (!spread_arg.IsValid()) { | 2339 if (!spread_arg.IsValid()) { |
| 2327 spread_arg.beg_pos = start_pos; | 2340 spread_arg.beg_pos = start_pos; |
| 2328 spread_arg.end_pos = peek_position(); | 2341 spread_arg.end_pos = peek_position(); |
| 2329 } | 2342 } |
| 2330 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 2343 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
| 2331 } | 2344 } |
| 2332 result->Add(argument, zone_); | 2345 result->Add(argument, zone_); |
| 2333 | 2346 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2357 Scanner::Location location = scanner_->location(); | 2370 Scanner::Location location = scanner_->location(); |
| 2358 if (Token::RPAREN != Next()) { | 2371 if (Token::RPAREN != Next()) { |
| 2359 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2372 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 2360 *ok = false; | 2373 *ok = false; |
| 2361 return impl()->NullExpressionList(); | 2374 return impl()->NullExpressionList(); |
| 2362 } | 2375 } |
| 2363 *first_spread_arg_loc = spread_arg; | 2376 *first_spread_arg_loc = spread_arg; |
| 2364 | 2377 |
| 2365 if (!maybe_arrow || peek() != Token::ARROW) { | 2378 if (!maybe_arrow || peek() != Token::ARROW) { |
| 2366 if (maybe_arrow) { | 2379 if (maybe_arrow) { |
| 2367 impl()->RewriteNonPattern(classifier, | 2380 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
| 2368 CHECK_OK_CUSTOM(NullExpressionList)); | |
| 2369 } | 2381 } |
| 2370 if (spread_arg.IsValid()) { | 2382 if (spread_arg.IsValid()) { |
| 2371 // Unspread parameter sequences are translated into array literals in the | 2383 // Unspread parameter sequences are translated into array literals in the |
| 2372 // parser. Ensure that the number of materialized literals matches between | 2384 // parser. Ensure that the number of materialized literals matches between |
| 2373 // the parser and preparser | 2385 // the parser and preparser |
| 2374 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2386 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2375 } | 2387 } |
| 2376 } | 2388 } |
| 2377 | 2389 |
| 2378 return result; | 2390 return result; |
| 2379 } | 2391 } |
| 2380 | 2392 |
| 2381 // Precedence = 2 | 2393 // Precedence = 2 |
| 2382 template <typename Impl> | 2394 template <typename Impl> |
| 2383 typename ParserBase<Impl>::ExpressionT | 2395 typename ParserBase<Impl>::ExpressionT |
| 2384 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, | 2396 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2385 ExpressionClassifier* classifier, | |
| 2386 bool* ok) { | |
| 2387 // AssignmentExpression :: | 2397 // AssignmentExpression :: |
| 2388 // ConditionalExpression | 2398 // ConditionalExpression |
| 2389 // ArrowFunction | 2399 // ArrowFunction |
| 2390 // YieldExpression | 2400 // YieldExpression |
| 2391 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2401 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2392 int lhs_beg_pos = peek_position(); | 2402 int lhs_beg_pos = peek_position(); |
| 2393 | 2403 |
| 2394 if (peek() == Token::YIELD && is_generator()) { | 2404 if (peek() == Token::YIELD && is_generator()) { |
| 2395 return ParseYieldExpression(accept_IN, classifier, ok); | 2405 return ParseYieldExpression(accept_IN, ok); |
| 2396 } | 2406 } |
| 2397 | 2407 |
| 2398 FuncNameInferrer::State fni_state(fni_); | 2408 FuncNameInferrer::State fni_state(fni_); |
| 2399 Checkpoint checkpoint(this); | 2409 Checkpoint checkpoint(this); |
| 2400 ExpressionClassifier arrow_formals_classifier(this, | 2410 ExpressionClassifier arrow_formals_classifier( |
| 2401 classifier->duplicate_finder()); | 2411 this, classifier()->duplicate_finder()); |
| 2402 | 2412 |
| 2403 Scope::Snapshot scope_snapshot(scope()); | 2413 Scope::Snapshot scope_snapshot(scope()); |
| 2404 | 2414 |
| 2405 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | 2415 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && |
| 2406 !scanner()->HasAnyLineTerminatorAfterNext() && | 2416 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 2407 IsValidArrowFormalParametersStart(PeekAhead()); | 2417 IsValidArrowFormalParametersStart(PeekAhead()); |
| 2408 | 2418 |
| 2409 bool parenthesized_formals = peek() == Token::LPAREN; | 2419 bool parenthesized_formals = peek() == Token::LPAREN; |
| 2410 if (!is_async && !parenthesized_formals) { | 2420 if (!is_async && !parenthesized_formals) { |
| 2411 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2421 ArrowFormalParametersUnexpectedToken(); |
| 2412 } | 2422 } |
| 2413 | 2423 |
| 2414 // Parse a simple, faster sub-grammar (primary expression) if it's evident | 2424 // Parse a simple, faster sub-grammar (primary expression) if it's evident |
| 2415 // that we have only a trivial expression to parse. | 2425 // that we have only a trivial expression to parse. |
| 2416 ExpressionT expression; | 2426 ExpressionT expression; |
| 2417 if (IsTrivialExpression()) { | 2427 if (IsTrivialExpression()) { |
| 2418 expression = | 2428 expression = ParsePrimaryExpression(&is_async, CHECK_OK); |
| 2419 ParsePrimaryExpression(&arrow_formals_classifier, &is_async, CHECK_OK); | |
| 2420 } else { | 2429 } else { |
| 2421 expression = ParseConditionalExpression( | 2430 expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
| 2422 accept_IN, &arrow_formals_classifier, CHECK_OK); | |
| 2423 } | 2431 } |
| 2424 | 2432 |
| 2425 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && | 2433 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && |
| 2426 PeekAhead() == Token::ARROW) { | 2434 PeekAhead() == Token::ARROW) { |
| 2427 // async Identifier => AsyncConciseBody | 2435 // async Identifier => AsyncConciseBody |
| 2428 IdentifierT name = | 2436 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); |
| 2429 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | |
| 2430 expression = impl()->ExpressionFromIdentifier( | 2437 expression = impl()->ExpressionFromIdentifier( |
| 2431 name, position(), scanner()->location().end_pos, InferName::kNo); | 2438 name, position(), scanner()->location().end_pos, InferName::kNo); |
| 2432 if (fni_) { | 2439 if (fni_) { |
| 2433 // Remove `async` keyword from inferred name stack. | 2440 // Remove `async` keyword from inferred name stack. |
| 2434 fni_->RemoveAsyncKeywordFromEnd(); | 2441 fni_->RemoveAsyncKeywordFromEnd(); |
| 2435 } | 2442 } |
| 2436 } | 2443 } |
| 2437 | 2444 |
| 2438 if (peek() == Token::ARROW) { | 2445 if (peek() == Token::ARROW) { |
| 2439 Scanner::Location arrow_loc = scanner()->peek_location(); | 2446 Scanner::Location arrow_loc = scanner()->peek_location(); |
| 2440 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2447 ValidateArrowFormalParameters(expression, parenthesized_formals, is_async, |
| 2441 parenthesized_formals, is_async, CHECK_OK); | 2448 CHECK_OK); |
| 2442 // This reads strangely, but is correct: it checks whether any | 2449 // This reads strangely, but is correct: it checks whether any |
| 2443 // sub-expression of the parameter list failed to be a valid formal | 2450 // sub-expression of the parameter list failed to be a valid formal |
| 2444 // parameter initializer. Since YieldExpressions are banned anywhere | 2451 // parameter initializer. Since YieldExpressions are banned anywhere |
| 2445 // in an arrow parameter list, this is correct. | 2452 // in an arrow parameter list, this is correct. |
| 2446 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2453 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
| 2447 // "YieldExpression", which is its only use. | 2454 // "YieldExpression", which is its only use. |
| 2448 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2455 ValidateFormalParameterInitializer(ok); |
| 2449 | 2456 |
| 2450 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2457 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| 2451 DeclarationScope* scope = | 2458 DeclarationScope* scope = |
| 2452 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction | 2459 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction |
| 2453 : FunctionKind::kArrowFunction); | 2460 : FunctionKind::kArrowFunction); |
| 2454 // Because the arrow's parameters were parsed in the outer scope, any | 2461 // Because the arrow's parameters were parsed in the outer scope, any |
| 2455 // usage flags that might have been triggered there need to be copied | 2462 // usage flags that might have been triggered there need to be copied |
| 2456 // to the arrow scope. | 2463 // to the arrow scope. |
| 2457 this->scope()->PropagateUsageFlagsToScope(scope); | 2464 this->scope()->PropagateUsageFlagsToScope(scope); |
| 2458 FormalParametersT parameters(scope); | 2465 FormalParametersT parameters(scope); |
| 2459 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2466 if (!classifier()->is_simple_parameter_list()) { |
| 2460 scope->SetHasNonSimpleParameters(); | 2467 scope->SetHasNonSimpleParameters(); |
| 2461 parameters.is_simple = false; | 2468 parameters.is_simple = false; |
| 2462 } | 2469 } |
| 2463 | 2470 |
| 2464 checkpoint.Restore(¶meters.materialized_literals_count); | 2471 checkpoint.Restore(¶meters.materialized_literals_count); |
| 2465 | 2472 |
| 2466 scope->set_start_position(lhs_beg_pos); | 2473 scope->set_start_position(lhs_beg_pos); |
| 2467 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2474 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2468 impl()->ParseArrowFunctionFormalParameterList( | 2475 impl()->ParseArrowFunctionFormalParameterList( |
| 2469 ¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK); | 2476 ¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK); |
| 2470 if (duplicate_loc.IsValid()) { | 2477 if (duplicate_loc.IsValid()) { |
| 2471 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2478 classifier()->RecordDuplicateFormalParameterError(duplicate_loc); |
| 2472 duplicate_loc); | |
| 2473 } | 2479 } |
| 2474 expression = ParseArrowFunctionLiteral(accept_IN, parameters, is_async, | 2480 expression = |
| 2475 arrow_formals_classifier, CHECK_OK); | 2481 ParseArrowFunctionLiteral(accept_IN, parameters, is_async, CHECK_OK); |
| 2476 arrow_formals_classifier.Discard(); | 2482 impl()->Discard(); |
| 2477 classifier->RecordPatternError(arrow_loc, | 2483 classifier()->RecordPatternError(arrow_loc, |
| 2478 MessageTemplate::kUnexpectedToken, | 2484 MessageTemplate::kUnexpectedToken, |
| 2479 Token::String(Token::ARROW)); | 2485 Token::String(Token::ARROW)); |
| 2480 | 2486 |
| 2481 if (fni_ != nullptr) fni_->Infer(); | 2487 if (fni_ != nullptr) fni_->Infer(); |
| 2482 | 2488 |
| 2483 return expression; | 2489 return expression; |
| 2484 } | 2490 } |
| 2485 | 2491 |
| 2486 // "expression" was not itself an arrow function parameter list, but it might | 2492 // "expression" was not itself an arrow function parameter list, but it might |
| 2487 // form part of one. Propagate speculative formal parameter error locations | 2493 // form part of one. Propagate speculative formal parameter error locations |
| 2488 // (including those for binding patterns, since formal parameters can | 2494 // (including those for binding patterns, since formal parameters can |
| 2489 // themselves contain binding patterns). | 2495 // themselves contain binding patterns). |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2503 if (is_destructuring_assignment) { | 2509 if (is_destructuring_assignment) { |
| 2504 // This is definitely not an expression so don't accumulate | 2510 // This is definitely not an expression so don't accumulate |
| 2505 // expression-related errors. | 2511 // expression-related errors. |
| 2506 productions &= ~(ExpressionClassifier::ExpressionProduction | | 2512 productions &= ~(ExpressionClassifier::ExpressionProduction | |
| 2507 ExpressionClassifier::TailCallExpressionProduction); | 2513 ExpressionClassifier::TailCallExpressionProduction); |
| 2508 } | 2514 } |
| 2509 | 2515 |
| 2510 if (!Token::IsAssignmentOp(peek())) { | 2516 if (!Token::IsAssignmentOp(peek())) { |
| 2511 // Parsed conditional expression only (no assignment). | 2517 // Parsed conditional expression only (no assignment). |
| 2512 // Pending non-pattern expressions must be merged. | 2518 // Pending non-pattern expressions must be merged. |
| 2513 classifier->Accumulate(&arrow_formals_classifier, productions); | 2519 impl()->Accumulate(productions); |
| 2514 return expression; | 2520 return expression; |
| 2515 } else { | 2521 } else { |
| 2516 // Pending non-pattern expressions must be discarded. | 2522 // Pending non-pattern expressions must be discarded. |
| 2517 classifier->Accumulate(&arrow_formals_classifier, productions, false); | 2523 impl()->Accumulate(productions, false); |
| 2518 } | 2524 } |
| 2519 | 2525 |
| 2520 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2526 CheckNoTailCallExpressions(CHECK_OK); |
| 2521 | 2527 |
| 2522 if (is_destructuring_assignment) { | 2528 if (is_destructuring_assignment) { |
| 2523 ValidateAssignmentPattern(classifier, CHECK_OK); | 2529 ValidateAssignmentPattern(CHECK_OK); |
| 2524 } else { | 2530 } else { |
| 2525 expression = CheckAndRewriteReferenceExpression( | 2531 expression = CheckAndRewriteReferenceExpression( |
| 2526 expression, lhs_beg_pos, scanner()->location().end_pos, | 2532 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2527 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2533 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 2528 } | 2534 } |
| 2529 | 2535 |
| 2530 expression = impl()->MarkExpressionAsAssigned(expression); | 2536 expression = impl()->MarkExpressionAsAssigned(expression); |
| 2531 | 2537 |
| 2532 Token::Value op = Next(); // Get assignment operator. | 2538 Token::Value op = Next(); // Get assignment operator. |
| 2533 if (op != Token::ASSIGN) { | 2539 if (op != Token::ASSIGN) { |
| 2534 classifier->RecordPatternError(scanner()->location(), | 2540 classifier()->RecordPatternError(scanner()->location(), |
| 2535 MessageTemplate::kUnexpectedToken, | 2541 MessageTemplate::kUnexpectedToken, |
| 2536 Token::String(op)); | 2542 Token::String(op)); |
| 2537 } | 2543 } |
| 2538 int pos = position(); | 2544 int pos = position(); |
| 2539 | 2545 |
| 2540 ExpressionClassifier rhs_classifier(this); | 2546 ExpressionClassifier rhs_classifier(this); |
| 2541 | 2547 |
| 2542 ExpressionT right = | 2548 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2543 ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2549 CheckNoTailCallExpressions(CHECK_OK); |
| 2544 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); | 2550 impl()->RewriteNonPattern(CHECK_OK); |
| 2545 impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2551 impl()->AccumulateFormalParameterContainmentErrors(); |
| 2546 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); | |
| 2547 | 2552 |
| 2548 // TODO(1231235): We try to estimate the set of properties set by | 2553 // TODO(1231235): We try to estimate the set of properties set by |
| 2549 // constructors. We define a new property whenever there is an | 2554 // constructors. We define a new property whenever there is an |
| 2550 // assignment to a property of 'this'. We should probably only add | 2555 // assignment to a property of 'this'. We should probably only add |
| 2551 // properties if we haven't seen them before. Otherwise we'll | 2556 // properties if we haven't seen them before. Otherwise we'll |
| 2552 // probably overestimate the number of properties. | 2557 // probably overestimate the number of properties. |
| 2553 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { | 2558 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { |
| 2554 function_state_->AddProperty(); | 2559 function_state_->AddProperty(); |
| 2555 } | 2560 } |
| 2556 | 2561 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2582 if (is_destructuring_assignment) { | 2587 if (is_destructuring_assignment) { |
| 2583 result = factory()->NewRewritableExpression(result); | 2588 result = factory()->NewRewritableExpression(result); |
| 2584 impl()->QueueDestructuringAssignmentForRewriting(result); | 2589 impl()->QueueDestructuringAssignmentForRewriting(result); |
| 2585 } | 2590 } |
| 2586 | 2591 |
| 2587 return result; | 2592 return result; |
| 2588 } | 2593 } |
| 2589 | 2594 |
| 2590 template <typename Impl> | 2595 template <typename Impl> |
| 2591 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( | 2596 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
| 2592 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2597 bool accept_IN, bool* ok) { |
| 2593 // YieldExpression :: | 2598 // YieldExpression :: |
| 2594 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2599 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 2595 int pos = peek_position(); | 2600 int pos = peek_position(); |
| 2596 classifier->RecordPatternError(scanner()->peek_location(), | 2601 classifier()->RecordPatternError( |
| 2597 MessageTemplate::kInvalidDestructuringTarget); | 2602 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget); |
| 2598 classifier->RecordFormalParameterInitializerError( | 2603 classifier()->RecordFormalParameterInitializerError( |
| 2599 scanner()->peek_location(), MessageTemplate::kYieldInParameter); | 2604 scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
| 2600 Expect(Token::YIELD, CHECK_OK); | 2605 Expect(Token::YIELD, CHECK_OK); |
| 2601 ExpressionT generator_object = | 2606 ExpressionT generator_object = |
| 2602 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2607 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
| 2603 // The following initialization is necessary. | 2608 // The following initialization is necessary. |
| 2604 ExpressionT expression = impl()->EmptyExpression(); | 2609 ExpressionT expression = impl()->EmptyExpression(); |
| 2605 bool delegating = false; // yield* | 2610 bool delegating = false; // yield* |
| 2606 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2611 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2607 if (Check(Token::MUL)) delegating = true; | 2612 if (Check(Token::MUL)) delegating = true; |
| 2608 switch (peek()) { | 2613 switch (peek()) { |
| 2609 case Token::EOS: | 2614 case Token::EOS: |
| 2610 case Token::SEMICOLON: | 2615 case Token::SEMICOLON: |
| 2611 case Token::RBRACE: | 2616 case Token::RBRACE: |
| 2612 case Token::RBRACK: | 2617 case Token::RBRACK: |
| 2613 case Token::RPAREN: | 2618 case Token::RPAREN: |
| 2614 case Token::COLON: | 2619 case Token::COLON: |
| 2615 case Token::COMMA: | 2620 case Token::COMMA: |
| 2616 // The above set of tokens is the complete set of tokens that can appear | 2621 // The above set of tokens is the complete set of tokens that can appear |
| 2617 // after an AssignmentExpression, and none of them can start an | 2622 // after an AssignmentExpression, and none of them can start an |
| 2618 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2623 // AssignmentExpression. This allows us to avoid looking for an RHS for |
| 2619 // a regular yield, given only one look-ahead token. | 2624 // a regular yield, given only one look-ahead token. |
| 2620 if (!delegating) break; | 2625 if (!delegating) break; |
| 2621 // Delegating yields require an RHS; fall through. | 2626 // Delegating yields require an RHS; fall through. |
| 2622 default: | 2627 default: |
| 2623 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2628 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2624 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2629 impl()->RewriteNonPattern(CHECK_OK); |
| 2625 break; | 2630 break; |
| 2626 } | 2631 } |
| 2627 } | 2632 } |
| 2628 | 2633 |
| 2629 if (delegating) { | 2634 if (delegating) { |
| 2630 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2635 return impl()->RewriteYieldStar(generator_object, expression, pos); |
| 2631 } | 2636 } |
| 2632 | 2637 |
| 2633 expression = impl()->BuildIteratorResult(expression, false); | 2638 expression = impl()->BuildIteratorResult(expression, false); |
| 2634 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2639 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| 2635 // TODO(verwaest): Come up with a better solution. | 2640 // TODO(verwaest): Come up with a better solution. |
| 2636 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, | 2641 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
| 2637 Yield::kOnExceptionThrow); | 2642 Yield::kOnExceptionThrow); |
| 2638 return yield; | 2643 return yield; |
| 2639 } | 2644 } |
| 2640 | 2645 |
| 2641 template <typename Impl> | 2646 template <typename Impl> |
| 2642 typename ParserBase<Impl>::ExpressionT | 2647 typename ParserBase<Impl>::ExpressionT |
| 2643 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, | 2648 ParserBase<Impl>::ParseTailCallExpression(bool* ok) { |
| 2644 bool* ok) { | |
| 2645 // TailCallExpression:: | 2649 // TailCallExpression:: |
| 2646 // 'continue' MemberExpression Arguments | 2650 // 'continue' MemberExpression Arguments |
| 2647 // 'continue' CallExpression Arguments | 2651 // 'continue' CallExpression Arguments |
| 2648 // 'continue' MemberExpression TemplateLiteral | 2652 // 'continue' MemberExpression TemplateLiteral |
| 2649 // 'continue' CallExpression TemplateLiteral | 2653 // 'continue' CallExpression TemplateLiteral |
| 2650 Expect(Token::CONTINUE, CHECK_OK); | 2654 Expect(Token::CONTINUE, CHECK_OK); |
| 2651 int pos = position(); | 2655 int pos = position(); |
| 2652 int sub_expression_pos = peek_position(); | 2656 int sub_expression_pos = peek_position(); |
| 2653 ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK); | 2657 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2654 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2658 CheckNoTailCallExpressions(CHECK_OK); |
| 2655 | 2659 |
| 2656 Scanner::Location loc(pos, scanner()->location().end_pos); | 2660 Scanner::Location loc(pos, scanner()->location().end_pos); |
| 2657 | 2661 |
| 2658 if (!expression->IsCall()) { | 2662 if (!expression->IsCall()) { |
| 2659 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); | 2663 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
| 2660 impl()->ReportMessageAt(sub_loc, | 2664 impl()->ReportMessageAt(sub_loc, |
| 2661 MessageTemplate::kUnexpectedInsideTailCall); | 2665 MessageTemplate::kUnexpectedInsideTailCall); |
| 2662 *ok = false; | 2666 *ok = false; |
| 2663 return impl()->EmptyExpression(); | 2667 return impl()->EmptyExpression(); |
| 2664 } | 2668 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2695 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; | 2699 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; |
| 2696 break; | 2700 break; |
| 2697 case ReturnExprContext::kInsideForInOfBody: | 2701 case ReturnExprContext::kInsideForInOfBody: |
| 2698 msg = MessageTemplate::kUnexpectedTailCallInForInOf; | 2702 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
| 2699 break; | 2703 break; |
| 2700 } | 2704 } |
| 2701 impl()->ReportMessageAt(loc, msg); | 2705 impl()->ReportMessageAt(loc, msg); |
| 2702 *ok = false; | 2706 *ok = false; |
| 2703 return impl()->EmptyExpression(); | 2707 return impl()->EmptyExpression(); |
| 2704 } | 2708 } |
| 2705 classifier->RecordTailCallExpressionError( | 2709 classifier()->RecordTailCallExpressionError( |
| 2706 loc, MessageTemplate::kUnexpectedTailCall); | 2710 loc, MessageTemplate::kUnexpectedTailCall); |
| 2707 function_state_->AddExplicitTailCallExpression(expression, loc); | 2711 function_state_->AddExplicitTailCallExpression(expression, loc); |
| 2708 return expression; | 2712 return expression; |
| 2709 } | 2713 } |
| 2710 | 2714 |
| 2711 // Precedence = 3 | 2715 // Precedence = 3 |
| 2712 template <typename Impl> | 2716 template <typename Impl> |
| 2713 typename ParserBase<Impl>::ExpressionT | 2717 typename ParserBase<Impl>::ExpressionT |
| 2714 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, | 2718 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, |
| 2715 ExpressionClassifier* classifier, | |
| 2716 bool* ok) { | 2719 bool* ok) { |
| 2717 // ConditionalExpression :: | 2720 // ConditionalExpression :: |
| 2718 // LogicalOrExpression | 2721 // LogicalOrExpression |
| 2719 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2722 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2720 | 2723 |
| 2721 int pos = peek_position(); | 2724 int pos = peek_position(); |
| 2722 // We start using the binary expression parser for prec >= 4 only! | 2725 // We start using the binary expression parser for prec >= 4 only! |
| 2723 ExpressionT expression = | 2726 ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2724 ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | |
| 2725 if (peek() != Token::CONDITIONAL) return expression; | 2727 if (peek() != Token::CONDITIONAL) return expression; |
| 2726 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2728 CheckNoTailCallExpressions(CHECK_OK); |
| 2727 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2729 impl()->RewriteNonPattern(CHECK_OK); |
| 2728 BindingPatternUnexpectedToken(classifier); | 2730 BindingPatternUnexpectedToken(); |
| 2729 ArrowFormalParametersUnexpectedToken(classifier); | 2731 ArrowFormalParametersUnexpectedToken(); |
| 2730 Consume(Token::CONDITIONAL); | 2732 Consume(Token::CONDITIONAL); |
| 2731 // In parsing the first assignment expression in conditional | 2733 // In parsing the first assignment expression in conditional |
| 2732 // expressions we always accept the 'in' keyword; see ECMA-262, | 2734 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2733 // section 11.12, page 58. | 2735 // section 11.12, page 58. |
| 2734 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2736 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); |
| 2735 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2737 impl()->RewriteNonPattern(CHECK_OK); |
| 2736 Expect(Token::COLON, CHECK_OK); | 2738 Expect(Token::COLON, CHECK_OK); |
| 2737 ExpressionT right = | 2739 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2738 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2740 impl()->RewriteNonPattern(CHECK_OK); |
| 2739 impl()->RewriteNonPattern(classifier, CHECK_OK); | |
| 2740 return factory()->NewConditional(expression, left, right, pos); | 2741 return factory()->NewConditional(expression, left, right, pos); |
| 2741 } | 2742 } |
| 2742 | 2743 |
| 2743 | 2744 |
| 2744 // Precedence >= 4 | 2745 // Precedence >= 4 |
| 2745 template <typename Impl> | 2746 template <typename Impl> |
| 2746 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( | 2747 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( |
| 2747 int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2748 int prec, bool accept_IN, bool* ok) { |
| 2748 DCHECK(prec >= 4); | 2749 DCHECK(prec >= 4); |
| 2749 ExpressionT x = ParseUnaryExpression(classifier, CHECK_OK); | 2750 ExpressionT x = ParseUnaryExpression(CHECK_OK); |
| 2750 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2751 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2751 // prec1 >= 4 | 2752 // prec1 >= 4 |
| 2752 while (Precedence(peek(), accept_IN) == prec1) { | 2753 while (Precedence(peek(), accept_IN) == prec1) { |
| 2753 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2754 CheckNoTailCallExpressions(CHECK_OK); |
| 2754 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2755 impl()->RewriteNonPattern(CHECK_OK); |
| 2755 BindingPatternUnexpectedToken(classifier); | 2756 BindingPatternUnexpectedToken(); |
| 2756 ArrowFormalParametersUnexpectedToken(classifier); | 2757 ArrowFormalParametersUnexpectedToken(); |
| 2757 Token::Value op = Next(); | 2758 Token::Value op = Next(); |
| 2758 int pos = position(); | 2759 int pos = position(); |
| 2759 | 2760 |
| 2760 const bool is_right_associative = op == Token::EXP; | 2761 const bool is_right_associative = op == Token::EXP; |
| 2761 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2762 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
| 2762 ExpressionT y = | 2763 ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK); |
| 2763 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | |
| 2764 if (op != Token::OR && op != Token::AND) { | 2764 if (op != Token::OR && op != Token::AND) { |
| 2765 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2765 CheckNoTailCallExpressions(CHECK_OK); |
| 2766 } | 2766 } |
| 2767 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2767 impl()->RewriteNonPattern(CHECK_OK); |
| 2768 | 2768 |
| 2769 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { | 2769 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { |
| 2770 continue; | 2770 continue; |
| 2771 } | 2771 } |
| 2772 | 2772 |
| 2773 // For now we distinguish between comparisons and other binary | 2773 // For now we distinguish between comparisons and other binary |
| 2774 // operations. (We could combine the two and get rid of this | 2774 // operations. (We could combine the two and get rid of this |
| 2775 // code and AST node eventually.) | 2775 // code and AST node eventually.) |
| 2776 if (Token::IsCompareOp(op)) { | 2776 if (Token::IsCompareOp(op)) { |
| 2777 // We have a comparison. | 2777 // We have a comparison. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2792 // We have a "normal" binary operation. | 2792 // We have a "normal" binary operation. |
| 2793 x = factory()->NewBinaryOperation(op, x, y, pos); | 2793 x = factory()->NewBinaryOperation(op, x, y, pos); |
| 2794 } | 2794 } |
| 2795 } | 2795 } |
| 2796 } | 2796 } |
| 2797 return x; | 2797 return x; |
| 2798 } | 2798 } |
| 2799 | 2799 |
| 2800 template <typename Impl> | 2800 template <typename Impl> |
| 2801 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( | 2801 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( |
| 2802 ExpressionClassifier* classifier, bool* ok) { | 2802 bool* ok) { |
| 2803 // UnaryExpression :: | 2803 // UnaryExpression :: |
| 2804 // PostfixExpression | 2804 // PostfixExpression |
| 2805 // 'delete' UnaryExpression | 2805 // 'delete' UnaryExpression |
| 2806 // 'void' UnaryExpression | 2806 // 'void' UnaryExpression |
| 2807 // 'typeof' UnaryExpression | 2807 // 'typeof' UnaryExpression |
| 2808 // '++' UnaryExpression | 2808 // '++' UnaryExpression |
| 2809 // '--' UnaryExpression | 2809 // '--' UnaryExpression |
| 2810 // '+' UnaryExpression | 2810 // '+' UnaryExpression |
| 2811 // '-' UnaryExpression | 2811 // '-' UnaryExpression |
| 2812 // '~' UnaryExpression | 2812 // '~' UnaryExpression |
| 2813 // '!' UnaryExpression | 2813 // '!' UnaryExpression |
| 2814 // [+Await] AwaitExpression[?Yield] | 2814 // [+Await] AwaitExpression[?Yield] |
| 2815 | 2815 |
| 2816 Token::Value op = peek(); | 2816 Token::Value op = peek(); |
| 2817 if (Token::IsUnaryOp(op)) { | 2817 if (Token::IsUnaryOp(op)) { |
| 2818 BindingPatternUnexpectedToken(classifier); | 2818 BindingPatternUnexpectedToken(); |
| 2819 ArrowFormalParametersUnexpectedToken(classifier); | 2819 ArrowFormalParametersUnexpectedToken(); |
| 2820 | 2820 |
| 2821 op = Next(); | 2821 op = Next(); |
| 2822 int pos = position(); | 2822 int pos = position(); |
| 2823 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2823 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
| 2824 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2824 CheckNoTailCallExpressions(CHECK_OK); |
| 2825 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2825 impl()->RewriteNonPattern(CHECK_OK); |
| 2826 | 2826 |
| 2827 if (op == Token::DELETE && is_strict(language_mode())) { | 2827 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2828 if (impl()->IsIdentifier(expression)) { | 2828 if (impl()->IsIdentifier(expression)) { |
| 2829 // "delete identifier" is a syntax error in strict mode. | 2829 // "delete identifier" is a syntax error in strict mode. |
| 2830 ReportMessage(MessageTemplate::kStrictDelete); | 2830 ReportMessage(MessageTemplate::kStrictDelete); |
| 2831 *ok = false; | 2831 *ok = false; |
| 2832 return impl()->EmptyExpression(); | 2832 return impl()->EmptyExpression(); |
| 2833 } | 2833 } |
| 2834 } | 2834 } |
| 2835 | 2835 |
| 2836 if (peek() == Token::EXP) { | 2836 if (peek() == Token::EXP) { |
| 2837 ReportUnexpectedToken(Next()); | 2837 ReportUnexpectedToken(Next()); |
| 2838 *ok = false; | 2838 *ok = false; |
| 2839 return impl()->EmptyExpression(); | 2839 return impl()->EmptyExpression(); |
| 2840 } | 2840 } |
| 2841 | 2841 |
| 2842 // Allow the parser's implementation to rewrite the expression. | 2842 // Allow the parser's implementation to rewrite the expression. |
| 2843 return impl()->BuildUnaryExpression(expression, op, pos); | 2843 return impl()->BuildUnaryExpression(expression, op, pos); |
| 2844 } else if (Token::IsCountOp(op)) { | 2844 } else if (Token::IsCountOp(op)) { |
| 2845 BindingPatternUnexpectedToken(classifier); | 2845 BindingPatternUnexpectedToken(); |
| 2846 ArrowFormalParametersUnexpectedToken(classifier); | 2846 ArrowFormalParametersUnexpectedToken(); |
| 2847 op = Next(); | 2847 op = Next(); |
| 2848 int beg_pos = peek_position(); | 2848 int beg_pos = peek_position(); |
| 2849 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2849 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
| 2850 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2850 CheckNoTailCallExpressions(CHECK_OK); |
| 2851 expression = CheckAndRewriteReferenceExpression( | 2851 expression = CheckAndRewriteReferenceExpression( |
| 2852 expression, beg_pos, scanner()->location().end_pos, | 2852 expression, beg_pos, scanner()->location().end_pos, |
| 2853 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2853 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
| 2854 expression = impl()->MarkExpressionAsAssigned(expression); | 2854 expression = impl()->MarkExpressionAsAssigned(expression); |
| 2855 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2855 impl()->RewriteNonPattern(CHECK_OK); |
| 2856 | 2856 |
| 2857 return factory()->NewCountOperation(op, | 2857 return factory()->NewCountOperation(op, |
| 2858 true /* prefix */, | 2858 true /* prefix */, |
| 2859 expression, | 2859 expression, |
| 2860 position()); | 2860 position()); |
| 2861 | 2861 |
| 2862 } else if (is_async_function() && peek() == Token::AWAIT) { | 2862 } else if (is_async_function() && peek() == Token::AWAIT) { |
| 2863 classifier->RecordFormalParameterInitializerError( | 2863 classifier()->RecordFormalParameterInitializerError( |
| 2864 scanner()->peek_location(), | 2864 scanner()->peek_location(), |
| 2865 MessageTemplate::kAwaitExpressionFormalParameter); | 2865 MessageTemplate::kAwaitExpressionFormalParameter); |
| 2866 | 2866 |
| 2867 int await_pos = peek_position(); | 2867 int await_pos = peek_position(); |
| 2868 Consume(Token::AWAIT); | 2868 Consume(Token::AWAIT); |
| 2869 | 2869 |
| 2870 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2870 ExpressionT value = ParseUnaryExpression(CHECK_OK); |
| 2871 | 2871 |
| 2872 return impl()->RewriteAwaitExpression(value, await_pos); | 2872 return impl()->RewriteAwaitExpression(value, await_pos); |
| 2873 } else { | 2873 } else { |
| 2874 return ParsePostfixExpression(classifier, ok); | 2874 return ParsePostfixExpression(ok); |
| 2875 } | 2875 } |
| 2876 } | 2876 } |
| 2877 | 2877 |
| 2878 template <typename Impl> | 2878 template <typename Impl> |
| 2879 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( | 2879 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( |
| 2880 ExpressionClassifier* classifier, bool* ok) { | 2880 bool* ok) { |
| 2881 // PostfixExpression :: | 2881 // PostfixExpression :: |
| 2882 // LeftHandSideExpression ('++' | '--')? | 2882 // LeftHandSideExpression ('++' | '--')? |
| 2883 | 2883 |
| 2884 int lhs_beg_pos = peek_position(); | 2884 int lhs_beg_pos = peek_position(); |
| 2885 ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK); | 2885 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2886 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2886 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2887 Token::IsCountOp(peek())) { | 2887 Token::IsCountOp(peek())) { |
| 2888 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2888 CheckNoTailCallExpressions(CHECK_OK); |
| 2889 BindingPatternUnexpectedToken(classifier); | 2889 BindingPatternUnexpectedToken(); |
| 2890 ArrowFormalParametersUnexpectedToken(classifier); | 2890 ArrowFormalParametersUnexpectedToken(); |
| 2891 | 2891 |
| 2892 expression = CheckAndRewriteReferenceExpression( | 2892 expression = CheckAndRewriteReferenceExpression( |
| 2893 expression, lhs_beg_pos, scanner()->location().end_pos, | 2893 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2894 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2894 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
| 2895 expression = impl()->MarkExpressionAsAssigned(expression); | 2895 expression = impl()->MarkExpressionAsAssigned(expression); |
| 2896 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2896 impl()->RewriteNonPattern(CHECK_OK); |
| 2897 | 2897 |
| 2898 Token::Value next = Next(); | 2898 Token::Value next = Next(); |
| 2899 expression = | 2899 expression = |
| 2900 factory()->NewCountOperation(next, | 2900 factory()->NewCountOperation(next, |
| 2901 false /* postfix */, | 2901 false /* postfix */, |
| 2902 expression, | 2902 expression, |
| 2903 position()); | 2903 position()); |
| 2904 } | 2904 } |
| 2905 return expression; | 2905 return expression; |
| 2906 } | 2906 } |
| 2907 | 2907 |
| 2908 template <typename Impl> | 2908 template <typename Impl> |
| 2909 typename ParserBase<Impl>::ExpressionT | 2909 typename ParserBase<Impl>::ExpressionT |
| 2910 ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 2910 ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { |
| 2911 bool* ok) { | |
| 2912 // LeftHandSideExpression :: | 2911 // LeftHandSideExpression :: |
| 2913 // (NewExpression | MemberExpression) ... | 2912 // (NewExpression | MemberExpression) ... |
| 2914 | 2913 |
| 2915 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { | 2914 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
| 2916 return ParseTailCallExpression(classifier, ok); | 2915 return ParseTailCallExpression(ok); |
| 2917 } | 2916 } |
| 2918 | 2917 |
| 2919 bool is_async = false; | 2918 bool is_async = false; |
| 2920 ExpressionT result = | 2919 ExpressionT result = |
| 2921 ParseMemberWithNewPrefixesExpression(classifier, &is_async, CHECK_OK); | 2920 ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK); |
| 2922 | 2921 |
| 2923 while (true) { | 2922 while (true) { |
| 2924 switch (peek()) { | 2923 switch (peek()) { |
| 2925 case Token::LBRACK: { | 2924 case Token::LBRACK: { |
| 2926 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2925 CheckNoTailCallExpressions(CHECK_OK); |
| 2927 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2926 impl()->RewriteNonPattern(CHECK_OK); |
| 2928 BindingPatternUnexpectedToken(classifier); | 2927 BindingPatternUnexpectedToken(); |
| 2929 ArrowFormalParametersUnexpectedToken(classifier); | 2928 ArrowFormalParametersUnexpectedToken(); |
| 2930 Consume(Token::LBRACK); | 2929 Consume(Token::LBRACK); |
| 2931 int pos = position(); | 2930 int pos = position(); |
| 2932 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2931 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); |
| 2933 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2932 impl()->RewriteNonPattern(CHECK_OK); |
| 2934 result = factory()->NewProperty(result, index, pos); | 2933 result = factory()->NewProperty(result, index, pos); |
| 2935 Expect(Token::RBRACK, CHECK_OK); | 2934 Expect(Token::RBRACK, CHECK_OK); |
| 2936 break; | 2935 break; |
| 2937 } | 2936 } |
| 2938 | 2937 |
| 2939 case Token::LPAREN: { | 2938 case Token::LPAREN: { |
| 2940 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2939 CheckNoTailCallExpressions(CHECK_OK); |
| 2941 int pos; | 2940 int pos; |
| 2942 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2941 impl()->RewriteNonPattern(CHECK_OK); |
| 2943 BindingPatternUnexpectedToken(classifier); | 2942 BindingPatternUnexpectedToken(); |
| 2944 if (scanner()->current_token() == Token::IDENTIFIER || | 2943 if (scanner()->current_token() == Token::IDENTIFIER || |
| 2945 scanner()->current_token() == Token::SUPER || | 2944 scanner()->current_token() == Token::SUPER || |
| 2946 scanner()->current_token() == Token::ASYNC) { | 2945 scanner()->current_token() == Token::ASYNC) { |
| 2947 // For call of an identifier we want to report position of | 2946 // For call of an identifier we want to report position of |
| 2948 // the identifier as position of the call in the stack trace. | 2947 // the identifier as position of the call in the stack trace. |
| 2949 pos = position(); | 2948 pos = position(); |
| 2950 } else { | 2949 } else { |
| 2951 // For other kinds of calls we record position of the parenthesis as | 2950 // For other kinds of calls we record position of the parenthesis as |
| 2952 // position of the call. Note that this is extremely important for | 2951 // position of the call. Note that this is extremely important for |
| 2953 // expressions of the form function(){...}() for which call position | 2952 // expressions of the form function(){...}() for which call position |
| 2954 // should not point to the closing brace otherwise it will intersect | 2953 // should not point to the closing brace otherwise it will intersect |
| 2955 // with positions recorded for function literal and confuse debugger. | 2954 // with positions recorded for function literal and confuse debugger. |
| 2956 pos = peek_position(); | 2955 pos = peek_position(); |
| 2957 // Also the trailing parenthesis are a hint that the function will | 2956 // Also the trailing parenthesis are a hint that the function will |
| 2958 // be called immediately. If we happen to have parsed a preceding | 2957 // be called immediately. If we happen to have parsed a preceding |
| 2959 // function literal eagerly, we can also compile it eagerly. | 2958 // function literal eagerly, we can also compile it eagerly. |
| 2960 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2959 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2961 result->AsFunctionLiteral()->set_should_eager_compile(); | 2960 result->AsFunctionLiteral()->set_should_eager_compile(); |
| 2962 } | 2961 } |
| 2963 } | 2962 } |
| 2964 Scanner::Location spread_pos; | 2963 Scanner::Location spread_pos; |
| 2965 typename Types::ExpressionList args; | 2964 typename Types::ExpressionList args; |
| 2966 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { | 2965 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { |
| 2967 ExpressionClassifier async_classifier(this); | 2966 ExpressionClassifier async_classifier(this); |
| 2968 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); | 2967 args = ParseArguments(&spread_pos, true, CHECK_OK); |
| 2969 if (peek() == Token::ARROW) { | 2968 if (peek() == Token::ARROW) { |
| 2970 if (fni_) { | 2969 if (fni_) { |
| 2971 fni_->RemoveAsyncKeywordFromEnd(); | 2970 fni_->RemoveAsyncKeywordFromEnd(); |
| 2972 } | 2971 } |
| 2973 ValidateBindingPattern(&async_classifier, CHECK_OK); | 2972 ValidateBindingPattern(CHECK_OK); |
| 2974 ValidateFormalParameterInitializer(&async_classifier, CHECK_OK); | 2973 ValidateFormalParameterInitializer(CHECK_OK); |
| 2975 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { | 2974 if (!classifier()->is_valid_async_arrow_formal_parameters()) { |
| 2976 ReportClassifierError( | 2975 ReportClassifierError( |
| 2977 async_classifier.async_arrow_formal_parameters_error()); | 2976 classifier()->async_arrow_formal_parameters_error()); |
| 2978 *ok = false; | 2977 *ok = false; |
| 2979 return impl()->EmptyExpression(); | 2978 return impl()->EmptyExpression(); |
| 2980 } | 2979 } |
| 2981 if (args->length()) { | 2980 if (args->length()) { |
| 2982 // async ( Arguments ) => ... | 2981 // async ( Arguments ) => ... |
| 2983 return impl()->ExpressionListToExpression(args); | 2982 return impl()->ExpressionListToExpression(args); |
| 2984 } | 2983 } |
| 2985 // async () => ... | 2984 // async () => ... |
| 2986 return factory()->NewEmptyParentheses(pos); | 2985 return factory()->NewEmptyParentheses(pos); |
| 2987 } else { | 2986 } else { |
| 2988 classifier->AccumulateFormalParameterContainmentErrors( | 2987 impl()->AccumulateFormalParameterContainmentErrors(); |
| 2989 &async_classifier); | |
| 2990 } | 2988 } |
| 2991 } else { | 2989 } else { |
| 2992 args = ParseArguments(&spread_pos, false, classifier, CHECK_OK); | 2990 args = ParseArguments(&spread_pos, false, CHECK_OK); |
| 2993 } | 2991 } |
| 2994 | 2992 |
| 2995 ArrowFormalParametersUnexpectedToken(classifier); | 2993 ArrowFormalParametersUnexpectedToken(); |
| 2996 | 2994 |
| 2997 // Keep track of eval() calls since they disable all local variable | 2995 // Keep track of eval() calls since they disable all local variable |
| 2998 // optimizations. | 2996 // optimizations. |
| 2999 // The calls that need special treatment are the | 2997 // The calls that need special treatment are the |
| 3000 // direct eval calls. These calls are all of the form eval(...), with | 2998 // direct eval calls. These calls are all of the form eval(...), with |
| 3001 // no explicit receiver. | 2999 // no explicit receiver. |
| 3002 // These calls are marked as potentially direct eval calls. Whether | 3000 // These calls are marked as potentially direct eval calls. Whether |
| 3003 // they are actually direct calls to eval is determined at run time. | 3001 // they are actually direct calls to eval is determined at run time. |
| 3004 Call::PossiblyEval is_possibly_eval = | 3002 Call::PossiblyEval is_possibly_eval = |
| 3005 CheckPossibleEvalCall(result, scope()); | 3003 CheckPossibleEvalCall(result, scope()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3018 ExpressionT this_expr = impl()->ThisExpression(pos); | 3016 ExpressionT this_expr = impl()->ThisExpression(pos); |
| 3019 result = | 3017 result = |
| 3020 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 3018 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
| 3021 } | 3019 } |
| 3022 | 3020 |
| 3023 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3021 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3024 break; | 3022 break; |
| 3025 } | 3023 } |
| 3026 | 3024 |
| 3027 case Token::PERIOD: { | 3025 case Token::PERIOD: { |
| 3028 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3026 CheckNoTailCallExpressions(CHECK_OK); |
| 3029 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3027 impl()->RewriteNonPattern(CHECK_OK); |
| 3030 BindingPatternUnexpectedToken(classifier); | 3028 BindingPatternUnexpectedToken(); |
| 3031 ArrowFormalParametersUnexpectedToken(classifier); | 3029 ArrowFormalParametersUnexpectedToken(); |
| 3032 Consume(Token::PERIOD); | 3030 Consume(Token::PERIOD); |
| 3033 int pos = position(); | 3031 int pos = position(); |
| 3034 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3032 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3035 result = factory()->NewProperty( | 3033 result = factory()->NewProperty( |
| 3036 result, factory()->NewStringLiteral(name, pos), pos); | 3034 result, factory()->NewStringLiteral(name, pos), pos); |
| 3037 if (fni_ != NULL) impl()->PushLiteralName(fni_, name); | 3035 if (fni_ != NULL) impl()->PushLiteralName(fni_, name); |
| 3038 break; | 3036 break; |
| 3039 } | 3037 } |
| 3040 | 3038 |
| 3041 case Token::TEMPLATE_SPAN: | 3039 case Token::TEMPLATE_SPAN: |
| 3042 case Token::TEMPLATE_TAIL: { | 3040 case Token::TEMPLATE_TAIL: { |
| 3043 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3041 CheckNoTailCallExpressions(CHECK_OK); |
| 3044 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3042 impl()->RewriteNonPattern(CHECK_OK); |
| 3045 BindingPatternUnexpectedToken(classifier); | 3043 BindingPatternUnexpectedToken(); |
| 3046 ArrowFormalParametersUnexpectedToken(classifier); | 3044 ArrowFormalParametersUnexpectedToken(); |
| 3047 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 3045 result = ParseTemplateLiteral(result, position(), CHECK_OK); |
| 3048 break; | 3046 break; |
| 3049 } | 3047 } |
| 3050 | 3048 |
| 3051 default: | 3049 default: |
| 3052 return result; | 3050 return result; |
| 3053 } | 3051 } |
| 3054 } | 3052 } |
| 3055 } | 3053 } |
| 3056 | 3054 |
| 3057 template <typename Impl> | 3055 template <typename Impl> |
| 3058 typename ParserBase<Impl>::ExpressionT | 3056 typename ParserBase<Impl>::ExpressionT |
| 3059 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression( | 3057 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async, |
| 3060 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 3058 bool* ok) { |
| 3061 // NewExpression :: | 3059 // NewExpression :: |
| 3062 // ('new')+ MemberExpression | 3060 // ('new')+ MemberExpression |
| 3063 // | 3061 // |
| 3064 // NewTarget :: | 3062 // NewTarget :: |
| 3065 // 'new' '.' 'target' | 3063 // 'new' '.' 'target' |
| 3066 | 3064 |
| 3067 // The grammar for new expressions is pretty warped. We can have several 'new' | 3065 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 3068 // keywords following each other, and then a MemberExpression. When we see '(' | 3066 // keywords following each other, and then a MemberExpression. When we see '(' |
| 3069 // after the MemberExpression, it's associated with the rightmost unassociated | 3067 // after the MemberExpression, it's associated with the rightmost unassociated |
| 3070 // 'new' to create a NewExpression with arguments. However, a NewExpression | 3068 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 3071 // can also occur without arguments. | 3069 // can also occur without arguments. |
| 3072 | 3070 |
| 3073 // Examples of new expression: | 3071 // Examples of new expression: |
| 3074 // new foo.bar().baz means (new (foo.bar)()).baz | 3072 // new foo.bar().baz means (new (foo.bar)()).baz |
| 3075 // new foo()() means (new foo())() | 3073 // new foo()() means (new foo())() |
| 3076 // new new foo()() means (new (new foo())()) | 3074 // new new foo()() means (new (new foo())()) |
| 3077 // new new foo means new (new foo) | 3075 // new new foo means new (new foo) |
| 3078 // new new foo() means new (new foo()) | 3076 // new new foo() means new (new foo()) |
| 3079 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3077 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 3080 | 3078 |
| 3081 if (peek() == Token::NEW) { | 3079 if (peek() == Token::NEW) { |
| 3082 BindingPatternUnexpectedToken(classifier); | 3080 BindingPatternUnexpectedToken(); |
| 3083 ArrowFormalParametersUnexpectedToken(classifier); | 3081 ArrowFormalParametersUnexpectedToken(); |
| 3084 Consume(Token::NEW); | 3082 Consume(Token::NEW); |
| 3085 int new_pos = position(); | 3083 int new_pos = position(); |
| 3086 ExpressionT result; | 3084 ExpressionT result; |
| 3087 if (peek() == Token::SUPER) { | 3085 if (peek() == Token::SUPER) { |
| 3088 const bool is_new = true; | 3086 const bool is_new = true; |
| 3089 result = ParseSuperExpression(is_new, CHECK_OK); | 3087 result = ParseSuperExpression(is_new, CHECK_OK); |
| 3090 } else if (peek() == Token::PERIOD) { | 3088 } else if (peek() == Token::PERIOD) { |
| 3091 return ParseNewTargetExpression(CHECK_OK); | 3089 return ParseNewTargetExpression(CHECK_OK); |
| 3092 } else { | 3090 } else { |
| 3093 result = | 3091 result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK); |
| 3094 ParseMemberWithNewPrefixesExpression(classifier, is_async, CHECK_OK); | |
| 3095 } | 3092 } |
| 3096 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3093 impl()->RewriteNonPattern(CHECK_OK); |
| 3097 if (peek() == Token::LPAREN) { | 3094 if (peek() == Token::LPAREN) { |
| 3098 // NewExpression with arguments. | 3095 // NewExpression with arguments. |
| 3099 Scanner::Location spread_pos; | 3096 Scanner::Location spread_pos; |
| 3100 typename Types::ExpressionList args = | 3097 typename Types::ExpressionList args = |
| 3101 ParseArguments(&spread_pos, classifier, CHECK_OK); | 3098 ParseArguments(&spread_pos, CHECK_OK); |
| 3102 | 3099 |
| 3103 if (spread_pos.IsValid()) { | 3100 if (spread_pos.IsValid()) { |
| 3104 args = impl()->PrepareSpreadArguments(args); | 3101 args = impl()->PrepareSpreadArguments(args); |
| 3105 result = impl()->SpreadCallNew(result, args, new_pos); | 3102 result = impl()->SpreadCallNew(result, args, new_pos); |
| 3106 } else { | 3103 } else { |
| 3107 result = factory()->NewCallNew(result, args, new_pos); | 3104 result = factory()->NewCallNew(result, args, new_pos); |
| 3108 } | 3105 } |
| 3109 // The expression can still continue with . or [ after the arguments. | 3106 // The expression can still continue with . or [ after the arguments. |
| 3110 result = ParseMemberExpressionContinuation(result, is_async, classifier, | 3107 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); |
| 3111 CHECK_OK); | |
| 3112 return result; | 3108 return result; |
| 3113 } | 3109 } |
| 3114 // NewExpression without arguments. | 3110 // NewExpression without arguments. |
| 3115 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); | 3111 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); |
| 3116 } | 3112 } |
| 3117 // No 'new' or 'super' keyword. | 3113 // No 'new' or 'super' keyword. |
| 3118 return ParseMemberExpression(classifier, is_async, ok); | 3114 return ParseMemberExpression(is_async, ok); |
| 3119 } | 3115 } |
| 3120 | 3116 |
| 3121 template <typename Impl> | 3117 template <typename Impl> |
| 3122 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( | 3118 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( |
| 3123 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 3119 bool* is_async, bool* ok) { |
| 3124 // MemberExpression :: | 3120 // MemberExpression :: |
| 3125 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3121 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 3126 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3122 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 3127 | 3123 |
| 3128 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3124 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 3129 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3125 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 3130 // caller. | 3126 // caller. |
| 3131 | 3127 |
| 3132 // Parse the initial primary or function expression. | 3128 // Parse the initial primary or function expression. |
| 3133 ExpressionT result; | 3129 ExpressionT result; |
| 3134 if (peek() == Token::FUNCTION) { | 3130 if (peek() == Token::FUNCTION) { |
| 3135 BindingPatternUnexpectedToken(classifier); | 3131 BindingPatternUnexpectedToken(); |
| 3136 ArrowFormalParametersUnexpectedToken(classifier); | 3132 ArrowFormalParametersUnexpectedToken(); |
| 3137 | 3133 |
| 3138 Consume(Token::FUNCTION); | 3134 Consume(Token::FUNCTION); |
| 3139 int function_token_position = position(); | 3135 int function_token_position = position(); |
| 3140 | 3136 |
| 3141 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { | 3137 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { |
| 3142 // function.sent | 3138 // function.sent |
| 3143 int pos = position(); | 3139 int pos = position(); |
| 3144 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); | 3140 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); |
| 3145 | 3141 |
| 3146 if (!is_generator()) { | 3142 if (!is_generator()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3171 result = impl()->ParseFunctionLiteral( | 3167 result = impl()->ParseFunctionLiteral( |
| 3172 name, function_name_location, | 3168 name, function_name_location, |
| 3173 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3169 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
| 3174 : kFunctionNameValidityUnknown, | 3170 : kFunctionNameValidityUnknown, |
| 3175 function_kind, function_token_position, function_type, language_mode(), | 3171 function_kind, function_token_position, function_type, language_mode(), |
| 3176 CHECK_OK); | 3172 CHECK_OK); |
| 3177 } else if (peek() == Token::SUPER) { | 3173 } else if (peek() == Token::SUPER) { |
| 3178 const bool is_new = false; | 3174 const bool is_new = false; |
| 3179 result = ParseSuperExpression(is_new, CHECK_OK); | 3175 result = ParseSuperExpression(is_new, CHECK_OK); |
| 3180 } else { | 3176 } else { |
| 3181 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); | 3177 result = ParsePrimaryExpression(is_async, CHECK_OK); |
| 3182 } | 3178 } |
| 3183 | 3179 |
| 3184 result = | 3180 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); |
| 3185 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); | |
| 3186 return result; | 3181 return result; |
| 3187 } | 3182 } |
| 3188 | 3183 |
| 3189 template <typename Impl> | 3184 template <typename Impl> |
| 3190 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( | 3185 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( |
| 3191 bool is_new, bool* ok) { | 3186 bool is_new, bool* ok) { |
| 3192 Expect(Token::SUPER, CHECK_OK); | 3187 Expect(Token::SUPER, CHECK_OK); |
| 3193 int pos = position(); | 3188 int pos = position(); |
| 3194 | 3189 |
| 3195 DeclarationScope* scope = GetReceiverScope(); | 3190 DeclarationScope* scope = GetReceiverScope(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3240 MessageTemplate::kUnexpectedNewTarget); | 3235 MessageTemplate::kUnexpectedNewTarget); |
| 3241 *ok = false; | 3236 *ok = false; |
| 3242 return impl()->EmptyExpression(); | 3237 return impl()->EmptyExpression(); |
| 3243 } | 3238 } |
| 3244 | 3239 |
| 3245 return impl()->NewTargetExpression(pos); | 3240 return impl()->NewTargetExpression(pos); |
| 3246 } | 3241 } |
| 3247 | 3242 |
| 3248 template <typename Impl> | 3243 template <typename Impl> |
| 3249 typename ParserBase<Impl>::ExpressionT | 3244 typename ParserBase<Impl>::ExpressionT |
| 3250 ParserBase<Impl>::ParseMemberExpressionContinuation( | 3245 ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, |
| 3251 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3246 bool* is_async, bool* ok) { |
| 3252 bool* ok) { | |
| 3253 // Parses this part of MemberExpression: | 3247 // Parses this part of MemberExpression: |
| 3254 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3248 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3255 while (true) { | 3249 while (true) { |
| 3256 switch (peek()) { | 3250 switch (peek()) { |
| 3257 case Token::LBRACK: { | 3251 case Token::LBRACK: { |
| 3258 *is_async = false; | 3252 *is_async = false; |
| 3259 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3253 impl()->RewriteNonPattern(CHECK_OK); |
| 3260 BindingPatternUnexpectedToken(classifier); | 3254 BindingPatternUnexpectedToken(); |
| 3261 ArrowFormalParametersUnexpectedToken(classifier); | 3255 ArrowFormalParametersUnexpectedToken(); |
| 3262 | 3256 |
| 3263 Consume(Token::LBRACK); | 3257 Consume(Token::LBRACK); |
| 3264 int pos = position(); | 3258 int pos = position(); |
| 3265 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3259 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); |
| 3266 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3260 impl()->RewriteNonPattern(CHECK_OK); |
| 3267 expression = factory()->NewProperty(expression, index, pos); | 3261 expression = factory()->NewProperty(expression, index, pos); |
| 3268 if (fni_ != NULL) { | 3262 if (fni_ != NULL) { |
| 3269 impl()->PushPropertyName(fni_, index); | 3263 impl()->PushPropertyName(fni_, index); |
| 3270 } | 3264 } |
| 3271 Expect(Token::RBRACK, CHECK_OK); | 3265 Expect(Token::RBRACK, CHECK_OK); |
| 3272 break; | 3266 break; |
| 3273 } | 3267 } |
| 3274 case Token::PERIOD: { | 3268 case Token::PERIOD: { |
| 3275 *is_async = false; | 3269 *is_async = false; |
| 3276 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3270 impl()->RewriteNonPattern(CHECK_OK); |
| 3277 BindingPatternUnexpectedToken(classifier); | 3271 BindingPatternUnexpectedToken(); |
| 3278 ArrowFormalParametersUnexpectedToken(classifier); | 3272 ArrowFormalParametersUnexpectedToken(); |
| 3279 | 3273 |
| 3280 Consume(Token::PERIOD); | 3274 Consume(Token::PERIOD); |
| 3281 int pos = position(); | 3275 int pos = position(); |
| 3282 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3276 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3283 expression = factory()->NewProperty( | 3277 expression = factory()->NewProperty( |
| 3284 expression, factory()->NewStringLiteral(name, pos), pos); | 3278 expression, factory()->NewStringLiteral(name, pos), pos); |
| 3285 if (fni_ != NULL) { | 3279 if (fni_ != NULL) { |
| 3286 impl()->PushLiteralName(fni_, name); | 3280 impl()->PushLiteralName(fni_, name); |
| 3287 } | 3281 } |
| 3288 break; | 3282 break; |
| 3289 } | 3283 } |
| 3290 case Token::TEMPLATE_SPAN: | 3284 case Token::TEMPLATE_SPAN: |
| 3291 case Token::TEMPLATE_TAIL: { | 3285 case Token::TEMPLATE_TAIL: { |
| 3292 *is_async = false; | 3286 *is_async = false; |
| 3293 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3287 impl()->RewriteNonPattern(CHECK_OK); |
| 3294 BindingPatternUnexpectedToken(classifier); | 3288 BindingPatternUnexpectedToken(); |
| 3295 ArrowFormalParametersUnexpectedToken(classifier); | 3289 ArrowFormalParametersUnexpectedToken(); |
| 3296 int pos; | 3290 int pos; |
| 3297 if (scanner()->current_token() == Token::IDENTIFIER) { | 3291 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3298 pos = position(); | 3292 pos = position(); |
| 3299 } else { | 3293 } else { |
| 3300 pos = peek_position(); | 3294 pos = peek_position(); |
| 3301 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3295 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3302 // If the tag function looks like an IIFE, set_parenthesized() to | 3296 // If the tag function looks like an IIFE, set_parenthesized() to |
| 3303 // force eager compilation. | 3297 // force eager compilation. |
| 3304 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3298 expression->AsFunctionLiteral()->set_should_eager_compile(); |
| 3305 } | 3299 } |
| 3306 } | 3300 } |
| 3307 expression = | 3301 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); |
| 3308 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | |
| 3309 break; | 3302 break; |
| 3310 } | 3303 } |
| 3311 case Token::ILLEGAL: { | 3304 case Token::ILLEGAL: { |
| 3312 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); | 3305 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); |
| 3313 *ok = false; | 3306 *ok = false; |
| 3314 return impl()->EmptyExpression(); | 3307 return impl()->EmptyExpression(); |
| 3315 } | 3308 } |
| 3316 default: | 3309 default: |
| 3317 return expression; | 3310 return expression; |
| 3318 } | 3311 } |
| 3319 } | 3312 } |
| 3320 DCHECK(false); | 3313 DCHECK(false); |
| 3321 return impl()->EmptyExpression(); | 3314 return impl()->EmptyExpression(); |
| 3322 } | 3315 } |
| 3323 | 3316 |
| 3324 template <typename Impl> | 3317 template <typename Impl> |
| 3325 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, | 3318 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, |
| 3326 ExpressionClassifier* classifier, | |
| 3327 bool* ok) { | 3319 bool* ok) { |
| 3328 // FormalParameter[Yield,GeneratorParameter] : | 3320 // FormalParameter[Yield,GeneratorParameter] : |
| 3329 // BindingElement[?Yield, ?GeneratorParameter] | 3321 // BindingElement[?Yield, ?GeneratorParameter] |
| 3330 bool is_rest = parameters->has_rest; | 3322 bool is_rest = parameters->has_rest; |
| 3331 | 3323 |
| 3332 ExpressionT pattern = | 3324 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void)); |
| 3333 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); | 3325 ValidateBindingPattern(CHECK_OK_CUSTOM(Void)); |
| 3334 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); | |
| 3335 | 3326 |
| 3336 if (!impl()->IsIdentifier(pattern)) { | 3327 if (!impl()->IsIdentifier(pattern)) { |
| 3337 parameters->is_simple = false; | 3328 parameters->is_simple = false; |
| 3338 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); | 3329 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); |
| 3339 classifier->RecordNonSimpleParameter(); | 3330 classifier()->RecordNonSimpleParameter(); |
| 3340 } | 3331 } |
| 3341 | 3332 |
| 3342 ExpressionT initializer = impl()->EmptyExpression(); | 3333 ExpressionT initializer = impl()->EmptyExpression(); |
| 3343 if (!is_rest && Check(Token::ASSIGN)) { | 3334 if (!is_rest && Check(Token::ASSIGN)) { |
| 3344 ExpressionClassifier init_classifier(this); | 3335 ExpressionClassifier init_classifier(this); |
| 3345 initializer = ParseAssignmentExpression(true, &init_classifier, | 3336 initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void)); |
| 3346 CHECK_OK_CUSTOM(Void)); | 3337 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); |
| 3347 impl()->RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3338 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); |
| 3348 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); | |
| 3349 parameters->is_simple = false; | 3339 parameters->is_simple = false; |
| 3350 init_classifier.Discard(); | 3340 impl()->Discard(); |
| 3351 classifier->RecordNonSimpleParameter(); | 3341 classifier()->RecordNonSimpleParameter(); |
| 3352 | 3342 |
| 3353 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern); | 3343 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern); |
| 3354 } | 3344 } |
| 3355 | 3345 |
| 3356 impl()->AddFormalParameter(parameters, pattern, initializer, | 3346 impl()->AddFormalParameter(parameters, pattern, initializer, |
| 3357 scanner()->location().end_pos, is_rest); | 3347 scanner()->location().end_pos, is_rest); |
| 3358 } | 3348 } |
| 3359 | 3349 |
| 3360 template <typename Impl> | 3350 template <typename Impl> |
| 3361 void ParserBase<Impl>::ParseFormalParameterList( | 3351 void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, |
| 3362 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3352 bool* ok) { |
| 3363 // FormalParameters[Yield] : | 3353 // FormalParameters[Yield] : |
| 3364 // [empty] | 3354 // [empty] |
| 3365 // FunctionRestParameter[?Yield] | 3355 // FunctionRestParameter[?Yield] |
| 3366 // FormalParameterList[?Yield] | 3356 // FormalParameterList[?Yield] |
| 3367 // FormalParameterList[?Yield] , | 3357 // FormalParameterList[?Yield] , |
| 3368 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] | 3358 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] |
| 3369 // | 3359 // |
| 3370 // FormalParameterList[Yield] : | 3360 // FormalParameterList[Yield] : |
| 3371 // FormalParameter[?Yield] | 3361 // FormalParameter[?Yield] |
| 3372 // FormalParameterList[?Yield] , FormalParameter[?Yield] | 3362 // FormalParameterList[?Yield] , FormalParameter[?Yield] |
| 3373 | 3363 |
| 3374 DCHECK_EQ(0, parameters->Arity()); | 3364 DCHECK_EQ(0, parameters->Arity()); |
| 3375 | 3365 |
| 3376 if (peek() != Token::RPAREN) { | 3366 if (peek() != Token::RPAREN) { |
| 3377 while (true) { | 3367 while (true) { |
| 3378 if (parameters->Arity() > Code::kMaxArguments) { | 3368 if (parameters->Arity() > Code::kMaxArguments) { |
| 3379 ReportMessage(MessageTemplate::kTooManyParameters); | 3369 ReportMessage(MessageTemplate::kTooManyParameters); |
| 3380 *ok = false; | 3370 *ok = false; |
| 3381 return; | 3371 return; |
| 3382 } | 3372 } |
| 3383 parameters->has_rest = Check(Token::ELLIPSIS); | 3373 parameters->has_rest = Check(Token::ELLIPSIS); |
| 3384 ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void)); | 3374 ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void)); |
| 3385 | 3375 |
| 3386 if (parameters->has_rest) { | 3376 if (parameters->has_rest) { |
| 3387 parameters->is_simple = false; | 3377 parameters->is_simple = false; |
| 3388 classifier->RecordNonSimpleParameter(); | 3378 classifier()->RecordNonSimpleParameter(); |
| 3389 if (peek() == Token::COMMA) { | 3379 if (peek() == Token::COMMA) { |
| 3390 impl()->ReportMessageAt(scanner()->peek_location(), | 3380 impl()->ReportMessageAt(scanner()->peek_location(), |
| 3391 MessageTemplate::kParamAfterRest); | 3381 MessageTemplate::kParamAfterRest); |
| 3392 *ok = false; | 3382 *ok = false; |
| 3393 return; | 3383 return; |
| 3394 } | 3384 } |
| 3395 break; | 3385 break; |
| 3396 } | 3386 } |
| 3397 if (!Check(Token::COMMA)) break; | 3387 if (!Check(Token::COMMA)) break; |
| 3398 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { | 3388 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { |
| 3399 // allow the trailing comma | 3389 // allow the trailing comma |
| 3400 break; | 3390 break; |
| 3401 } | 3391 } |
| 3402 } | 3392 } |
| 3403 } | 3393 } |
| 3404 | 3394 |
| 3405 for (int i = 0; i < parameters->Arity(); ++i) { | 3395 for (int i = 0; i < parameters->Arity(); ++i) { |
| 3406 auto parameter = parameters->at(i); | 3396 auto parameter = parameters->at(i); |
| 3407 impl()->DeclareFormalParameter(parameters->scope, parameter, classifier); | 3397 impl()->DeclareFormalParameter(parameters->scope, parameter); |
| 3408 } | 3398 } |
| 3409 } | 3399 } |
| 3410 | 3400 |
| 3411 template <typename Impl> | 3401 template <typename Impl> |
| 3412 void ParserBase<Impl>::CheckArityRestrictions(int param_count, | 3402 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
| 3413 FunctionKind function_kind, | 3403 FunctionKind function_kind, |
| 3414 bool has_rest, | 3404 bool has_rest, |
| 3415 int formals_start_pos, | 3405 int formals_start_pos, |
| 3416 int formals_end_pos, bool* ok) { | 3406 int formals_end_pos, bool* ok) { |
| 3417 if (IsGetterFunction(function_kind)) { | 3407 if (IsGetterFunction(function_kind)) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3477 return true; | 3467 return true; |
| 3478 } | 3468 } |
| 3479 } | 3469 } |
| 3480 return false; | 3470 return false; |
| 3481 } | 3471 } |
| 3482 | 3472 |
| 3483 template <typename Impl> | 3473 template <typename Impl> |
| 3484 typename ParserBase<Impl>::ExpressionT | 3474 typename ParserBase<Impl>::ExpressionT |
| 3485 ParserBase<Impl>::ParseArrowFunctionLiteral( | 3475 ParserBase<Impl>::ParseArrowFunctionLiteral( |
| 3486 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, | 3476 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
| 3487 const ExpressionClassifier& formals_classifier, bool* ok) { | 3477 bool* ok) { |
| 3488 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3478 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3489 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3479 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3490 // `=> ...` is never a valid expression, so report as syntax error. | 3480 // `=> ...` is never a valid expression, so report as syntax error. |
| 3491 // If next token is not `=>`, it's a syntax error anyways. | 3481 // If next token is not `=>`, it's a syntax error anyways. |
| 3492 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3482 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3493 *ok = false; | 3483 *ok = false; |
| 3494 return impl()->EmptyExpression(); | 3484 return impl()->EmptyExpression(); |
| 3495 } | 3485 } |
| 3496 | 3486 |
| 3497 typename Types::StatementList body; | 3487 typename Types::StatementList body; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 int pos = position(); | 3528 int pos = position(); |
| 3539 DCHECK(ReturnExprContext::kInsideValidBlock == | 3529 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 3540 function_state_->return_expr_context()); | 3530 function_state_->return_expr_context()); |
| 3541 ReturnExprScope allow_tail_calls( | 3531 ReturnExprScope allow_tail_calls( |
| 3542 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3532 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| 3543 body = impl()->NewStatementList(1); | 3533 body = impl()->NewStatementList(1); |
| 3544 impl()->AddParameterInitializationBlock(formal_parameters, body, is_async, | 3534 impl()->AddParameterInitializationBlock(formal_parameters, body, is_async, |
| 3545 CHECK_OK); | 3535 CHECK_OK); |
| 3546 ExpressionClassifier classifier(this); | 3536 ExpressionClassifier classifier(this); |
| 3547 if (is_async) { | 3537 if (is_async) { |
| 3548 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, | 3538 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, pos, |
| 3549 &classifier, pos, CHECK_OK); | 3539 CHECK_OK); |
| 3550 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 3540 impl()->RewriteNonPattern(CHECK_OK); |
| 3551 } else { | 3541 } else { |
| 3552 ExpressionT expression = | 3542 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 3553 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3543 impl()->RewriteNonPattern(CHECK_OK); |
| 3554 impl()->RewriteNonPattern(&classifier, CHECK_OK); | |
| 3555 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3544 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3556 if (allow_tailcalls() && !is_sloppy(language_mode())) { | 3545 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 3557 // ES6 14.6.1 Static Semantics: IsInTailPosition | 3546 // ES6 14.6.1 Static Semantics: IsInTailPosition |
| 3558 impl()->MarkTailPosition(expression); | 3547 impl()->MarkTailPosition(expression); |
| 3559 } | 3548 } |
| 3560 } | 3549 } |
| 3561 materialized_literal_count = function_state.materialized_literal_count(); | 3550 materialized_literal_count = function_state.materialized_literal_count(); |
| 3562 expected_property_count = function_state.expected_property_count(); | 3551 expected_property_count = function_state.expected_property_count(); |
| 3563 impl()->MarkCollectedTailCallExpressions(); | 3552 impl()->MarkCollectedTailCallExpressions(); |
| 3564 } | 3553 } |
| 3565 | 3554 |
| 3566 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3555 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
| 3567 | 3556 |
| 3568 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3557 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 3569 // which is not the same as "parameters of a strict function"; it only means | 3558 // which is not the same as "parameters of a strict function"; it only means |
| 3570 // that duplicates are not allowed. Of course, the arrow function may | 3559 // that duplicates are not allowed. Of course, the arrow function may |
| 3571 // itself be strict as well. | 3560 // itself be strict as well. |
| 3572 const bool allow_duplicate_parameters = false; | 3561 const bool allow_duplicate_parameters = false; |
| 3573 ValidateFormalParameters(&formals_classifier, language_mode(), | 3562 ValidateFormalParameters(language_mode(), allow_duplicate_parameters, |
| 3574 allow_duplicate_parameters, CHECK_OK); | 3563 CHECK_OK); |
| 3575 | 3564 |
| 3576 // Validate strict mode. | 3565 // Validate strict mode. |
| 3577 if (is_strict(language_mode())) { | 3566 if (is_strict(language_mode())) { |
| 3578 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3567 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
| 3579 scanner()->location().end_pos, CHECK_OK); | 3568 scanner()->location().end_pos, CHECK_OK); |
| 3580 } | 3569 } |
| 3581 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3570 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
| 3582 | 3571 |
| 3583 impl()->RewriteDestructuringAssignments(); | 3572 impl()->RewriteDestructuringAssignments(); |
| 3584 } | 3573 } |
| 3585 | 3574 |
| 3586 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3575 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 3587 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 3576 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
| 3588 materialized_literal_count, expected_property_count, num_parameters, | 3577 materialized_literal_count, expected_property_count, num_parameters, |
| 3589 FunctionLiteral::kNoDuplicateParameters, | 3578 FunctionLiteral::kNoDuplicateParameters, |
| 3590 FunctionLiteral::kAnonymousExpression, | 3579 FunctionLiteral::kAnonymousExpression, |
| 3591 FunctionLiteral::kShouldLazyCompile, arrow_kind, | 3580 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
| 3592 formal_parameters.scope->start_position()); | 3581 formal_parameters.scope->start_position()); |
| 3593 | 3582 |
| 3594 function_literal->set_function_token_position( | 3583 function_literal->set_function_token_position( |
| 3595 formal_parameters.scope->start_position()); | 3584 formal_parameters.scope->start_position()); |
| 3596 | 3585 |
| 3597 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); | 3586 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); |
| 3598 | 3587 |
| 3599 return function_literal; | 3588 return function_literal; |
| 3600 } | 3589 } |
| 3601 | 3590 |
| 3602 template <typename Impl> | 3591 template <typename Impl> |
| 3603 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 3592 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
| 3604 ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok) { | 3593 ExpressionT tag, int start, bool* ok) { |
| 3605 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3594 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
| 3606 // text followed by a substitution expression), finalized by a single | 3595 // text followed by a substitution expression), finalized by a single |
| 3607 // TEMPLATE_TAIL. | 3596 // TEMPLATE_TAIL. |
| 3608 // | 3597 // |
| 3609 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3598 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
| 3610 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3599 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
| 3611 // NoSubstitutionTemplate. | 3600 // NoSubstitutionTemplate. |
| 3612 // | 3601 // |
| 3613 // When parsing a TemplateLiteral, we must have scanned either an initial | 3602 // When parsing a TemplateLiteral, we must have scanned either an initial |
| 3614 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3603 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3646 return impl()->EmptyExpression(); | 3635 return impl()->EmptyExpression(); |
| 3647 } else if (next == Token::ILLEGAL) { | 3636 } else if (next == Token::ILLEGAL) { |
| 3648 impl()->ReportMessageAt( | 3637 impl()->ReportMessageAt( |
| 3649 Scanner::Location(position() + 1, peek_position()), | 3638 Scanner::Location(position() + 1, peek_position()), |
| 3650 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3639 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3651 *ok = false; | 3640 *ok = false; |
| 3652 return impl()->EmptyExpression(); | 3641 return impl()->EmptyExpression(); |
| 3653 } | 3642 } |
| 3654 | 3643 |
| 3655 int expr_pos = peek_position(); | 3644 int expr_pos = peek_position(); |
| 3656 ExpressionT expression = ParseExpression(true, classifier, CHECK_OK); | 3645 ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK); |
| 3657 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3646 CheckNoTailCallExpressions(CHECK_OK); |
| 3658 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3647 impl()->RewriteNonPattern(CHECK_OK); |
| 3659 impl()->AddTemplateExpression(&ts, expression); | 3648 impl()->AddTemplateExpression(&ts, expression); |
| 3660 | 3649 |
| 3661 if (peek() != Token::RBRACE) { | 3650 if (peek() != Token::RBRACE) { |
| 3662 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3651 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
| 3663 MessageTemplate::kUnterminatedTemplateExpr); | 3652 MessageTemplate::kUnterminatedTemplateExpr); |
| 3664 *ok = false; | 3653 *ok = false; |
| 3665 return impl()->EmptyExpression(); | 3654 return impl()->EmptyExpression(); |
| 3666 } | 3655 } |
| 3667 | 3656 |
| 3668 // If we didn't die parsing that expression, our next token should be a | 3657 // 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... |
| 3727 *ok = false; | 3716 *ok = false; |
| 3728 return impl()->EmptyExpression(); | 3717 return impl()->EmptyExpression(); |
| 3729 } | 3718 } |
| 3730 | 3719 |
| 3731 template <typename Impl> | 3720 template <typename Impl> |
| 3732 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { | 3721 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { |
| 3733 return IsAssignableIdentifier(expression) || expression->IsProperty(); | 3722 return IsAssignableIdentifier(expression) || expression->IsProperty(); |
| 3734 } | 3723 } |
| 3735 | 3724 |
| 3736 template <typename Impl> | 3725 template <typename Impl> |
| 3737 void ParserBase<Impl>::CheckDestructuringElement( | 3726 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, |
| 3738 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3727 int begin, int end) { |
| 3739 int end) { | |
| 3740 if (!IsValidPattern(expression) && !expression->IsAssignment() && | 3728 if (!IsValidPattern(expression) && !expression->IsAssignment() && |
| 3741 !IsValidReferenceExpression(expression)) { | 3729 !IsValidReferenceExpression(expression)) { |
| 3742 classifier->RecordAssignmentPatternError( | 3730 classifier()->RecordAssignmentPatternError( |
| 3743 Scanner::Location(begin, end), | 3731 Scanner::Location(begin, end), |
| 3744 MessageTemplate::kInvalidDestructuringTarget); | 3732 MessageTemplate::kInvalidDestructuringTarget); |
| 3745 } | 3733 } |
| 3746 } | 3734 } |
| 3747 | 3735 |
| 3748 | 3736 |
| 3749 #undef CHECK_OK | 3737 #undef CHECK_OK |
| 3750 #undef CHECK_OK_CUSTOM | 3738 #undef CHECK_OK_CUSTOM |
| 3751 | 3739 |
| 3752 template <typename Impl> | 3740 template <typename Impl> |
| 3753 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( | 3741 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( |
| 3754 Token::Value property, PropertyKind type, MethodKind method_type, | 3742 Token::Value property, PropertyKind type, MethodKind method_type, |
| 3755 ExpressionClassifier* classifier, bool* ok) { | 3743 bool* ok) { |
| 3756 DCHECK(!IsStaticMethod(method_type)); | 3744 DCHECK(!IsStaticMethod(method_type)); |
| 3757 DCHECK(!IsSpecialMethod(method_type) || | 3745 DCHECK(!IsSpecialMethod(method_type) || |
| 3758 type == PropertyKind::kMethodProperty); | 3746 type == PropertyKind::kMethodProperty); |
| 3759 | 3747 |
| 3760 if (property == Token::SMI || property == Token::NUMBER) return; | 3748 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3761 | 3749 |
| 3762 if (type == PropertyKind::kValueProperty && IsProto()) { | 3750 if (type == PropertyKind::kValueProperty && IsProto()) { |
| 3763 if (has_seen_proto_) { | 3751 if (has_seen_proto_) { |
| 3764 classifier->RecordExpressionError(this->scanner()->location(), | 3752 this->parser()->classifier()->RecordExpressionError( |
| 3765 MessageTemplate::kDuplicateProto); | 3753 this->scanner()->location(), MessageTemplate::kDuplicateProto); |
| 3766 return; | 3754 return; |
| 3767 } | 3755 } |
| 3768 has_seen_proto_ = true; | 3756 has_seen_proto_ = true; |
| 3769 } | 3757 } |
| 3770 } | 3758 } |
| 3771 | 3759 |
| 3772 template <typename Impl> | 3760 template <typename Impl> |
| 3773 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( | 3761 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( |
| 3774 Token::Value property, PropertyKind type, MethodKind method_type, | 3762 Token::Value property, PropertyKind type, MethodKind method_type, |
| 3775 ExpressionClassifier* classifier, bool* ok) { | 3763 bool* ok) { |
| 3776 DCHECK(type == PropertyKind::kMethodProperty || | 3764 DCHECK(type == PropertyKind::kMethodProperty || |
| 3777 type == PropertyKind::kAccessorProperty); | 3765 type == PropertyKind::kAccessorProperty); |
| 3778 | 3766 |
| 3779 if (property == Token::SMI || property == Token::NUMBER) return; | 3767 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3780 | 3768 |
| 3781 if (IsStaticMethod(method_type)) { | 3769 if (IsStaticMethod(method_type)) { |
| 3782 if (IsPrototype()) { | 3770 if (IsPrototype()) { |
| 3783 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); | 3771 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
| 3784 *ok = false; | 3772 *ok = false; |
| 3785 return; | 3773 return; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3804 has_seen_constructor_ = true; | 3792 has_seen_constructor_ = true; |
| 3805 return; | 3793 return; |
| 3806 } | 3794 } |
| 3807 } | 3795 } |
| 3808 | 3796 |
| 3809 | 3797 |
| 3810 } // namespace internal | 3798 } // namespace internal |
| 3811 } // namespace v8 | 3799 } // namespace v8 |
| 3812 | 3800 |
| 3813 #endif // V8_PARSING_PARSER_BASE_H | 3801 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |