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 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 |