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

Unified Diff: src/parsing/parser.cc

Issue 1508933004: [es6] support AssignmentPattern as LHS in for-in/of loops (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Don't reuse VariableProxy ast node Created 5 years 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
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index ccb106598db55002acf5d4dd0d0534bda03465cb..8e17f478dd1c14a6f8be6a755769e83da744032b 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -3326,9 +3326,9 @@ Expression* Parser::BuildIteratorNextResult(Expression* iterator,
void Parser::InitializeForEachStatement(ForEachStatement* stmt,
- Expression* each,
- Expression* subject,
- Statement* body) {
+ Expression* each, Expression* subject,
+ Statement* body,
+ bool is_destructuring) {
ForOfStatement* for_of = stmt->AsForOfStatement();
if (for_of != NULL) {
@@ -3379,6 +3379,16 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
result_proxy, value_literal, RelocInfo::kNoPosition);
assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
RelocInfo::kNoPosition);
+ if (is_destructuring) {
+ DCHECK(allow_harmony_destructuring_assignment());
+ bool ok = true;
+ auto rewrite =
+ factory()->NewRewritableAssignmentExpression(assign_each);
adamk 2015/12/10 17:28:03 Making the callers here and below construct a Rewr
caitp (gmail) 2015/12/10 18:19:35 Done
+ PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_,
+ &ok);
+ DCHECK(ok);
adamk 2015/12/10 17:28:03 It looks like all callers of RewriteDestructuringA
caitp (gmail) 2015/12/10 18:19:36 Done.
+ assign_each = rewrite->expression();
+ }
}
for_of->Initialize(each, subject, body,
@@ -3387,6 +3397,27 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
result_done,
assign_each);
} else {
+ if (is_destructuring) {
+ Variable* temp =
+ scope_->NewTemporary(ast_value_factory()->dot_result_string());
adamk 2015/12/10 17:28:03 dot_result_string has a special usage (for complet
caitp (gmail) 2015/12/10 18:19:36 I think this is the completion-correct model, and
adamk 2015/12/10 19:23:33 If there's a reason for it to be .result, I'd expe
+ VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
+ bool ok = true;
+ auto rewrite =
+ factory()->NewRewritableAssignmentExpression(factory()->NewAssignment(
+ Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition));
+ PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_,
+ &ok);
+ DCHECK(ok);
+ auto block =
+ factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
+ block->statements()->Add(
+ factory()->NewExpressionStatement(rewrite->expression(),
+ RelocInfo::kNoPosition),
+ zone());
+ block->statements()->Add(body, zone());
+ body = block;
+ each = factory()->NewVariableProxy(temp);
+ }
stmt->Initialize(each, subject, body);
}
}
@@ -3771,7 +3802,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
body_block->statements()->Add(body, zone());
VariableProxy* temp_proxy =
factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
- InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
+ InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
+ false);
scope_ = for_scope;
body_scope->set_end_position(scanner()->location().end_pos);
body_scope = body_scope->FinalizeBlockScope();
@@ -3822,7 +3854,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
}
} else {
int lhs_beg_pos = peek_position();
- Expression* expression = ParseExpression(false, CHECK_OK);
+ ExpressionClassifier classifier;
+ Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
ForEachStatement::VisitMode mode;
is_let_identifier_expression =
@@ -3832,9 +3865,17 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
if (CheckInOrOf(&mode, ok)) {
if (!*ok) return nullptr;
- expression = this->CheckAndRewriteReferenceExpression(
- expression, lhs_beg_pos, lhs_end_pos,
- MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
+ bool is_destructuring =
+ allow_harmony_destructuring_assignment() &&
+ (expression->IsArrayLiteral() || expression->IsObjectLiteral());
+ if (is_destructuring) {
+ ValidateAssignmentPattern(&classifier, CHECK_OK);
+ } else {
+ ValidateExpression(&classifier, CHECK_OK);
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_beg_pos, lhs_end_pos,
+ MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
+ }
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
@@ -3855,7 +3896,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
Statement* body = ParseSubStatement(NULL, CHECK_OK);
block->statements()->Add(body, zone());
- InitializeForEachStatement(loop, expression, enumerable, block);
+ InitializeForEachStatement(loop, expression, enumerable, block,
+ is_destructuring);
scope_ = saved_scope;
body_scope->set_end_position(scanner()->location().end_pos);
body_scope = body_scope->FinalizeBlockScope();
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/preparser.cc » ('j') | src/parsing/preparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698