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

Side by Side Diff: src/preparser.h

Issue 1178523002: Support rest parameters in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Add test for duplicate formal param detection Created 5 years, 6 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
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_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 UNREACHABLE(); 1521 UNREACHABLE();
1522 } 1522 }
1523 1523
1524 V8_INLINE PreParserStatementList 1524 V8_INLINE PreParserStatementList
1525 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, 1525 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1526 Variable* fvar, Token::Value fvar_init_op, 1526 Variable* fvar, Token::Value fvar_init_op,
1527 FunctionKind kind, bool* ok); 1527 FunctionKind kind, bool* ok);
1528 1528
1529 V8_INLINE void ParseArrowFunctionFormalParameters( 1529 V8_INLINE void ParseArrowFunctionFormalParameters(
1530 Scope* scope, PreParserExpression expression, 1530 Scope* scope, PreParserExpression expression,
1531 const Scanner::Location& params_loc, bool* is_rest, 1531 const Scanner::Location& params_loc, bool* has_rest,
1532 Scanner::Location* duplicate_loc, bool* ok); 1532 Scanner::Location* duplicate_loc, bool* ok);
1533 1533
1534 struct TemplateLiteralState {}; 1534 struct TemplateLiteralState {};
1535 1535
1536 TemplateLiteralState OpenTemplateLiteral(int pos) { 1536 TemplateLiteralState OpenTemplateLiteral(int pos) {
1537 return TemplateLiteralState(); 1537 return TemplateLiteralState();
1538 } 1538 }
1539 void AddTemplateSpan(TemplateLiteralState*, bool) {} 1539 void AddTemplateSpan(TemplateLiteralState*, bool) {}
1540 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} 1540 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
1541 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, 1541 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 1745
1746 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, 1746 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1747 PreParserExpressionList args, 1747 PreParserExpressionList args,
1748 int pos) { 1748 int pos) {
1749 return pre_parser_->factory()->NewCallNew(function, args, pos); 1749 return pre_parser_->factory()->NewCallNew(function, args, pos);
1750 } 1750 }
1751 1751
1752 1752
1753 void PreParserTraits::ParseArrowFunctionFormalParameters( 1753 void PreParserTraits::ParseArrowFunctionFormalParameters(
1754 Scope* scope, PreParserExpression params, 1754 Scope* scope, PreParserExpression params,
1755 const Scanner::Location& params_loc, bool* is_rest, 1755 const Scanner::Location& params_loc, bool* has_rest,
1756 Scanner::Location* duplicate_loc, bool* ok) { 1756 Scanner::Location* duplicate_loc, bool* ok) {
1757 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter 1757 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1758 // lists that are too long. 1758 // lists that are too long.
1759 } 1759 }
1760 1760
1761 1761
1762 PreParserStatementList PreParser::ParseEagerFunctionBody( 1762 PreParserStatementList PreParser::ParseEagerFunctionBody(
1763 PreParserIdentifier function_name, int pos, Variable* fvar, 1763 PreParserIdentifier function_name, int pos, Variable* fvar,
1764 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { 1764 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
1765 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1765 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 classifier->RecordBindingPatternError(scanner()->location(), 2152 classifier->RecordBindingPatternError(scanner()->location(),
2153 MessageTemplate::kUnexpectedToken, 2153 MessageTemplate::kUnexpectedToken,
2154 Token::String(Token::RPAREN)); 2154 Token::String(Token::RPAREN));
2155 Scope* scope = 2155 Scope* scope =
2156 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2156 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2157 scope->set_start_position(beg_pos); 2157 scope->set_start_position(beg_pos);
2158 ExpressionClassifier args_classifier; 2158 ExpressionClassifier args_classifier;
2159 bool has_rest = false; 2159 bool has_rest = false;
2160 result = this->ParseArrowFunctionLiteral(scope, has_rest, 2160 result = this->ParseArrowFunctionLiteral(scope, has_rest,
2161 args_classifier, CHECK_OK); 2161 args_classifier, CHECK_OK);
2162 } else if (allow_harmony_arrow_functions() &&
2163 allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
2164 // (...x) => y
2165 Scope* scope =
2166 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2167 scope->set_start_position(beg_pos);
2168 ExpressionClassifier args_classifier;
2169 const bool has_rest = true;
2170 this->ParseFormalParameter(scope, has_rest, &args_classifier, CHECK_OK);
2171 if (peek() == Token::COMMA) {
2172 ReportMessageAt(scanner()->peek_location(),
2173 MessageTemplate::kParamAfterRest);
2174 *ok = false;
2175 return this->EmptyExpression();
2176 }
2177 Expect(Token::RPAREN, CHECK_OK);
2178 result = this->ParseArrowFunctionLiteral(scope, has_rest,
2179 args_classifier, CHECK_OK);
2162 } else { 2180 } else {
2163 // Heuristically try to detect immediately called functions before 2181 // Heuristically try to detect immediately called functions before
2164 // seeing the call parentheses. 2182 // seeing the call parentheses.
2165 parenthesized_function_ = (peek() == Token::FUNCTION); 2183 parenthesized_function_ = (peek() == Token::FUNCTION);
2166 result = this->ParseExpression(true, classifier, CHECK_OK); 2184 result = this->ParseExpression(true, classifier, CHECK_OK);
2167 Expect(Token::RPAREN, CHECK_OK); 2185 Expect(Token::RPAREN, CHECK_OK);
2168 } 2186 }
2169 break; 2187 break;
2170 2188
2171 case Token::CLASS: { 2189 case Token::CLASS: {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 2250 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2233 // Expression :: 2251 // Expression ::
2234 // AssignmentExpression 2252 // AssignmentExpression
2235 // Expression ',' AssignmentExpression 2253 // Expression ',' AssignmentExpression
2236 2254
2237 ExpressionClassifier binding_classifier; 2255 ExpressionClassifier binding_classifier;
2238 ExpressionT result = 2256 ExpressionT result =
2239 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2257 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2240 classifier->Accumulate(binding_classifier, 2258 classifier->Accumulate(binding_classifier,
2241 ExpressionClassifier::AllProductions); 2259 ExpressionClassifier::AllProductions);
2242 while (peek() == Token::COMMA) { 2260 bool seen_rest = false;
2243 Expect(Token::COMMA, CHECK_OK); 2261 while (Check(Token::COMMA)) {
2262 if (seen_rest) {
2263 // Seeing the first rest param meant that this form wasn't a valid
2264 // expression or pattern. Now we know it's not a valid formal parameter
2265 // list either.
2266 ReportMessageAt(scanner()->peek_location(),
rossberg 2015/06/10 13:43:53 Nit: Should this really be an eager error here? It
caitp (gmail) 2015/06/10 14:30:49 We should mark it in the expression classifier ins
2267 MessageTemplate::kParamAfterRest);
2268 *ok = false;
2269 return this->EmptyExpression();
2270 }
2271 if (allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
2272 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2273 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2274 // valid expression or binding pattern.
2275 ExpressionUnexpectedToken(classifier);
2276 BindingPatternUnexpectedToken(classifier);
2277 seen_rest = true;
2278 }
2244 int pos = position(); 2279 int pos = position();
2245 ExpressionT right = this->ParseAssignmentExpression( 2280 ExpressionT right = this->ParseAssignmentExpression(
2246 accept_IN, &binding_classifier, CHECK_OK); 2281 accept_IN, &binding_classifier, CHECK_OK);
2282 if (seen_rest) right = factory()->NewSpread(right, pos);
2247 classifier->Accumulate(binding_classifier, 2283 classifier->Accumulate(binding_classifier,
2248 ExpressionClassifier::AllProductions); 2284 ExpressionClassifier::AllProductions);
2249 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2285 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2250 } 2286 }
2251 return result; 2287 return result;
2252 } 2288 }
2253 2289
2254 2290
2255 template <class Traits> 2291 template <class Traits>
2256 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 2292 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 if (fni_ != NULL) fni_->Enter(); 2700 if (fni_ != NULL) fni_->Enter();
2665 ParserBase<Traits>::Checkpoint checkpoint(this); 2701 ParserBase<Traits>::Checkpoint checkpoint(this);
2666 ExpressionClassifier arrow_formals_classifier; 2702 ExpressionClassifier arrow_formals_classifier;
2667 if (peek() != Token::LPAREN) { 2703 if (peek() != Token::LPAREN) {
2668 // The expression we are going to read is not a parenthesized arrow function 2704 // The expression we are going to read is not a parenthesized arrow function
2669 // formal parameter list. 2705 // formal parameter list.
2670 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); 2706 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2671 } 2707 }
2672 ExpressionT expression = this->ParseConditionalExpression( 2708 ExpressionT expression = this->ParseConditionalExpression(
2673 accept_IN, &arrow_formals_classifier, CHECK_OK); 2709 accept_IN, &arrow_formals_classifier, CHECK_OK);
2674 classifier->Accumulate(arrow_formals_classifier);
2675 2710
2676 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { 2711 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2677 checkpoint.Restore(); 2712 checkpoint.Restore();
2678 BindingPatternUnexpectedToken(classifier); 2713 BindingPatternUnexpectedToken(classifier);
2679 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2714 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2680 CHECK_OK); 2715 CHECK_OK);
2681 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); 2716 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
2682 bool has_rest = false;
2683 Scope* scope = 2717 Scope* scope =
2684 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2718 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2685 scope->set_start_position(lhs_location.beg_pos); 2719 scope->set_start_position(lhs_location.beg_pos);
2686 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2720 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2721 bool has_rest = false;
2687 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, 2722 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
2688 &duplicate_loc, CHECK_OK); 2723 &duplicate_loc, CHECK_OK);
2689 if (duplicate_loc.IsValid()) { 2724 if (duplicate_loc.IsValid()) {
2690 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2725 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2691 duplicate_loc); 2726 duplicate_loc);
2692 } 2727 }
2693 expression = this->ParseArrowFunctionLiteral( 2728 expression = this->ParseArrowFunctionLiteral(
2694 scope, has_rest, arrow_formals_classifier, CHECK_OK); 2729 scope, has_rest, arrow_formals_classifier, CHECK_OK);
2695 return expression; 2730 return expression;
2696 } 2731 }
2697 2732
2698 // "expression" was not itself an arrow function parameter list, but it might 2733 // "expression" was not itself an arrow function parameter list, but it might
2699 // form part of one. Propagate speculative formal parameter error locations. 2734 // form part of one. Propagate speculative formal parameter error locations.
2700 classifier->Accumulate(arrow_formals_classifier, 2735 classifier->Accumulate(arrow_formals_classifier,
2701 ExpressionClassifier::FormalParametersProductions); 2736 ExpressionClassifier::StandardProductions |
2737 ExpressionClassifier::FormalParametersProductions);
2702 2738
2703 if (!Token::IsAssignmentOp(peek())) { 2739 if (!Token::IsAssignmentOp(peek())) {
2704 if (fni_ != NULL) fni_->Leave(); 2740 if (fni_ != NULL) fni_->Leave();
2705 // Parsed conditional expression only (no assignment). 2741 // Parsed conditional expression only (no assignment).
2706 return expression; 2742 return expression;
2707 } 2743 }
2708 2744
2709 if (!allow_harmony_destructuring()) { 2745 if (!allow_harmony_destructuring()) {
2710 BindingPatternUnexpectedToken(classifier); 2746 BindingPatternUnexpectedToken(classifier);
2711 } 2747 }
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 *ok = false; 3846 *ok = false;
3811 return; 3847 return;
3812 } 3848 }
3813 has_seen_constructor_ = true; 3849 has_seen_constructor_ = true;
3814 return; 3850 return;
3815 } 3851 }
3816 } 3852 }
3817 } } // v8::internal 3853 } } // v8::internal
3818 3854
3819 #endif // V8_PREPARSER_H 3855 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698