Skip to content

Commit bb43d6c

Browse files
wingoCommit bot
authored andcommitted
Fix parsing of arrow function formal parameters
Not all parenthesized AssignmentExpressions whose components are valid binding patterns are valid arrow function formal parameters. In particular (a,b,c)() is not valid, and in general the existing code wasn't catching the tail productions of ConditionalExpression, BinaryExpression, PostfixExpression, LeftHandSideExpression, and MemberExpression. Thanks to Adrian Perez for the test case. BUG=v8:4211 LOG=Y [email protected] Review URL: https://codereview.chromium.org/1306583002 Cr-Commit-Position: refs/heads/master@{#30286}
1 parent 371ad73 commit bb43d6c

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

src/preparser.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,6 +2988,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
29882988
ExpressionT expression =
29892989
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
29902990
if (peek() != Token::CONDITIONAL) return expression;
2991+
ArrowFormalParametersUnexpectedToken(classifier);
29912992
BindingPatternUnexpectedToken(classifier);
29922993
Consume(Token::CONDITIONAL);
29932994
// In parsing the first assignment expression in conditional
@@ -3013,6 +3014,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
30133014
// prec1 >= 4
30143015
while (Precedence(peek(), accept_IN) == prec1) {
30153016
BindingPatternUnexpectedToken(classifier);
3017+
ArrowFormalParametersUnexpectedToken(classifier);
30163018
Token::Value op = Next();
30173019
Scanner::Location op_location = scanner()->location();
30183020
int pos = position();
@@ -3075,6 +3077,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
30753077
Token::Value op = peek();
30763078
if (Token::IsUnaryOp(op)) {
30773079
BindingPatternUnexpectedToken(classifier);
3080+
ArrowFormalParametersUnexpectedToken(classifier);
30783081

30793082
op = Next();
30803083
int pos = position();
@@ -3097,6 +3100,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
30973100
return this->BuildUnaryExpression(expression, op, pos, factory());
30983101
} else if (Token::IsCountOp(op)) {
30993102
BindingPatternUnexpectedToken(classifier);
3103+
ArrowFormalParametersUnexpectedToken(classifier);
31003104
op = Next();
31013105
int beg_pos = peek_position();
31023106
ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
@@ -3129,6 +3133,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
31293133
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
31303134
Token::IsCountOp(peek())) {
31313135
BindingPatternUnexpectedToken(classifier);
3136+
ArrowFormalParametersUnexpectedToken(classifier);
31323137

31333138
expression = this->CheckAndRewriteReferenceExpression(
31343139
expression, lhs_beg_pos, scanner()->location().end_pos,
@@ -3160,6 +3165,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
31603165
switch (peek()) {
31613166
case Token::LBRACK: {
31623167
BindingPatternUnexpectedToken(classifier);
3168+
ArrowFormalParametersUnexpectedToken(classifier);
31633169
Consume(Token::LBRACK);
31643170
int pos = position();
31653171
ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
@@ -3170,6 +3176,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
31703176

31713177
case Token::LPAREN: {
31723178
BindingPatternUnexpectedToken(classifier);
3179+
ArrowFormalParametersUnexpectedToken(classifier);
31733180

31743181
if (is_strong(language_mode()) && this->IsIdentifier(result) &&
31753182
this->IsEval(this->AsIdentifier(result))) {
@@ -3231,6 +3238,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
32313238

32323239
case Token::PERIOD: {
32333240
BindingPatternUnexpectedToken(classifier);
3241+
ArrowFormalParametersUnexpectedToken(classifier);
32343242
Consume(Token::PERIOD);
32353243
int pos = position();
32363244
IdentifierT name = ParseIdentifierName(CHECK_OK);
@@ -3243,6 +3251,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
32433251
case Token::TEMPLATE_SPAN:
32443252
case Token::TEMPLATE_TAIL: {
32453253
BindingPatternUnexpectedToken(classifier);
3254+
ArrowFormalParametersUnexpectedToken(classifier);
32463255
result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
32473256
break;
32483257
}
@@ -3280,6 +3289,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
32803289

32813290
if (peek() == Token::NEW) {
32823291
BindingPatternUnexpectedToken(classifier);
3292+
ArrowFormalParametersUnexpectedToken(classifier);
32833293
Consume(Token::NEW);
32843294
int new_pos = position();
32853295
ExpressionT result = this->EmptyExpression();
@@ -3333,6 +3343,7 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
33333343
ExpressionT result = this->EmptyExpression();
33343344
if (peek() == Token::FUNCTION) {
33353345
BindingPatternUnexpectedToken(classifier);
3346+
ArrowFormalParametersUnexpectedToken(classifier);
33363347

33373348
Consume(Token::FUNCTION);
33383349
int function_token_position = position();
@@ -3576,6 +3587,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
35763587
switch (peek()) {
35773588
case Token::LBRACK: {
35783589
BindingPatternUnexpectedToken(classifier);
3590+
ArrowFormalParametersUnexpectedToken(classifier);
35793591

35803592
Consume(Token::LBRACK);
35813593
int pos = position();
@@ -3589,6 +3601,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
35893601
}
35903602
case Token::PERIOD: {
35913603
BindingPatternUnexpectedToken(classifier);
3604+
ArrowFormalParametersUnexpectedToken(classifier);
35923605

35933606
Consume(Token::PERIOD);
35943607
int pos = position();
@@ -3603,6 +3616,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
36033616
case Token::TEMPLATE_SPAN:
36043617
case Token::TEMPLATE_TAIL: {
36053618
BindingPatternUnexpectedToken(classifier);
3619+
ArrowFormalParametersUnexpectedToken(classifier);
36063620
int pos;
36073621
if (scanner()->current_token() == Token::IDENTIFIER) {
36083622
pos = position();

test/cctest/test-parsing.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,6 +3510,67 @@ TEST(UseConstLegacyCount) {
35103510
}
35113511

35123512

3513+
TEST(ErrorsArrowFormalParameters) {
3514+
const char* context_data[][2] = {
3515+
{ "()", "=>{}" },
3516+
{ "()", "=>{};" },
3517+
{ "var x = ()", "=>{}" },
3518+
{ "var x = ()", "=>{};" },
3519+
3520+
{ "a", "=>{}" },
3521+
{ "a", "=>{};" },
3522+
{ "var x = a", "=>{}" },
3523+
{ "var x = a", "=>{};" },
3524+
3525+
{ "(a)", "=>{}" },
3526+
{ "(a)", "=>{};" },
3527+
{ "var x = (a)", "=>{}" },
3528+
{ "var x = (a)", "=>{};" },
3529+
3530+
{ "(...a)", "=>{}" },
3531+
{ "(...a)", "=>{};" },
3532+
{ "var x = (...a)", "=>{}" },
3533+
{ "var x = (...a)", "=>{};" },
3534+
3535+
{ "(a,b)", "=>{}" },
3536+
{ "(a,b)", "=>{};" },
3537+
{ "var x = (a,b)", "=>{}" },
3538+
{ "var x = (a,b)", "=>{};" },
3539+
3540+
{ "(a,...b)", "=>{}" },
3541+
{ "(a,...b)", "=>{};" },
3542+
{ "var x = (a,...b)", "=>{}" },
3543+
{ "var x = (a,...b)", "=>{};" },
3544+
3545+
{ nullptr, nullptr }
3546+
};
3547+
const char* assignment_expression_suffix_data[] = {
3548+
"?c:d=>{}",
3549+
"=c=>{}",
3550+
"()",
3551+
"(c)",
3552+
"[1]",
3553+
"[c]",
3554+
".c",
3555+
"-c",
3556+
"+c",
3557+
"c++",
3558+
"`c`",
3559+
"`${c}`",
3560+
"`template-head${c}`",
3561+
"`${c}template-tail`",
3562+
"`template-head${c}template-tail`",
3563+
"`${c}template-tail`",
3564+
nullptr
3565+
};
3566+
3567+
static const ParserFlag always_flags[] = { kAllowHarmonyArrowFunctions,
3568+
kAllowHarmonyRestParameters };
3569+
RunParserSyncTest(context_data, assignment_expression_suffix_data, kError,
3570+
NULL, 0, always_flags, arraysize(always_flags));
3571+
}
3572+
3573+
35133574
TEST(ErrorsArrowFunctions) {
35143575
// Tests that parser and preparser generate the same kind of errors
35153576
// on invalid arrow function syntax.

0 commit comments

Comments
 (0)