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 // A simple arrow formal parameter: IDENTIFIER => BODY. | 901 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 902 if (!this->IsIdentifier(expr)) { | 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 } | 907 } |
| 908 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 908 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
| 909 // If after parsing the expr, we see an error but the expression is | 909 // If after parsing the expr, we see an error but the expression is |
| 910 // neither a valid binding pattern nor a valid parenthesized formal | 910 // neither a valid binding pattern nor a valid parenthesized formal |
| 911 // parameter list, show the "arrow formal parameters" error if the formals | 911 // parameter list, show the "arrow formal parameters" error if the formals |
| 912 // started with a parenthesis, and the binding pattern error otherwise. | 912 // started with a parenthesis, and the binding pattern error otherwise. |
| 913 const typename ExpressionClassifier::Error& error = | 913 const typename ExpressionClassifier::Error& error = |
| 914 parenthesized_formals ? classifier->arrow_formal_parameters_error() | 914 parenthesized_formals ? classifier->arrow_formal_parameters_error() |
| 915 : classifier->binding_pattern_error(); | 915 : classifier->binding_pattern_error(); |
| 916 ReportClassifierError(error); | 916 ReportClassifierError(error); |
| 917 *ok = false; | 917 *ok = false; |
| 918 } | 918 } |
| 919 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) { | 919 if (is_async) { |
| 920 const typename ExpressionClassifier::Error& error = | 920 if (!classifier->is_valid_async_arrow_formal_parameters()) { |
| 921 classifier->async_arrow_formal_parameters_error(); | 921 const typename ExpressionClassifier::Error& error = |
| 922 ReportClassifierError(error); | 922 classifier->async_arrow_formal_parameters_error(); |
| 923 *ok = false; | 923 ReportClassifierError(error); |
| 924 *ok = false; | |
| 925 } | |
| 926 if (!classifier->is_valid_binding_pattern()) { | |
|
nickie
2016/07/11 13:19:50
Is it possible that we have both !is_valid_async_a
caitp
2016/07/11 13:24:42
Yeah, this is true --- the WebKit style is to just
nickie
2016/07/11 13:32:18
Yes, I think that adding return statements is a be
| |
| 927 ReportClassifierError(classifier->binding_pattern_error()); | |
| 928 *ok = false; | |
| 929 } | |
| 924 } | 930 } |
| 925 } | 931 } |
| 926 | 932 |
| 927 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 933 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
| 928 if (!classifier->is_valid_let_pattern()) { | 934 if (!classifier->is_valid_let_pattern()) { |
| 929 ReportClassifierError(classifier->let_pattern_error()); | 935 ReportClassifierError(classifier->let_pattern_error()); |
| 930 *ok = false; | 936 *ok = false; |
| 931 } | 937 } |
| 932 } | 938 } |
| 933 | 939 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1017 Scanner::Location* first_spread_pos, bool maybe_arrow, | 1023 Scanner::Location* first_spread_pos, bool maybe_arrow, |
| 1018 ExpressionClassifier* classifier, bool* ok); | 1024 ExpressionClassifier* classifier, bool* ok); |
| 1019 typename Traits::Type::ExpressionList ParseArguments( | 1025 typename Traits::Type::ExpressionList ParseArguments( |
| 1020 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 1026 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 1021 bool* ok) { | 1027 bool* ok) { |
| 1022 return ParseArguments(first_spread_pos, false, classifier, ok); | 1028 return ParseArguments(first_spread_pos, false, classifier, ok); |
| 1023 } | 1029 } |
| 1024 | 1030 |
| 1025 ExpressionT ParseAssignmentExpression(bool accept_IN, | 1031 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 1026 ExpressionClassifier* classifier, | 1032 ExpressionClassifier* classifier, |
| 1027 bool* ok); | 1033 bool marge_partterns, bool* ok); |
|
nickie
2016/07/11 13:19:50
Unless I'm missing the pun, "merge_patterns" :-)
caitp
2016/07/11 13:24:42
just a typo, will fix
| |
| 1034 ExpressionT ParseAssignmentExpression(bool accept_IN, | |
| 1035 ExpressionClassifier* classifier, | |
| 1036 bool* ok) { | |
| 1037 return ParseAssignmentExpression(accept_IN, classifier, false, ok); | |
| 1038 } | |
| 1028 ExpressionT ParseYieldExpression(bool accept_IN, | 1039 ExpressionT ParseYieldExpression(bool accept_IN, |
| 1029 ExpressionClassifier* classifier, bool* ok); | 1040 ExpressionClassifier* classifier, bool* ok); |
| 1030 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | 1041 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
| 1031 bool* ok); | 1042 bool* ok); |
| 1032 ExpressionT ParseConditionalExpression(bool accept_IN, | 1043 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 1033 ExpressionClassifier* classifier, | 1044 ExpressionClassifier* classifier, |
| 1034 bool* ok); | 1045 bool* ok); |
| 1035 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1046 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 1036 ExpressionClassifier* classifier, bool* ok); | 1047 ExpressionClassifier* classifier, bool* ok); |
| 1037 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 1048 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)); | 2176 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2166 bool done = (peek() == Token::RPAREN); | 2177 bool done = (peek() == Token::RPAREN); |
| 2167 bool was_unspread = false; | 2178 bool was_unspread = false; |
| 2168 int unspread_sequences_count = 0; | 2179 int unspread_sequences_count = 0; |
| 2169 while (!done) { | 2180 while (!done) { |
| 2170 int start_pos = peek_position(); | 2181 int start_pos = peek_position(); |
| 2171 bool is_spread = Check(Token::ELLIPSIS); | 2182 bool is_spread = Check(Token::ELLIPSIS); |
| 2172 int expr_pos = peek_position(); | 2183 int expr_pos = peek_position(); |
| 2173 | 2184 |
| 2174 ExpressionT argument = this->ParseAssignmentExpression( | 2185 ExpressionT argument = this->ParseAssignmentExpression( |
| 2175 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2186 true, classifier, maybe_arrow, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2176 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2187 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2177 if (!maybe_arrow) { | 2188 if (!maybe_arrow) { |
| 2178 Traits::RewriteNonPattern(classifier, | 2189 Traits::RewriteNonPattern(classifier, |
| 2179 CHECK_OK_CUSTOM(NullExpressionList)); | 2190 CHECK_OK_CUSTOM(NullExpressionList)); |
| 2180 } | 2191 } |
| 2181 if (is_spread) { | 2192 if (is_spread) { |
| 2182 if (!spread_arg.IsValid()) { | 2193 if (!spread_arg.IsValid()) { |
| 2183 spread_arg.beg_pos = start_pos; | 2194 spread_arg.beg_pos = start_pos; |
| 2184 spread_arg.end_pos = peek_position(); | 2195 spread_arg.end_pos = peek_position(); |
| 2185 } | 2196 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2232 } | 2243 } |
| 2233 | 2244 |
| 2234 return result; | 2245 return result; |
| 2235 } | 2246 } |
| 2236 | 2247 |
| 2237 // Precedence = 2 | 2248 // Precedence = 2 |
| 2238 template <class Traits> | 2249 template <class Traits> |
| 2239 typename ParserBase<Traits>::ExpressionT | 2250 typename ParserBase<Traits>::ExpressionT |
| 2240 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2251 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| 2241 ExpressionClassifier* classifier, | 2252 ExpressionClassifier* classifier, |
| 2242 bool* ok) { | 2253 bool merge_patterns, bool* ok) { |
| 2243 // AssignmentExpression :: | 2254 // AssignmentExpression :: |
| 2244 // ConditionalExpression | 2255 // ConditionalExpression |
| 2245 // ArrowFunction | 2256 // ArrowFunction |
| 2246 // YieldExpression | 2257 // YieldExpression |
| 2247 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2258 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2248 bool is_destructuring_assignment = false; | 2259 bool is_destructuring_assignment = false; |
| 2249 int lhs_beg_pos = peek_position(); | 2260 int lhs_beg_pos = peek_position(); |
| 2250 | 2261 |
| 2251 if (peek() == Token::YIELD && is_generator()) { | 2262 if (peek() == Token::YIELD && is_generator()) { |
| 2252 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2263 return this->ParseYieldExpression(accept_IN, classifier, ok); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2324 return expression; | 2335 return expression; |
| 2325 } | 2336 } |
| 2326 | 2337 |
| 2327 if (this->IsValidReferenceExpression(expression)) { | 2338 if (this->IsValidReferenceExpression(expression)) { |
| 2328 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2339 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
| 2329 } | 2340 } |
| 2330 | 2341 |
| 2331 // "expression" was not itself an arrow function parameter list, but it might | 2342 // "expression" was not itself an arrow function parameter list, but it might |
| 2332 // form part of one. Propagate speculative formal parameter error locations. | 2343 // form part of one. Propagate speculative formal parameter error locations. |
| 2333 // Do not merge pending non-pattern expressions yet! | 2344 // Do not merge pending non-pattern expressions yet! |
| 2334 classifier->Accumulate( | 2345 int productions_to_propagate = |
| 2335 &arrow_formals_classifier, | |
| 2336 ExpressionClassifier::StandardProductions | | 2346 ExpressionClassifier::StandardProductions | |
| 2337 ExpressionClassifier::FormalParametersProductions | | 2347 ExpressionClassifier::FormalParametersProductions | |
| 2338 ExpressionClassifier::CoverInitializedNameProduction | | 2348 ExpressionClassifier::CoverInitializedNameProduction | |
| 2339 ExpressionClassifier::AsyncArrowFormalParametersProduction | | 2349 ExpressionClassifier::AsyncArrowFormalParametersProduction | |
| 2340 ExpressionClassifier::AsyncBindingPatternProduction, | 2350 ExpressionClassifier::AsyncBindingPatternProduction; |
| 2341 false); | 2351 if (merge_patterns) { |
|
Dan Ehrenberg
2016/07/11 23:22:47
I find this logic of when to merge_patterns to be
caitp
2016/07/11 23:32:24
That doesn't really work, because then we could fa
Dan Ehrenberg
2016/07/11 23:37:57
I don't understand the issue. The binding pattern
nickie
2016/07/12 13:11:53
I tried the following with Dan's patch and they se
caitp
2016/07/12 14:38:30
What are either of you even talking about? Using p
| |
| 2352 productions_to_propagate |= ExpressionClassifier::BindingPatternProduction; | |
| 2353 } | |
| 2354 | |
| 2355 classifier->Accumulate(&arrow_formals_classifier, productions_to_propagate, | |
| 2356 false); | |
| 2342 | 2357 |
| 2343 if (!Token::IsAssignmentOp(peek())) { | 2358 if (!Token::IsAssignmentOp(peek())) { |
| 2344 // Parsed conditional expression only (no assignment). | 2359 // Parsed conditional expression only (no assignment). |
| 2345 // Now pending non-pattern expressions must be merged. | 2360 // Now pending non-pattern expressions must be merged. |
| 2346 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2361 classifier->MergeNonPatterns(&arrow_formals_classifier); |
| 2347 return expression; | 2362 return expression; |
| 2348 } | 2363 } |
| 2349 | 2364 |
| 2350 // Now pending non-pattern expressions must be discarded. | 2365 // Now pending non-pattern expressions must be discarded. |
| 2351 arrow_formals_classifier.Discard(); | 2366 arrow_formals_classifier.Discard(); |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2798 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2813 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2799 result = factory()->NewProperty(result, index, pos); | 2814 result = factory()->NewProperty(result, index, pos); |
| 2800 Expect(Token::RBRACK, CHECK_OK); | 2815 Expect(Token::RBRACK, CHECK_OK); |
| 2801 break; | 2816 break; |
| 2802 } | 2817 } |
| 2803 | 2818 |
| 2804 case Token::LPAREN: { | 2819 case Token::LPAREN: { |
| 2805 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2820 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2806 int pos; | 2821 int pos; |
| 2807 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2822 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2808 BindingPatternUnexpectedToken(classifier); | 2823 |
| 2824 const char* arg; | |
| 2825 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | |
| 2826 Scanner::Location location = scanner()->peek_location(); | |
| 2827 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | |
| 2828 | |
| 2829 if (!is_async) { | |
| 2830 classifier->RecordBindingPatternError(location, message, arg); | |
| 2831 } | |
| 2832 | |
| 2809 if (scanner()->current_token() == Token::IDENTIFIER || | 2833 if (scanner()->current_token() == Token::IDENTIFIER || |
| 2810 scanner()->current_token() == Token::SUPER || | 2834 scanner()->current_token() == Token::SUPER || |
| 2811 scanner()->current_token() == Token::ASYNC) { | 2835 scanner()->current_token() == Token::ASYNC) { |
| 2812 // For call of an identifier we want to report position of | 2836 // For call of an identifier we want to report position of |
| 2813 // the identifier as position of the call in the stack trace. | 2837 // the identifier as position of the call in the stack trace. |
| 2814 pos = position(); | 2838 pos = position(); |
| 2815 } else { | 2839 } else { |
| 2816 // For other kinds of calls we record position of the parenthesis as | 2840 // For other kinds of calls we record position of the parenthesis as |
| 2817 // position of the call. Note that this is extremely important for | 2841 // position of the call. Note that this is extremely important for |
| 2818 // expressions of the form function(){...}() for which call position | 2842 // expressions of the form function(){...}() for which call position |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2830 typename Traits::Type::ExpressionList args = | 2854 typename Traits::Type::ExpressionList args = |
| 2831 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); | 2855 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK); |
| 2832 | 2856 |
| 2833 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { | 2857 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) { |
| 2834 if (args->length()) { | 2858 if (args->length()) { |
| 2835 // async ( Arguments ) => ... | 2859 // async ( Arguments ) => ... |
| 2836 return Traits::ExpressionListToExpression(args); | 2860 return Traits::ExpressionListToExpression(args); |
| 2837 } | 2861 } |
| 2838 // async () => ... | 2862 // async () => ... |
| 2839 return factory()->NewEmptyParentheses(pos); | 2863 return factory()->NewEmptyParentheses(pos); |
| 2864 } else { | |
| 2865 classifier->ReplaceBindingPatternError(location, message, arg); | |
|
Dan Ehrenberg
2016/07/11 23:22:47
I don't understand why this case is added when we'
caitp
2016/07/11 23:32:24
ArrowFormalParameters don't really matter for asyn
Dan Ehrenberg
2016/07/11 23:37:57
Could you write a test for it?
| |
| 2840 } | 2866 } |
| 2841 | 2867 |
| 2842 ArrowFormalParametersUnexpectedToken(classifier); | 2868 ArrowFormalParametersUnexpectedToken(classifier); |
| 2843 | 2869 |
| 2844 // Keep track of eval() calls since they disable all local variable | 2870 // Keep track of eval() calls since they disable all local variable |
| 2845 // optimizations. | 2871 // optimizations. |
| 2846 // The calls that need special treatment are the | 2872 // The calls that need special treatment are the |
| 2847 // direct eval calls. These calls are all of the form eval(...), with | 2873 // direct eval calls. These calls are all of the form eval(...), with |
| 2848 // no explicit receiver. | 2874 // no explicit receiver. |
| 2849 // These calls are marked as potentially direct eval calls. Whether | 2875 // 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; | 3677 has_seen_constructor_ = true; |
| 3652 return; | 3678 return; |
| 3653 } | 3679 } |
| 3654 } | 3680 } |
| 3655 | 3681 |
| 3656 | 3682 |
| 3657 } // namespace internal | 3683 } // namespace internal |
| 3658 } // namespace v8 | 3684 } // namespace v8 |
| 3659 | 3685 |
| 3660 #endif // V8_PARSING_PARSER_BASE_H | 3686 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |