Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Unified Diff: src/parsing/parser-base.h

Issue 2372733002: [parser] Refactor of (Parse|Desugar)*(Async|Arrow)* (Closed)
Patch Set: Rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(
- &parameters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK);
+ impl()->DeclareArrowFunctionFormalParameters(&parameters, 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:
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698