Commit 51b6a3d1 authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Refactor of Parse*Statement*, part 8

This patch moves the following parsing method to ParserBase:

- ParseForStatement

R=adamk@chromium.org, marja@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2351233002
Cr-Commit-Position: refs/heads/master@{#39587}
parent 2fd6d609
This diff is collapsed.
This diff is collapsed.
......@@ -386,8 +386,6 @@ class Parser : public ParserBase<Parser> {
DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()
};
Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
// !%_IsJSReceiver(result = iterator.next()) &&
// %ThrowIteratorResultNotAnObject(result)
Expression* BuildIteratorNextResult(Expression* iterator, Variable* result,
......@@ -403,10 +401,15 @@ class Parser : public ParserBase<Parser> {
Expression* iterable, Statement* body,
bool finalize,
int next_result_pos = kNoSourcePosition);
Block* RewriteForVarInLegacy(const ForInfo& for_info);
void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
Expression** each_variable, bool* ok);
Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info,
bool* ok);
Statement* DesugarLexicalBindingsInForStatement(
Scope* inner_scope, VariableMode mode,
ZoneList<const AstRawString*>* names, ForStatement* loop, Statement* init,
Expression* cond, Statement* next, Statement* body, bool* ok);
ForStatement* loop, Statement* init, Expression* cond, Statement* next,
Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok);
void DesugarAsyncFunctionBody(Scope* scope, ZoneList<Statement*>* body,
FunctionKind kind, FunctionBodyType type,
......
......@@ -164,140 +164,6 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
}
PreParser::Statement PreParser::ParseForStatement(
ZoneList<const AstRawString*>* labels, bool* ok) {
// ForStatement ::
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
// Create an in-between scope for let-bound iteration variables.
bool has_lexical = false;
BlockState block_state(&scope_state_);
Expect(Token::FOR, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
if (peek() != Token::SEMICOLON) {
ForEachStatement::VisitMode mode;
if (peek() == Token::VAR || peek() == Token::CONST ||
(peek() == Token::LET && IsNextLetKeyword())) {
DeclarationParsingResult parsing_result;
ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
CHECK_OK);
if (parsing_result.descriptor.mode == CONST ||
parsing_result.descriptor.mode == LET) {
has_lexical = true;
}
if (CheckInOrOf(&mode)) {
if (!*ok) return Statement::Default();
if (parsing_result.declarations.length() != 1) {
ReportMessageAt(parsing_result.bindings_loc,
MessageTemplate::kForInOfLoopMultiBindings,
ForEachStatement::VisitModeString(mode));
*ok = false;
return Statement::Default();
}
bool is_binding_pattern =
parsing_result.declarations[0].pattern.IsObjectLiteral() ||
parsing_result.declarations[0].pattern.IsArrayLiteral();
if (parsing_result.first_initializer_loc.IsValid() &&
(is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
has_lexical || is_binding_pattern || allow_harmony_for_in())) {
// Only increment the use count if we would have let this through
// without the flag.
if (use_counts_ != nullptr && allow_harmony_for_in()) {
++use_counts_[v8::Isolate::kForInInitializer];
}
ReportMessageAt(parsing_result.first_initializer_loc,
MessageTemplate::kForInOfLoopInitializer,
ForEachStatement::VisitModeString(mode));
*ok = false;
return Statement::Default();
}
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ParseAssignmentExpression(true, CHECK_OK);
RewriteNonPattern(CHECK_OK);
} else {
ParseExpression(true, CHECK_OK);
}
Expect(Token::RPAREN, CHECK_OK);
{
ReturnExprScope no_tail_calls(function_state_,
ReturnExprContext::kInsideForInOfBody);
ParseScopedStatement(nullptr, true, CHECK_OK);
}
return Statement::Default();
}
} else {
int lhs_beg_pos = peek_position();
ExpressionClassifier classifier(this);
Expression lhs = ParseExpressionCoverGrammar(false, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
bool is_for_each = CheckInOrOf(&mode);
bool is_destructuring = is_for_each &&
(lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
if (is_destructuring) {
ValidateAssignmentPattern(CHECK_OK);
} else {
ValidateExpression(CHECK_OK);
}
if (is_for_each) {
if (!is_destructuring) {
lhs = CheckAndRewriteReferenceExpression(
lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
kSyntaxError, CHECK_OK);
}
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ParseAssignmentExpression(true, CHECK_OK);
RewriteNonPattern(CHECK_OK);
} else {
ParseExpression(true, CHECK_OK);
}
Expect(Token::RPAREN, CHECK_OK);
{
BlockState block_state(&scope_state_);
ParseScopedStatement(nullptr, true, CHECK_OK);
}
return Statement::Default();
}
}
}
// Parsed initializer at this point.
Expect(Token::SEMICOLON, CHECK_OK);
// If there are let bindings, then condition and the next statement of the
// for loop must be parsed in a new scope.
Scope* inner_scope = scope();
// TODO(verwaest): Allocate this through a ScopeState as well.
if (has_lexical) inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
{
BlockState block_state(&scope_state_, inner_scope);
if (peek() != Token::SEMICOLON) {
ParseExpression(true, CHECK_OK);
}
Expect(Token::SEMICOLON, CHECK_OK);
if (peek() != Token::RPAREN) {
ParseExpression(true, CHECK_OK);
}
Expect(Token::RPAREN, CHECK_OK);
ParseScopedStatement(nullptr, true, ok);
}
return Statement::Default();
}
// Redefinition of CHECK_OK for parsing expressions.
#undef CHECK_OK
#define CHECK_OK CHECK_OK_VALUE(Expression::Default())
......
......@@ -451,6 +451,8 @@ class PreParserStatement {
PreParserStatementList statements() { return PreParserStatementList(); }
void set_scope(Scope* scope) {}
void Initialize(PreParserExpression cond, PreParserStatement body) {}
void Initialize(PreParserStatement init, PreParserExpression cond,
PreParserStatement next, PreParserStatement body) {}
private:
enum Type {
......@@ -666,6 +668,17 @@ class PreParserFactory {
return PreParserStatement::Default();
}
PreParserStatement NewForStatement(ZoneList<const AstRawString*>* labels,
int pos) {
return PreParserStatement::Default();
}
PreParserStatement NewForEachStatement(ForEachStatement::VisitMode visit_mode,
ZoneList<const AstRawString*>* labels,
int pos) {
return PreParserStatement::Default();
}
// Return the object itself as AstVisitor and implement the needed
// dummy method right in this class.
PreParserFactory* visitor() { return this; }
......@@ -829,7 +842,6 @@ class PreParser : public ParserBase<PreParser> {
Expression ParseAsyncFunctionExpression(bool* ok);
Statement ParseClassDeclaration(ZoneList<const AstRawString*>* names,
bool default_export, bool* ok);
Statement ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
Expression ParseConditionalExpression(bool accept_IN, bool* ok);
Expression ParseObjectLiteral(bool* ok);
......@@ -1121,6 +1133,38 @@ class PreParser : public ParserBase<PreParser> {
return PreParserExpression::Default();
}
V8_INLINE PreParserStatement
BuildInitializationBlock(DeclarationParsingResult* parsing_result,
ZoneList<const AstRawString*>* names, bool* ok) {
return PreParserStatement::Default();
}
V8_INLINE PreParserStatement
InitializeForEachStatement(PreParserStatement stmt, PreParserExpression each,
PreParserExpression subject,
PreParserStatement body, int each_keyword_pos) {
return stmt;
}
V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) {
return PreParserStatement::Null();
}
V8_INLINE void DesugarBindingInForEachStatement(
ForInfo* for_info, PreParserStatement* body_block,
PreParserExpression* each_variable, bool* ok) {}
V8_INLINE PreParserStatement CreateForEachStatementTDZ(
PreParserStatement init_block, const ForInfo& for_info, bool* ok) {
return init_block;
}
V8_INLINE StatementT DesugarLexicalBindingsInForStatement(
PreParserStatement loop, PreParserStatement init,
PreParserExpression cond, PreParserStatement next,
PreParserStatement body, Scope* inner_scope, const ForInfo& for_info,
bool* ok) {
return loop;
}
V8_INLINE PreParserExpression
NewThrowReferenceError(MessageTemplate::Template message, int pos) {
return PreParserExpression::Default();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment