| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 263e16aab8910925dec24d3ac121710344fb3929..e4a007841af798d761c6ab92d45c71cd15af5d2c 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -1528,7 +1528,7 @@ class PreParserTraits {
|
|
|
| V8_INLINE void ParseArrowFunctionFormalParameters(
|
| Scope* scope, PreParserExpression expression,
|
| - const Scanner::Location& params_loc, bool* is_rest,
|
| + const Scanner::Location& params_loc, bool has_rest,
|
| Scanner::Location* duplicate_loc, bool* ok);
|
|
|
| struct TemplateLiteralState {};
|
| @@ -1752,7 +1752,7 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
|
|
|
| void PreParserTraits::ParseArrowFunctionFormalParameters(
|
| Scope* scope, PreParserExpression params,
|
| - const Scanner::Location& params_loc, bool* is_rest,
|
| + const Scanner::Location& params_loc, bool has_rest,
|
| Scanner::Location* duplicate_loc, bool* ok) {
|
| // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
|
| // lists that are too long.
|
| @@ -2159,6 +2159,24 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| bool has_rest = false;
|
| result = this->ParseArrowFunctionLiteral(scope, has_rest,
|
| args_classifier, CHECK_OK);
|
| + } else if (allow_harmony_arrow_functions() &&
|
| + allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
|
| + // (...x) => y
|
| + Scope* scope =
|
| + this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
|
| + scope->set_start_position(beg_pos);
|
| + ExpressionClassifier args_classifier;
|
| + const bool has_rest = true;
|
| + this->ParseFormalParameter(scope, has_rest, &args_classifier, CHECK_OK);
|
| + if (peek() == Token::COMMA) {
|
| + ReportMessageAt(scanner()->peek_location(),
|
| + MessageTemplate::kParamAfterRest);
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| + }
|
| + Expect(Token::RPAREN, CHECK_OK);
|
| + result = this->ParseArrowFunctionLiteral(scope, has_rest,
|
| + args_classifier, CHECK_OK);
|
| } else {
|
| // Heuristically try to detect immediately called functions before
|
| // seeing the call parentheses.
|
| @@ -2239,8 +2257,26 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
|
| this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
|
| classifier->Accumulate(binding_classifier,
|
| ExpressionClassifier::AllProductions);
|
| - while (peek() == Token::COMMA) {
|
| - Expect(Token::COMMA, CHECK_OK);
|
| + bool seen_rest = false;
|
| + while (Check(Token::COMMA)) {
|
| + if (seen_rest) {
|
| + // Seeing the first rest param meant that this form wasn't a valid
|
| + // expression or pattern. Now we know it's not a valid formal parameter
|
| + // list either.
|
| + ReportMessageAt(scanner()->peek_location(),
|
| + MessageTemplate::kParamAfterRest);
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| + }
|
| + if (allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
|
| + // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
|
| + // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
|
| + // valid expression or binding pattern.
|
| + ExpressionUnexpectedToken(classifier);
|
| + BindingPatternUnexpectedToken(classifier);
|
| + seen_rest = true;
|
| + classifier->RecordArrowFormalParametersWithRest();
|
| + }
|
| int pos = position();
|
| ExpressionT right = this->ParseAssignmentExpression(
|
| accept_IN, &binding_classifier, CHECK_OK);
|
| @@ -2671,7 +2707,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| }
|
| ExpressionT expression = this->ParseConditionalExpression(
|
| accept_IN, &arrow_formals_classifier, CHECK_OK);
|
| - classifier->Accumulate(arrow_formals_classifier);
|
|
|
| if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
|
| checkpoint.Restore();
|
| @@ -2679,12 +2714,13 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
|
| CHECK_OK);
|
| Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
|
| - bool has_rest = false;
|
| + bool has_rest =
|
| + arrow_formals_classifier.is_arrow_formal_parameters_with_rest();
|
| Scope* scope =
|
| this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
|
| scope->set_start_position(lhs_location.beg_pos);
|
| Scanner::Location duplicate_loc = Scanner::Location::invalid();
|
| - this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
|
| + this->ParseArrowFunctionFormalParameters(scope, expression, loc, has_rest,
|
| &duplicate_loc, CHECK_OK);
|
| if (duplicate_loc.IsValid()) {
|
| arrow_formals_classifier.RecordDuplicateFormalParameterError(
|
| @@ -2698,7 +2734,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| // "expression" was not itself an arrow function parameter list, but it might
|
| // form part of one. Propagate speculative formal parameter error locations.
|
| classifier->Accumulate(arrow_formals_classifier,
|
| - ExpressionClassifier::FormalParametersProductions);
|
| + ExpressionClassifier::StandardProductions |
|
| + ExpressionClassifier::FormalParametersProductions);
|
|
|
| if (!Token::IsAssignmentOp(peek())) {
|
| if (fni_ != NULL) fni_->Leave();
|
|
|