Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: src/parsing/parser-base.h

Issue 2133543003: [parser] report errors for invalid binding patterns in async formal parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixup Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/expression-classifier.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/expression-classifier.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698