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

Unified Diff: src/parsing/parser.cc

Issue 2111153002: [modules] Refactor parsing of anonymous declarations in default exports. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Nits and remove TODOs for now. Created 4 years, 6 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.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 24df10cb9d7a4021d1541c90c77e09caee97ed6a..21b316e94042a3d3c2436f08e0517e29e1c9ab8c 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -1285,10 +1285,10 @@ Statement* Parser::ParseStatementListItem(bool* ok) {
const Token::Value peeked = peek();
switch (peeked) {
case Token::FUNCTION:
- return ParseHoistableDeclaration(NULL, ok);
+ return ParseHoistableDeclaration(NULL, false, ok);
case Token::CLASS:
Consume(Token::CLASS);
- return ParseClassDeclaration(NULL, ok);
+ return ParseClassDeclaration(NULL, false, ok);
case Token::CONST:
return ParseVariableStatement(kStatementListItem, NULL, ok);
case Token::VAR:
@@ -1302,7 +1302,7 @@ Statement* Parser::ParseStatementListItem(bool* ok) {
if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
!scanner()->HasAnyLineTerminatorAfterNext()) {
Consume(Token::ASYNC);
- return ParseAsyncFunctionDeclaration(NULL, ok);
+ return ParseAsyncFunctionDeclaration(NULL, false, ok);
}
/* falls through */
default:
@@ -1576,66 +1576,20 @@ Statement* Parser::ParseExportDefault(bool* ok) {
Statement* result = nullptr;
Expression* default_export = nullptr;
switch (peek()) {
- case Token::FUNCTION: {
- Consume(Token::FUNCTION);
- int pos = position();
- bool is_generator = Check(Token::MUL);
- if (peek() == Token::LPAREN) {
- // FunctionDeclaration[+Default] ::
- // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
- //
- // GeneratorDeclaration[+Default] ::
- // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
- default_export = ParseFunctionLiteral(
- default_string, Scanner::Location::invalid(),
- kSkipFunctionNameCheck,
- is_generator ? FunctionKind::kGeneratorFunction
- : FunctionKind::kNormalFunction,
- pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
- result = factory()->NewEmptyStatement(kNoSourcePosition);
- } else {
- result = ParseHoistableDeclaration(
- pos, is_generator ? ParseFunctionFlags::kIsGenerator
- : ParseFunctionFlags::kIsNormal,
- &names, CHECK_OK);
- }
+ case Token::FUNCTION:
+ result = ParseHoistableDeclaration(&names, true, CHECK_OK);
break;
- }
case Token::CLASS:
Consume(Token::CLASS);
- if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
- // ClassDeclaration[+Default] ::
- // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
- default_export = ParseClassLiteral(nullptr, default_string,
- Scanner::Location::invalid(), false,
- position(), CHECK_OK);
- result = factory()->NewEmptyStatement(kNoSourcePosition);
- } else {
- result = ParseClassDeclaration(&names, CHECK_OK);
- }
+ result = ParseClassDeclaration(&names, true, CHECK_OK);
break;
case Token::ASYNC:
if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
!scanner()->HasAnyLineTerminatorAfterNext()) {
Consume(Token::ASYNC);
- Consume(Token::FUNCTION);
- int pos = position();
- if (peek() == Token::LPAREN) {
- // AsyncFunctionDeclaration[+Default] ::
- // async [no LineTerminator here] function ( FormalParameters ) {
- // AsyncFunctionBody
- // }
- default_export = ParseFunctionLiteral(
- default_string, Scanner::Location::invalid(),
- kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos,
- FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
- result = factory()->NewEmptyStatement(kNoSourcePosition);
- } else {
- result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync,
- &names, CHECK_OK);
- }
+ result = ParseAsyncFunctionDeclaration(&names, true, CHECK_OK);
break;
}
/* falls through */
@@ -1750,12 +1704,12 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
}
case Token::FUNCTION:
- result = ParseHoistableDeclaration(&names, CHECK_OK);
+ result = ParseHoistableDeclaration(&names, false, CHECK_OK);
break;
case Token::CLASS:
Consume(Token::CLASS);
- result = ParseClassDeclaration(&names, CHECK_OK);
+ result = ParseClassDeclaration(&names, false, CHECK_OK);
break;
case Token::VAR:
@@ -1767,7 +1721,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
case Token::ASYNC:
if (allow_harmony_async_await()) {
Consume(Token::ASYNC);
- result = ParseAsyncFunctionDeclaration(&names, CHECK_OK);
+ result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
break;
}
/* falls through */
@@ -2139,20 +2093,19 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
pos);
}
-
Statement* Parser::ParseHoistableDeclaration(
- ZoneList<const AstRawString*>* names, bool* ok) {
+ ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
Expect(Token::FUNCTION, CHECK_OK);
int pos = position();
ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
if (Check(Token::MUL)) {
flags |= ParseFunctionFlags::kIsGenerator;
}
- return ParseHoistableDeclaration(pos, flags, names, ok);
+ return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}
Statement* Parser::ParseAsyncFunctionDeclaration(
- ZoneList<const AstRawString*>* names, bool* ok) {
+ ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
int pos = position();
if (scanner()->HasAnyLineTerminatorBeforeNext()) {
@@ -2162,25 +2115,41 @@ Statement* Parser::ParseAsyncFunctionDeclaration(
}
Expect(Token::FUNCTION, CHECK_OK);
ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
- return ParseHoistableDeclaration(pos, flags, names, ok);
+ return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}
Statement* Parser::ParseHoistableDeclaration(
int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
- bool* ok) {
+ bool default_export, bool* ok) {
// FunctionDeclaration ::
// 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
+ // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
// GeneratorDeclaration ::
// 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
+ // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
+ //
+ // The anonymous forms are allowed iff [default_export] is true.
//
// 'function' and '*' (if present) have been consumed by the caller.
+
const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
const bool is_async = flags & ParseFunctionFlags::kIsAsync;
DCHECK(!is_generator || !is_async);
- bool is_strict_reserved = false;
- const AstRawString* name = ParseIdentifierOrStrictReservedWord(
- &is_strict_reserved, CHECK_OK);
+ const AstRawString* name;
+ FunctionNameValidity name_validity;
+ const AstRawString* variable_name;
+ if (default_export && peek() == Token::LPAREN) {
+ name = ast_value_factory()->default_string();
+ name_validity = kSkipFunctionNameCheck;
+ variable_name = ast_value_factory()->star_default_star_string();
+ } else {
+ bool is_strict_reserved;
+ name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
+ name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
+ : kFunctionNameValidityUnknown;
+ variable_name = name;
+ }
if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
ReportMessageAt(scanner()->location(),
@@ -2192,9 +2161,7 @@ Statement* Parser::ParseHoistableDeclaration(
FuncNameInferrer::State fni_state(fni_);
if (fni_ != NULL) fni_->PushEnclosingName(name);
FunctionLiteral* fun = ParseFunctionLiteral(
- name, scanner()->location(),
- is_strict_reserved ? kFunctionNameIsStrictReserved
- : kFunctionNameValidityUnknown,
+ name, scanner()->location(), name_validity,
is_generator ? FunctionKind::kGeneratorFunction
: is_async ? FunctionKind::kAsyncFunction
: FunctionKind::kNormalFunction,
@@ -2208,11 +2175,11 @@ Statement* Parser::ParseHoistableDeclaration(
VariableMode mode =
(!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET
: VAR;
- VariableProxy* proxy = NewUnresolved(name, mode);
+ VariableProxy* proxy = NewUnresolved(variable_name, mode);
Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
- if (names) names->Add(name, zone());
+ if (names) names->Add(variable_name, zone());
EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
// Async functions don't undergo sloppy mode block scoped hoisting, and don't
// allow duplicates in a block. Both are represented by the
@@ -2223,18 +2190,20 @@ Statement* Parser::ParseHoistableDeclaration(
!is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
SloppyBlockFunctionStatement* delegate =
factory()->NewSloppyBlockFunctionStatement(empty, scope_);
- scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
- delegate);
+ scope_->DeclarationScope()->sloppy_block_function_map()->Declare(
+ variable_name, delegate);
return delegate;
}
return empty;
}
-
Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
- bool* ok) {
+ bool default_export, bool* ok) {
// ClassDeclaration ::
// 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
+ // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
+ //
+ // The anonymous form is allowed iff [default_export] is true.
//
// 'class' is expected to be consumed by the caller.
//
@@ -2249,13 +2218,23 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
// so rewrite it as such.
int pos = position();
- bool is_strict_reserved = false;
- const AstRawString* name =
- ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
+
+ const AstRawString* name;
+ bool is_strict_reserved;
+ const AstRawString* variable_name;
+ if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
+ name = ast_value_factory()->default_string();
+ is_strict_reserved = false;
+ variable_name = ast_value_factory()->star_default_star_string();
+ } else {
+ name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
+ variable_name = name;
+ }
+
ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(),
is_strict_reserved, pos, CHECK_OK);
- VariableProxy* proxy = NewUnresolved(name, LET);
+ VariableProxy* proxy = NewUnresolved(variable_name, LET);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
@@ -2264,7 +2243,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
factory()->NewAssignment(Token::INIT, proxy, value, pos);
Statement* assignment_statement =
factory()->NewExpressionStatement(assignment, kNoSourcePosition);
- if (names) names->Add(name, zone());
+ if (names) names->Add(variable_name, zone());
return assignment_statement;
}
@@ -2524,7 +2503,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
}
}
- return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK);
+ return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK);
}
Statement* Parser::ParseExpressionOrLabelledStatement(
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698