Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index f687820fd57ff3277f2ca75bb197a4c6c9f82274..eec7f773d192fb4788ce7b7de25126f47e5b1cd2 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -1616,39 +1616,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( |
MessageTemplate::kUnexpectedToken, |
Token::String(Token::RPAREN)); |
return factory()->NewEmptyParentheses(beg_pos); |
- } else if (Check(Token::ELLIPSIS)) { |
- // (...x)=>x. The continuation that looks for the => is in |
- // ParseAssignmentExpression. |
- int ellipsis_pos = position(); |
- int expr_pos = peek_position(); |
- classifier->RecordExpressionError(scanner()->location(), |
- MessageTemplate::kUnexpectedToken, |
- Token::String(Token::ELLIPSIS)); |
- classifier->RecordNonSimpleParameter(); |
- ExpressionClassifier binding_classifier(this); |
- // TODO(adamk): The grammar for this is |
- // BindingIdentifier | BindingPattern, so |
- // ParseAssignmentExpression is overkill. |
- ExpressionT expr = |
- ParseAssignmentExpression(true, &binding_classifier, CHECK_OK); |
- // This already couldn't be an expression or a pattern, so the |
- // only remaining possibility is an arrow formal parameter list. |
- classifier->Accumulate( |
- &binding_classifier, |
- ExpressionClassifier::ArrowFormalParametersProduction); |
- if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { |
- classifier->RecordArrowFormalParametersError( |
- Scanner::Location(ellipsis_pos, scanner()->location().end_pos), |
- MessageTemplate::kInvalidRestParameter); |
- } |
- if (peek() == Token::COMMA) { |
- impl()->ReportMessageAt(scanner()->peek_location(), |
- MessageTemplate::kParamAfterRest); |
- *ok = false; |
- return impl()->EmptyExpression(); |
- } |
- Expect(Token::RPAREN, CHECK_OK); |
- return factory()->NewSpread(expr, ellipsis_pos, expr_pos); |
} |
// Heuristically try to detect immediately called functions before |
// seeing the call parentheses. |
@@ -1721,66 +1688,57 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
// AssignmentExpression |
// Expression ',' AssignmentExpression |
- ExpressionT result; |
- |
- // No need to accumulate binding pattern-related errors, since |
- // an Expression can't be a binding pattern anyway. |
- static const unsigned kExpressionProductions = |
- ExpressionClassifier::AllProductions & |
- ~(ExpressionClassifier::BindingPatternProduction | |
- ExpressionClassifier::LetPatternProduction); |
- { |
- ExpressionClassifier binding_classifier(this); |
- result = |
- ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
- classifier->Accumulate(&binding_classifier, kExpressionProductions); |
- } |
- bool is_simple_parameter_list = impl()->IsIdentifier(result); |
- bool seen_rest = false; |
- while (peek() == Token::COMMA) { |
+ ExpressionT result = impl()->EmptyExpression(); |
+ while (true) { |
adamk
2016/08/26 20:13:04
The other loop construct that might make sense her
|
CheckNoTailCallExpressions(classifier, CHECK_OK); |
- if (seen_rest) { |
- // At this point the production can't possibly be valid, but we don't know |
- // which error to signal. |
+ int comma_pos = position(); |
+ ExpressionClassifier binding_classifier(this); |
+ ExpressionT right; |
+ if (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. |
+ binding_classifier.RecordExpressionError( |
+ scanner()->location(), MessageTemplate::kUnexpectedToken, |
+ Token::String(Token::ELLIPSIS)); |
+ int ellipsis_pos = position(); |
+ int pattern_pos = peek_position(); |
+ ExpressionT pattern = |
+ ParsePrimaryExpression(&binding_classifier, CHECK_OK); |
+ ValidateBindingPattern(&binding_classifier, CHECK_OK); |
+ right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos); |
+ } else { |
+ right = |
+ ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
+ } |
+ // No need to accumulate binding pattern-related errors, since |
+ // an Expression can't be a binding pattern anyway. |
+ classifier->Accumulate( |
+ &binding_classifier, |
+ ExpressionClassifier::AllProductions & |
+ ~(ExpressionClassifier::BindingPatternProduction | |
+ ExpressionClassifier::LetPatternProduction)); |
+ if (!impl()->IsIdentifier(right)) classifier->RecordNonSimpleParameter(); |
+ if (impl()->IsEmptyExpression(result)) { |
adamk
2016/08/26 20:13:04
This IsEmptyExpression() thing could be replaced b
nickie
2016/08/29 17:21:27
I'm in favor of the IsEmptyExpression, which I alr
|
+ // First time through the loop. |
+ result = right; |
+ } else { |
+ result = |
+ factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos); |
+ } |
+ |
+ if (!Check(Token::COMMA)) break; |
+ |
+ if (right->IsSpread()) { |
classifier->RecordArrowFormalParametersError( |
- scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
+ scanner()->location(), MessageTemplate::kParamAfterRest); |
} |
- Consume(Token::COMMA); |
- bool is_rest = false; |
+ |
if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && |
PeekAhead() == Token::ARROW) { |
// a trailing comma is allowed at the end of an arrow parameter list |
break; |
- } else if (peek() == 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); |
- Consume(Token::ELLIPSIS); |
- // TODO(adamk): If is_rest is true we don't need to parse an assignment |
- // expression, the grammar is BindingIdentifier | BindingPattern. |
- seen_rest = is_rest = true; |
} |
- int pos = position(), expr_pos = peek_position(); |
- ExpressionClassifier binding_classifier(this); |
- ExpressionT right = |
- ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
- classifier->Accumulate(&binding_classifier, kExpressionProductions); |
- if (is_rest) { |
- if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) { |
- classifier->RecordArrowFormalParametersError( |
- Scanner::Location(pos, scanner()->location().end_pos), |
- MessageTemplate::kInvalidRestParameter); |
- } |
- right = factory()->NewSpread(right, pos, expr_pos); |
- } |
- is_simple_parameter_list = |
- is_simple_parameter_list && impl()->IsIdentifier(right); |
- result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
- } |
- if (!is_simple_parameter_list || seen_rest) { |
- classifier->RecordNonSimpleParameter(); |
} |
return result; |