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