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

Unified Diff: src/parsing/preparser.cc

Issue 2307073002: [parser] Refactor of Parse*Statement*, part 1 (Closed)
Patch Set: Fix weird compilation bug with line continuation in comment 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
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/preparser.cc
diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc
index 369ff2415efb8dbe3351b73dfb3c818147460c64..4a3f680f035d1384bb8d445bf5b40ec5b4ee2910 100644
--- a/src/parsing/preparser.cc
+++ b/src/parsing/preparser.cc
@@ -122,223 +122,19 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
// it is used) are generally omitted.
-PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
- // ECMA 262 6th Edition
- // StatementListItem[Yield, Return] :
- // Statement[?Yield, ?Return]
- // Declaration[?Yield]
- //
- // Declaration[Yield] :
- // HoistableDeclaration[?Yield]
- // ClassDeclaration[?Yield]
- // LexicalDeclaration[In, ?Yield]
- //
- // HoistableDeclaration[Yield, Default] :
- // FunctionDeclaration[?Yield, ?Default]
- // GeneratorDeclaration[?Yield, ?Default]
- //
- // LexicalDeclaration[In, Yield] :
- // LetOrConst BindingList[?In, ?Yield] ;
-
- switch (peek()) {
- case Token::FUNCTION:
- return ParseHoistableDeclaration(ok);
- case Token::CLASS:
- return ParseClassDeclaration(ok);
- case Token::CONST:
- return ParseVariableStatement(kStatementListItem, ok);
- case Token::LET:
- if (IsNextLetKeyword()) {
- return ParseVariableStatement(kStatementListItem, ok);
- }
- break;
- case Token::ASYNC:
- if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
- !scanner()->HasAnyLineTerminatorAfterNext()) {
- Consume(Token::ASYNC);
- return ParseAsyncFunctionDeclaration(ok);
- }
- /* falls through */
- default:
- break;
- }
- return ParseStatement(kAllowLabelledFunctionStatement, ok);
-}
-
-PreParser::LazyParsingResult PreParser::ParseStatementList(int end_token,
- bool may_abort,
- bool* ok) {
- // SourceElements ::
- // (Statement)* <end_token>
-
- int count_statements = 0;
-
- bool directive_prologue = true;
- while (peek() != end_token) {
- if (directive_prologue && peek() != Token::STRING) {
- directive_prologue = false;
- }
- bool starts_with_identifier = peek() == Token::IDENTIFIER;
- Scanner::Location token_loc = scanner()->peek_location();
- Statement statement =
- ParseStatementListItem(CHECK_OK_VALUE(kLazyParsingComplete));
-
- if (directive_prologue) {
- bool use_strict_found = statement.IsUseStrictLiteral();
-
- if (use_strict_found) {
- scope()->SetLanguageMode(
- static_cast<LanguageMode>(scope()->language_mode() | STRICT));
- } else if (!statement.IsStringLiteral()) {
- directive_prologue = false;
- }
-
- if (use_strict_found && !scope()->HasSimpleParameters()) {
- // TC39 deemed "use strict" directives to be an error when occurring
- // in the body of a function with non-simple parameter list, on
- // 29/7/2015. https://goo.gl/ueA7Ln
- ReportMessageAt(token_loc,
- MessageTemplate::kIllegalLanguageModeDirective,
- "use strict");
- *ok = false;
- return kLazyParsingComplete;
- }
- }
-
- // If we're allowed to reset to a bookmark, we will do so when we see a long
- // and trivial function.
- // Our current definition of 'long and trivial' is:
- // - over 200 statements
- // - all starting with an identifier (i.e., no if, for, while, etc.)
- if (may_abort) {
- if (!starts_with_identifier) {
- may_abort = false;
- } else if (++count_statements > kLazyParseTrialLimit) {
- return kLazyParsingAborted;
- }
- }
- }
- return kLazyParsingComplete;
-}
-
-
-PreParser::Statement PreParser::ParseStatement(
- AllowLabelledFunctionStatement allow_function, bool* ok) {
- // Statement ::
- // EmptyStatement
- // ...
-
- if (peek() == Token::SEMICOLON) {
- Next();
- return Statement::Default();
- }
- return ParseSubStatement(allow_function, ok);
-}
-
PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
(legacy && allow_harmony_restrictive_declarations())) {
- return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
+ return ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
} else {
BlockState block_state(&scope_state_);
return ParseFunctionDeclaration(ok);
}
}
-PreParser::Statement PreParser::ParseSubStatement(
- AllowLabelledFunctionStatement allow_function, bool* ok) {
- // Statement ::
- // Block
- // VariableStatement
- // EmptyStatement
- // ExpressionStatement
- // IfStatement
- // IterationStatement
- // ContinueStatement
- // BreakStatement
- // ReturnStatement
- // WithStatement
- // LabelledStatement
- // SwitchStatement
- // ThrowStatement
- // TryStatement
- // DebuggerStatement
-
- // Note: Since labels can only be used by 'break' and 'continue'
- // statements, which themselves are only valid within blocks,
- // iterations or 'switch' statements (i.e., BreakableStatements),
- // labels can be simply ignored in all other cases; except for
- // trivial labeled break statements 'label: break label' which is
- // parsed into an empty statement.
-
- // Keep the source position of the statement
- switch (peek()) {
- case Token::LBRACE:
- return ParseBlock(ok);
-
- case Token::SEMICOLON:
- Next();
- return Statement::Default();
-
- case Token::IF:
- return ParseIfStatement(ok);
-
- case Token::DO:
- return ParseDoWhileStatement(ok);
-
- case Token::WHILE:
- return ParseWhileStatement(ok);
-
- case Token::FOR:
- return ParseForStatement(ok);
-
- case Token::CONTINUE:
- return ParseContinueStatement(ok);
-
- case Token::BREAK:
- return ParseBreakStatement(ok);
-
- case Token::RETURN:
- return ParseReturnStatement(ok);
-
- case Token::WITH:
- return ParseWithStatement(ok);
-
- case Token::SWITCH:
- return ParseSwitchStatement(ok);
-
- case Token::THROW:
- return ParseThrowStatement(ok);
-
- case Token::TRY:
- return ParseTryStatement(ok);
-
- case Token::FUNCTION:
- // FunctionDeclaration only allowed as a StatementListItem, not in
- // an arbitrary Statement position. Exceptions such as
- // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
- // are handled by calling ParseScopedStatement rather than
- // ParseSubStatement directly.
- ReportMessageAt(scanner()->peek_location(),
- is_strict(language_mode())
- ? MessageTemplate::kStrictFunction
- : MessageTemplate::kSloppyFunction);
- *ok = false;
- return Statement::Default();
-
- case Token::DEBUGGER:
- return ParseDebuggerStatement(ok);
-
- case Token::VAR:
- return ParseVariableStatement(kStatement, ok);
-
- default:
- return ParseExpressionOrLabelledStatement(allow_function, ok);
- }
-}
-
PreParser::Statement PreParser::ParseHoistableDeclaration(
- int pos, ParseFunctionFlags flags, bool* ok) {
+ int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
+ bool default_export, bool* ok) {
const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
const bool is_async = flags & ParseFunctionFlags::kIsAsync;
DCHECK(!is_generator || !is_async);
@@ -358,7 +154,8 @@ PreParser::Statement PreParser::ParseHoistableDeclaration(
return Statement::FunctionDeclaration();
}
-PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
+PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(
+ ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
// AsyncFunctionDeclaration ::
// async [no LineTerminator here] function BindingIdentifier[Await]
// ( FormalParameters[Await] ) { AsyncFunctionBody }
@@ -366,10 +163,11 @@ PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
int pos = position();
Expect(Token::FUNCTION, CHECK_OK);
ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
- return ParseHoistableDeclaration(pos, flags, ok);
+ return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}
-PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
+PreParser::Statement PreParser::ParseHoistableDeclaration(
+ ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
// FunctionDeclaration ::
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
// GeneratorDeclaration ::
@@ -382,13 +180,11 @@ PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
if (Check(Token::MUL)) {
flags |= ParseFunctionFlags::kIsGenerator;
}
- return ParseHoistableDeclaration(pos, flags, ok);
+ return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}
-
-PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
- Expect(Token::CLASS, CHECK_OK);
-
+PreParser::Statement PreParser::ParseClassDeclaration(
+ ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
int pos = position();
bool is_strict_reserved = false;
Identifier name =
@@ -399,8 +195,8 @@ PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
return Statement::Default();
}
-
-PreParser::Statement PreParser::ParseBlock(bool* ok) {
+PreParser::Statement PreParser::ParseBlock(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// Block ::
// '{' StatementList '}'
@@ -416,15 +212,14 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
return final;
}
-
PreParser::Statement PreParser::ParseVariableStatement(
VariableDeclarationContext var_context,
- bool* ok) {
+ ZoneList<const AstRawString*>* names, bool* ok) {
// VariableStatement ::
// VariableDeclarations ';'
Statement result =
- ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK);
+ ParseVariableDeclarations(var_context, nullptr, names, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -442,10 +237,11 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
return Statement::Default();
}
}
- return ParseHoistableDeclaration(pos, flags, ok);
+ return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
}
PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
+ ZoneList<const AstRawString*>* names,
AllowLabelledFunctionStatement allow_function, bool* ok) {
// ExpressionStatement | LabelledStatement ::
// Expression ';'
@@ -489,7 +285,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
}
}
Statement statement =
- ParseStatement(kDisallowLabelledFunctionStatement, ok);
+ ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
return statement.IsJumpStatement() ? Statement::Default() : statement;
// Preparsing is disabled for extensions (because the extension details
// aren't passed to lazily compiled functions), so we don't
@@ -500,8 +296,8 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
return Statement::ExpressionStatement(expr);
}
-
-PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
+PreParser::Statement PreParser::ParseIfStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// IfStatement ::
// 'if' '(' Expression ')' Statement ('else' Statement)?
@@ -539,8 +335,8 @@ PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
return Statement::Jump();
}
-
-PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
+PreParser::Statement PreParser::ParseBreakStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// BreakStatement ::
// 'break' [no line terminator] Identifier? ';'
@@ -593,8 +389,8 @@ PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
return Statement::Jump();
}
-
-PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
+PreParser::Statement PreParser::ParseWithStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// WithStatement ::
// 'with' '(' Expression ')' Statement
Expect(Token::WITH, CHECK_OK);
@@ -613,8 +409,8 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
return Statement::Default();
}
-
-PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
+PreParser::Statement PreParser::ParseSwitchStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// SwitchStatement ::
// 'switch' '(' Expression ')' '{' CaseClause* '}'
@@ -649,8 +445,8 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
return Statement::Default();
}
-
-PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
+PreParser::Statement PreParser::ParseDoWhileStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// DoStatement ::
// 'do' Statement 'while' '(' Expression ')' ';'
@@ -664,8 +460,8 @@ PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
return Statement::Default();
}
-
-PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
+PreParser::Statement PreParser::ParseWhileStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// WhileStatement ::
// 'while' '(' Expression ')' Statement
@@ -677,8 +473,8 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
return Statement::Default();
}
-
-PreParser::Statement PreParser::ParseForStatement(bool* ok) {
+PreParser::Statement PreParser::ParseForStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok) {
// ForStatement ::
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
@@ -844,7 +640,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
{
ReturnExprScope no_tail_calls(function_state_,
ReturnExprContext::kInsideTryBlock);
- ParseBlock(CHECK_OK);
+ ParseBlock(nullptr, CHECK_OK);
}
Token::Value tok = peek();
@@ -870,7 +666,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
BlockState block_state(&scope_state_, catch_scope);
{
BlockState block_state(&scope_state_);
- ParseBlock(CHECK_OK);
+ ParseBlock(nullptr, CHECK_OK);
}
}
catch_block_exists = true;
@@ -878,7 +674,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
}
if (tok == Token::FINALLY) {
Consume(Token::FINALLY);
- ParseBlock(CHECK_OK);
+ ParseBlock(nullptr, CHECK_OK);
if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
// TODO(ishell): update chapter number.
@@ -919,6 +715,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// '(' FormalParameterList? ')' '{' FunctionBody '}'
// Parse function body.
+ PreParserStatementList body;
bool outer_is_script_scope = scope()->is_script_scope();
DeclarationScope* function_scope = NewFunctionScope(kind);
function_scope->SetLanguageMode(language_mode);
@@ -947,7 +744,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
if (is_lazily_parsed) {
ParseLazyFunctionLiteralBody(false, CHECK_OK);
} else {
- ParseStatementList(Token::RBRACE, CHECK_OK);
+ ParseStatementList(body, Token::RBRACE, CHECK_OK);
}
Expect(Token::RBRACE, CHECK_OK);
@@ -1002,8 +799,9 @@ PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) {
PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody(
bool may_abort, bool* ok) {
int body_start = position();
+ PreParserStatementList body;
LazyParsingResult result = ParseStatementList(
- Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
+ body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
if (result == kLazyParsingAborted) return result;
// Position right after terminal '}'.
« src/parsing/parser-base.h ('K') | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698