Commit e45fba81 authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

[parser] only parse async arrow function when necessary

Previously, an async arrow function would be parsed if any valid
ConditionalExpression began with the identifier "async", and its following token
was on the same line.

So for example, `async.bar foo => 1` was parsed as a valid async arrow function.
This patch corrects this behaviour by asserting that the following token is a
valid arrow parameters start.

BUG=v8:4483
R=littledan@chromium.org, henrique.ferreiro@gmail.com

Review-Url: https://codereview.chromium.org/2089733002
Cr-Commit-Position: refs/heads/master@{#37154}
parent 9bfd7b9d
......@@ -669,13 +669,13 @@ class ParserBase : public Traits {
Expect(Token::SEMICOLON, ok);
}
bool peek_any_identifier() {
Token::Value next = peek();
return next == Token::IDENTIFIER || next == Token::ENUM ||
next == Token::AWAIT || next == Token::ASYNC ||
next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
next == Token::STATIC || next == Token::YIELD;
bool is_any_identifier(Token::Value token) {
return token == Token::IDENTIFIER || token == Token::ENUM ||
token == Token::AWAIT || token == Token::ASYNC ||
token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
token == Token::STATIC || token == Token::YIELD;
}
bool peek_any_identifier() { return is_any_identifier(peek()); }
bool CheckContextualKeyword(Vector<const char> keyword) {
if (PeekContextualKeyword(keyword)) {
......@@ -888,6 +888,10 @@ class ParserBase : public Traits {
}
}
bool IsValidArrowFormalParametersStart(Token::Value token) {
return is_any_identifier(token) || token == Token::LPAREN;
}
void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
ExpressionT expr,
bool parenthesized_formals, bool is_async,
......@@ -2231,7 +2235,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
classifier->duplicate_finder());
bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
!scanner()->HasAnyLineTerminatorAfterNext();
!scanner()->HasAnyLineTerminatorAfterNext() &&
IsValidArrowFormalParametersStart(PeekAhead());
bool parenthesized_formals = peek() == Token::LPAREN;
if (!is_async && !parenthesized_formals) {
......
......@@ -7640,6 +7640,31 @@ TEST(AsyncAwaitErrors) {
"var O = { async method() { function await() {} } }",
"async function foo() { function await() {} }",
// Henrique Ferreiro's bug (tm)
"(async function foo() { } foo => 1)",
"(async function foo() { } () => 1)",
"(async function foo() { } => 1)",
"(async function() { } foo => 1)",
"(async function() { } () => 1)",
"(async function() { } => 1)",
"(async.foo => 1)",
"(async.foo foo => 1)",
"(async.foo () => 1)",
"(async().foo => 1)",
"(async().foo foo => 1)",
"(async().foo () => 1)",
"(async['foo'] => 1)",
"(async['foo'] foo => 1)",
"(async['foo'] () => 1)",
"(async()['foo'] => 1)",
"(async()['foo'] foo => 1)",
"(async()['foo'] () => 1)",
"(async`foo` => 1)",
"(async`foo` foo => 1)",
"(async`foo` () => 1)",
"(async`foo`.bar => 1)",
"(async`foo`.bar foo => 1)",
"(async`foo`.bar () => 1)",
NULL
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment