| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index 86135f8caf9b70bfaeb8f34d8c8204ff925148a6..f9af124bc38e2e9a8e35b9f2e6b107ca0b25c114 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -250,6 +250,11 @@ class ParserBase {
|
| kStatement,
|
| kForStatement
|
| };
|
| +
|
| + enum class FunctionBodyType {
|
| + kNormal,
|
| + kSingleExpression
|
| + };
|
| // clang-format on
|
|
|
| class Checkpoint;
|
| @@ -1191,6 +1196,10 @@ class ParserBase {
|
| ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
|
| const FormalParametersT& parameters,
|
| bool* ok);
|
| + void ParseAsyncFunctionBody(Scope* scope, StatementListT body,
|
| + FunctionKind kind, FunctionBodyType type,
|
| + bool accept_IN, int pos, bool* ok);
|
| + ExpressionT ParseAsyncFunctionLiteral(bool* ok);
|
| ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
| ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
| ExpressionT ParseNewTargetExpression(bool* ok);
|
| @@ -1205,6 +1214,8 @@ class ParserBase {
|
| DeclarationParsingResult* parsing_result,
|
| ZoneList<const AstRawString*>* names,
|
| bool* ok);
|
| + StatementT ParseAsyncFunctionDeclaration(ZoneList<const AstRawString*>* names,
|
| + bool default_export, bool* ok);
|
| StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names,
|
| bool default_export, bool* ok);
|
| StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
|
| @@ -1707,7 +1718,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
| // '(' Expression ')'
|
| // TemplateLiteral
|
| // do Block
|
| - // AsyncFunctionExpression
|
| + // AsyncFunctionLiteral
|
|
|
| int beg_pos = peek_position();
|
| switch (peek()) {
|
| @@ -1730,7 +1741,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
| !scanner()->HasAnyLineTerminatorAfterNext() &&
|
| PeekAhead() == Token::FUNCTION) {
|
| Consume(Token::ASYNC);
|
| - return impl()->ParseAsyncFunctionExpression(CHECK_OK);
|
| + return ParseAsyncFunctionLiteral(CHECK_OK);
|
| }
|
| // CoverCallExpressionAndAsyncArrowHead
|
| *is_async = true;
|
| @@ -2667,6 +2678,9 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
| // usage flags that might have been triggered there need to be copied
|
| // to the arrow scope.
|
| this->scope()->PropagateUsageFlagsToScope(scope);
|
| +
|
| + scope_snapshot.Reparent(scope);
|
| +
|
| FormalParametersT parameters(scope);
|
| if (!classifier()->is_simple_parameter_list()) {
|
| scope->SetHasNonSimpleParameters();
|
| @@ -2677,8 +2691,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
|
|
| scope->set_start_position(lhs_beg_pos);
|
| Scanner::Location duplicate_loc = Scanner::Location::invalid();
|
| - impl()->ParseArrowFunctionFormalParameterList(
|
| - ¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK);
|
| + impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc,
|
| + &duplicate_loc, CHECK_OK);
|
| if (duplicate_loc.IsValid()) {
|
| classifier()->RecordDuplicateFormalParameterError(duplicate_loc);
|
| }
|
| @@ -3806,6 +3820,25 @@ ParserBase<Impl>::ParseHoistableDeclaration(
|
| }
|
|
|
| template <typename Impl>
|
| +typename ParserBase<Impl>::StatementT
|
| +ParserBase<Impl>::ParseAsyncFunctionDeclaration(
|
| + ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
|
| + // AsyncFunctionDeclaration ::
|
| + // async [no LineTerminator here] function BindingIdentifier[Await]
|
| + // ( FormalParameters[Await] ) { AsyncFunctionBody }
|
| + DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
|
| + int pos = position();
|
| + if (scanner()->HasAnyLineTerminatorBeforeNext()) {
|
| + *ok = false;
|
| + impl()->ReportUnexpectedToken(scanner()->current_token());
|
| + return impl()->NullStatement();
|
| + }
|
| + Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
|
| + ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
|
| + return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
|
| +}
|
| +
|
| +template <typename Impl>
|
| void ParserBase<Impl>::CheckArityRestrictions(int param_count,
|
| FunctionKind function_kind,
|
| bool has_rest,
|
| @@ -3964,8 +3997,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
| formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK);
|
| ExpressionClassifier classifier(this);
|
| if (kind == kAsyncArrowFunction) {
|
| - impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, pos,
|
| - CHECK_OK);
|
| + ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction,
|
| + FunctionBodyType::kSingleExpression, accept_IN,
|
| + pos, CHECK_OK);
|
| impl()->RewriteNonPattern(CHECK_OK);
|
| } else {
|
| ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
|
| @@ -4020,6 +4054,61 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
| }
|
|
|
| template <typename Impl>
|
| +void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
|
| + FunctionKind kind,
|
| + FunctionBodyType body_type,
|
| + bool accept_IN, int pos,
|
| + bool* ok) {
|
| + scope->ForceContextAllocation();
|
| +
|
| + impl()->PrepareAsyncFunctionBody(body, kind, pos);
|
| +
|
| + BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
|
| +
|
| + ExpressionT return_value = impl()->EmptyExpression();
|
| + if (body_type == FunctionBodyType::kNormal) {
|
| + ParseStatementList(block->statements(), Token::RBRACE,
|
| + CHECK_OK_CUSTOM(Void));
|
| + return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
|
| + } else {
|
| + return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void));
|
| + impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
|
| + }
|
| +
|
| + impl()->RewriteAsyncFunctionBody(body, block, return_value,
|
| + CHECK_OK_CUSTOM(Void));
|
| + scope->set_end_position(scanner()->location().end_pos);
|
| +}
|
| +
|
| +template <typename Impl>
|
| +typename ParserBase<Impl>::ExpressionT
|
| +ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
|
| + // AsyncFunctionLiteral ::
|
| + // async [no LineTerminator here] function ( FormalParameters[Await] )
|
| + // { AsyncFunctionBody }
|
| + //
|
| + // async [no LineTerminator here] function BindingIdentifier[Await]
|
| + // ( FormalParameters[Await] ) { AsyncFunctionBody }
|
| + DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
|
| + int pos = position();
|
| + Expect(Token::FUNCTION, CHECK_OK);
|
| + bool is_strict_reserved = false;
|
| + IdentifierT name = impl()->EmptyIdentifier();
|
| + FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
|
| +
|
| + if (peek_any_identifier()) {
|
| + type = FunctionLiteral::kNamedExpression;
|
| + name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction,
|
| + &is_strict_reserved, CHECK_OK);
|
| + }
|
| + return impl()->ParseFunctionLiteral(
|
| + name, scanner()->location(),
|
| + is_strict_reserved ? kFunctionNameIsStrictReserved
|
| + : kFunctionNameValidityUnknown,
|
| + FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK);
|
| +}
|
| +
|
| +template <typename Impl>
|
| typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
|
| ExpressionT tag, int start, bool* ok) {
|
| // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
|
| @@ -4329,7 +4418,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem(
|
| if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
|
| !scanner()->HasAnyLineTerminatorAfterNext()) {
|
| Consume(Token::ASYNC);
|
| - return impl()->ParseAsyncFunctionDeclaration(nullptr, false, ok);
|
| + return ParseAsyncFunctionDeclaration(nullptr, false, ok);
|
| }
|
| /* falls through */
|
| default:
|
|
|