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 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
890 } | 890 } |
891 | 891 |
892 bool IsValidArrowFormalParametersStart(Token::Value token) { | 892 bool IsValidArrowFormalParametersStart(Token::Value token) { |
893 return is_any_identifier(token) || token == Token::LPAREN; | 893 return is_any_identifier(token) || token == Token::LPAREN; |
894 } | 894 } |
895 | 895 |
896 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 896 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
897 ExpressionT expr, | 897 ExpressionT expr, |
898 bool parenthesized_formals, bool is_async, | 898 bool parenthesized_formals, bool is_async, |
899 bool* ok) { | 899 bool* ok) { |
900 if (classifier->is_valid_binding_pattern()) { | 900 if (!is_async && classifier->is_valid_binding_pattern() && |
901 !this->IsIdentifier(expr)) { | |
nickie
2016/07/12 12:27:13
Merging the conditions and removing the "else" cha
| |
901 // A simple arrow formal parameter: IDENTIFIER => BODY. | 902 // A simple arrow formal parameter: IDENTIFIER => BODY. |
902 if (!this->IsIdentifier(expr)) { | 903 Traits::ReportMessageAt(scanner()->location(), |
903 Traits::ReportMessageAt(scanner()->location(), | 904 MessageTemplate::kUnexpectedToken, |
904 MessageTemplate::kUnexpectedToken, | 905 Token::String(scanner()->current_token())); |
905 Token::String(scanner()->current_token())); | 906 *ok = false; |
906 *ok = false; | 907 return; |
907 } | 908 } |
908 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 909 |
910 if (!classifier->is_valid_arrow_formal_parameters()) { | |
909 // If after parsing the expr, we see an error but the expression is | 911 // If after parsing the expr, we see an error but the expression is |
910 // neither a valid binding pattern nor a valid parenthesized formal | 912 // neither a valid binding pattern nor a valid parenthesized formal |
911 // parameter list, show the "arrow formal parameters" error if the formals | 913 // parameter list, show the "arrow formal parameters" error if the formals |
912 // started with a parenthesis, and the binding pattern error otherwise. | 914 // started with a parenthesis, and the binding pattern error otherwise. |
913 const typename ExpressionClassifier::Error& error = | 915 const typename ExpressionClassifier::Error& error = |
914 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 916 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
915 : classifier->binding_pattern_error(); | 917 : classifier->binding_pattern_error(); |
916 ReportClassifierError(error); | 918 ReportClassifierError(error); |
917 *ok = false; | 919 *ok = false; |
920 return; | |
918 } | 921 } |
919 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | 922 |
920 const typename ExpressionClassifier::Error& error = | 923 if (is_async) { |
921 classifier->async_arrow_formal_parameters_error(); | 924 if (!classifier->is_valid_async_arrow_formal_parameters()) { |
922 ReportClassifierError(error); | 925 const typename ExpressionClassifier::Error& error = |
923 *ok = false; | 926 classifier->async_arrow_formal_parameters_error(); |
927 ReportClassifierError(error); | |
928 *ok = false; | |
929 return; | |
930 } | |
931 if (!classifier->is_valid_binding_pattern()) { | |
932 ReportClassifierError(classifier->binding_pattern_error()); | |
933 *ok = false; | |
934 return; | |
935 } | |
924 } | 936 } |
925 } | 937 } |
926 | 938 |
927 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 939 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
928 if (!classifier->is_valid_let_pattern()) { | 940 if (!classifier->is_valid_let_pattern()) { |
929 ReportClassifierError(classifier->let_pattern_error()); | 941 ReportClassifierError(classifier->let_pattern_error()); |
930 *ok = false; | 942 *ok = false; |
931 } | 943 } |
932 } | 944 } |
933 | 945 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1017 Scanner::Location* first_spread_pos, bool maybe_arrow, | 1029 Scanner::Location* first_spread_pos, bool maybe_arrow, |
1018 ExpressionClassifier* classifier, bool* ok); | 1030 ExpressionClassifier* classifier, bool* ok); |
1019 typename Traits::Type::ExpressionList ParseArguments( | 1031 typename Traits::Type::ExpressionList ParseArguments( |
1020 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1032 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
1021 bool* ok) { | 1033 bool* ok) { |
1022 return ParseArguments(first_spread_pos, false, classifier, ok); | 1034 return ParseArguments(first_spread_pos, false, classifier, ok); |
1023 } | 1035 } |
1024 | 1036 |
1025 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1037 ExpressionT ParseAssignmentExpression(bool accept_IN, |
1026 ExpressionClassifier* classifier, | 1038 ExpressionClassifier* classifier, |
1027 bool* ok); | 1039 bool merge_patterns, bool* ok); |
1040 ExpressionT ParseAssignmentExpression(bool accept_IN, | |
1041 ExpressionClassifier* classifier, | |
1042 bool* ok) { | |
1043 return ParseAssignmentExpression(accept_IN, classifier, false, ok); | |
1044 } | |
1028 ExpressionT ParseYieldExpression(bool accept_IN, | 1045 ExpressionT ParseYieldExpression(bool accept_IN, |
1029 ExpressionClassifier* classifier, bool* ok); | 1046 ExpressionClassifier* classifier, bool* ok); |
1030 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 1047 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
1031 bool* ok); | 1048 bool* ok); |
1032 ExpressionT ParseConditionalExpression(bool accept_IN, | 1049 ExpressionT ParseConditionalExpression(bool accept_IN, |
1033 ExpressionClassifier* classifier, | 1050 ExpressionClassifier* classifier, |
1034 bool* ok); | 1051 bool* ok); |
1035 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1052 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
1036 ExpressionClassifier* classifier, bool* ok); | 1053 ExpressionClassifier* classifier, bool* ok); |
1037 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 1054 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2165 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2182 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2166 bool done = (peek() == Token::RPAREN); | 2183 bool done = (peek() == Token::RPAREN); |
2167 bool was_unspread = false; | 2184 bool was_unspread = false; |
2168 int unspread_sequences_count = 0; | 2185 int unspread_sequences_count = 0; |
2169 while (!done) { | 2186 while (!done) { |
2170 int start_pos = peek_position(); | 2187 int start_pos = peek_position(); |
2171 bool is_spread = Check(Token::ELLIPSIS); | 2188 bool is_spread = Check(Token::ELLIPSIS); |
2172 int expr_pos = peek_position(); | 2189 int expr_pos = peek_position(); |
2173 | 2190 |
2174 ExpressionT argument = this->ParseAssignmentExpression( | 2191 ExpressionT argument = this->ParseAssignmentExpression( |
2175 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2192 true, classifier, maybe_arrow, CHECK_OK_CUSTOM(NullExpressionList)); |
2176 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2193 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
2177 if (!maybe_arrow) { | 2194 if (!maybe_arrow) { |
2178 Traits::RewriteNonPattern(classifier, | 2195 Traits::RewriteNonPattern(classifier, |
2179 CHECK_OK_CUSTOM(NullExpressionList)); | 2196 CHECK_OK_CUSTOM(NullExpressionList)); |
2180 } | 2197 } |
2181 if (is_spread) { | 2198 if (is_spread) { |
2182 if (!spread_arg.IsValid()) { | 2199 if (!spread_arg.IsValid()) { |
2183 spread_arg.beg_pos = start_pos; | 2200 spread_arg.beg_pos = start_pos; |
2184 spread_arg.end_pos = peek_position(); | 2201 spread_arg.end_pos = peek_position(); |
2185 } | 2202 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2232 } | 2249 } |
2233 | 2250 |
2234 return result; | 2251 return result; |
2235 } | 2252 } |
2236 | 2253 |
2237 // Precedence = 2 | 2254 // Precedence = 2 |
2238 template <class Traits> | 2255 template <class Traits> |
2239 typename ParserBase<Traits>::ExpressionT | 2256 typename ParserBase<Traits>::ExpressionT |
2240 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2257 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
2241 ExpressionClassifier* classifier, | 2258 ExpressionClassifier* classifier, |
2242 bool* ok) { | 2259 bool merge_patterns, bool* ok) { |
2243 // AssignmentExpression :: | 2260 // AssignmentExpression :: |
2244 // ConditionalExpression | 2261 // ConditionalExpression |
2245 // ArrowFunction | 2262 // ArrowFunction |
2246 // YieldExpression | 2263 // YieldExpression |
2247 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2264 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2248 bool is_destructuring_assignment = false; | 2265 bool is_destructuring_assignment = false; |
2249 int lhs_beg_pos = peek_position(); | 2266 int lhs_beg_pos = peek_position(); |
2250 | 2267 |
2251 if (peek() == Token::YIELD && is_generator()) { | 2268 if (peek() == Token::YIELD && is_generator()) { |
2252 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2269 return this->ParseYieldExpression(accept_IN, classifier, ok); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2324 return expression; | 2341 return expression; |
2325 } | 2342 } |
2326 | 2343 |
2327 if (this->IsValidReferenceExpression(expression)) { | 2344 if (this->IsValidReferenceExpression(expression)) { |
2328 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2345 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
2329 } | 2346 } |
2330 | 2347 |
2331 // "expression" was not itself an arrow function parameter list, but it might | 2348 // "expression" was not itself an arrow function parameter list, but it might |
2332 // form part of one. Propagate speculative formal parameter error locations. | 2349 // form part of one. Propagate speculative formal parameter error locations. |
2333 // Do not merge pending non-pattern expressions yet! | 2350 // Do not merge pending non-pattern expressions yet! |
2334 classifier->Accumulate( | 2351 int productions_to_propagate = |
2335 &arrow_formals_classifier, | |
2336 ExpressionClassifier::StandardProductions | | 2352 ExpressionClassifier::StandardProductions | |
2337 ExpressionClassifier::FormalParametersProductions | | 2353 ExpressionClassifier::FormalParametersProductions | |
2338 ExpressionClassifier::CoverInitializedNameProduction | | 2354 ExpressionClassifier::CoverInitializedNameProduction | |
2339 ExpressionClassifier::AsyncArrowFormalParametersProduction | | 2355 ExpressionClassifier::AsyncArrowFormalParametersProduction | |
2340 ExpressionClassifier::AsyncBindingPatternProduction, | 2356 ExpressionClassifier::AsyncBindingPatternProduction; |
2341 false); | 2357 if (merge_patterns) { |
2358 productions_to_propagate |= ExpressionClassifier::BindingPatternProduction; | |
2359 } | |
2360 | |
2361 classifier->Accumulate(&arrow_formals_classifier, productions_to_propagate, | |
2362 false); | |
2342 | 2363 |
2343 if (!Token::IsAssignmentOp(peek())) { | 2364 if (!Token::IsAssignmentOp(peek())) { |
2344 // Parsed conditional expression only (no assignment). | 2365 // Parsed conditional expression only (no assignment). |
2345 // Now pending non-pattern expressions must be merged. | 2366 // Now pending non-pattern expressions must be merged. |
2346 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2367 classifier->MergeNonPatterns(&arrow_formals_classifier); |
2347 return expression; | 2368 return expression; |
2348 } | 2369 } |
2349 | 2370 |
2350 // Now pending non-pattern expressions must be discarded. | 2371 // Now pending non-pattern expressions must be discarded. |
2351 arrow_formals_classifier.Discard(); | 2372 arrow_formals_classifier.Discard(); |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2798 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2819 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2799 result = factory()->NewProperty(result, index, pos); | 2820 result = factory()->NewProperty(result, index, pos); |
2800 Expect(Token::RBRACK, CHECK_OK); | 2821 Expect(Token::RBRACK, CHECK_OK); |
2801 break; | 2822 break; |
2802 } | 2823 } |
2803 | 2824 |
2804 case Token::LPAREN: { | 2825 case Token::LPAREN: { |
2805 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2826 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2806 int pos; | 2827 int pos; |
2807 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2828 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2808 BindingPatternUnexpectedToken(classifier); | 2829 |
2830 const char* arg; | |
2831 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | |
2832 Scanner::Location location = scanner()->peek_location(); | |
2833 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | |
2834 | |
2835 if (!is_async) { | |
2836 classifier->RecordBindingPatternError(location, message, arg); | |
2837 } | |
2838 | |
2809 if (scanner()->current_token() == Token::IDENTIFIER || | 2839 if (scanner()->current_token() == Token::IDENTIFIER || |
2810 scanner()->current_token() == Token::SUPER || | 2840 scanner()->current_token() == Token::SUPER || |
2811 scanner()->current_token() == Token::ASYNC) { | 2841 scanner()->current_token() == Token::ASYNC) { |
2812 // For call of an identifier we want to report position of | 2842 // For call of an identifier we want to report position of |
2813 // the identifier as position of the call in the stack trace. | 2843 // the identifier as position of the call in the stack trace. |
2814 pos = position(); | 2844 pos = position(); |
2815 } else { | 2845 } else { |
2816 // For other kinds of calls we record position of the parenthesis as | 2846 // For other kinds of calls we record position of the parenthesis as |
2817 // position of the call. Note that this is extremely important for | 2847 // position of the call. Note that this is extremely important for |
2818 // expressions of the form function(){...}() for which call position | 2848 // expressions of the form function(){...}() for which call position |
(...skipping 11 matching lines...) Expand all Loading... | |
2830 typename Traits::Type::ExpressionList args = | 2860 typename Traits::Type::ExpressionList args = |
2831 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); | 2861 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); |
2832 | 2862 |
2833 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { | 2863 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { |
2834 if (args->length()) { | 2864 if (args->length()) { |
2835 // async ( Arguments ) => ... | 2865 // async ( Arguments ) => ... |
2836 return Traits::ExpressionListToExpression(args); | 2866 return Traits::ExpressionListToExpression(args); |
2837 } | 2867 } |
2838 // async () => ... | 2868 // async () => ... |
2839 return factory()->NewEmptyParentheses(pos); | 2869 return factory()->NewEmptyParentheses(pos); |
2870 } else { | |
2871 classifier->ReplaceBindingPatternError(location, message, arg); | |
2840 } | 2872 } |
2841 | 2873 |
2842 ArrowFormalParametersUnexpectedToken(classifier); | 2874 ArrowFormalParametersUnexpectedToken(classifier); |
2843 | 2875 |
2844 // Keep track of eval() calls since they disable all local variable | 2876 // Keep track of eval() calls since they disable all local variable |
2845 // optimizations. | 2877 // optimizations. |
2846 // The calls that need special treatment are the | 2878 // The calls that need special treatment are the |
2847 // direct eval calls. These calls are all of the form eval(...), with | 2879 // direct eval calls. These calls are all of the form eval(...), with |
2848 // no explicit receiver. | 2880 // no explicit receiver. |
2849 // These calls are marked as potentially direct eval calls. Whether | 2881 // These calls are marked as potentially direct eval calls. Whether |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3651 has_seen_constructor_ = true; | 3683 has_seen_constructor_ = true; |
3652 return; | 3684 return; |
3653 } | 3685 } |
3654 } | 3686 } |
3655 | 3687 |
3656 | 3688 |
3657 } // namespace internal | 3689 } // namespace internal |
3658 } // namespace v8 | 3690 } // namespace v8 |
3659 | 3691 |
3660 #endif // V8_PARSING_PARSER_BASE_H | 3692 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |