Bug 1185106 - Part 6.1: Support async function expression in Parser. r=till
MozReview-Commit-ID: Ed7PAq3bNTX
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3518,44 +3518,49 @@ Parser<ParseHandler>::functionStmt(Yield
return finishLexicalScope(*synthesizedScopeForAnnexB, synthesizedStmtList);
}
return fun;
}
template <typename ParseHandler>
typename ParseHandler::Node
-Parser<ParseHandler>::functionExpr(InvokedPrediction invoked)
+Parser<ParseHandler>::functionExpr(InvokedPrediction invoked, FunctionAsyncKind asyncKind)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
- GeneratorKind generatorKind = NotGenerator;
+ AutoAwaitIsKeyword awaitIsKeyword(&tokenStream, asyncKind == AsyncFunction);
+ GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator;
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_MUL) {
+ if (asyncKind != SyncFunction) {
+ report(ParseError, false, null(), JSMSG_ASYNC_GENERATOR);
+ return null();
+ }
generatorKind = StarGenerator;
if (!tokenStream.getToken(&tt))
return null();
}
- YieldHandling yieldHandling = GetYieldHandling(generatorKind, SyncFunction);
+ YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind);
RootedPropertyName name(context);
if (tt == TOK_NAME || tt == TOK_YIELD) {
name = bindingIdentifier(yieldHandling);
if (!name)
return null();
} else {
tokenStream.ungetToken();
}
return functionDefinition(InAllowed, yieldHandling, name, Expression, generatorKind,
- SyncFunction, invoked);
+ asyncKind, invoked);
}
/*
* Return true if this node, known to be an unparenthesized string literal,
* could be the string of a directive in a Directive Prologue. Directive
* strings never contain escape sequences or line continuations.
* isEscapeFreeStringLiteral, below, checks whether the node itself could be
* a directive.
@@ -9234,16 +9239,27 @@ Parser<ParseHandler>::primaryExpr(YieldH
case TOK_NO_SUBS_TEMPLATE:
return noSubstitutionTemplate();
case TOK_STRING:
return stringLiteral();
case TOK_YIELD:
case TOK_NAME: {
+ if (tokenStream.currentName() == context->names().async) {
+ TokenKind nextSameLine = TOK_EOF;
+ if (!tokenStream.peekTokenSameLine(&nextSameLine))
+ return null();
+
+ if (nextSameLine == TOK_FUNCTION) {
+ tokenStream.consumeKnownToken(TOK_FUNCTION);
+ return functionExpr(PredictUninvoked, AsyncFunction);
+ }
+ }
+
Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
if (!name)
return null();
return identifierReference(name);
}
case TOK_REGEXP:
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1082,17 +1082,18 @@ class Parser final : private JS::AutoGCR
* number of the parsers this is convenient and avoids a lot of
* unnecessary ungetting and regetting of tokens.
*
* Some parsers have two versions: an always-inlined version (with an 'i'
* suffix) and a never-inlined version (with an 'n' suffix).
*/
Node functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling,
FunctionAsyncKind asyncKind = SyncFunction);
- Node functionExpr(InvokedPrediction invoked = PredictUninvoked);
+ Node functionExpr(InvokedPrediction invoked = PredictUninvoked,
+ FunctionAsyncKind asyncKind = SyncFunction);
Node statementList(YieldHandling yieldHandling);
Node blockStatement(YieldHandling yieldHandling,
unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
Node doWhileStatement(YieldHandling yieldHandling);
Node whileStatement(YieldHandling yieldHandling);