Chromium Code Reviews| Index: src/parsing/parser.cc |
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
| index d2919e1216e3a32ea3cfb90f5b726bba75854ddb..879719deb477b4d0663626c5c6e20883b5c7981e 100644 |
| --- a/src/parsing/parser.cc |
| +++ b/src/parsing/parser.cc |
| @@ -3322,9 +3322,10 @@ 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) { |
| + DCHECK(!is_destructuring || allow_harmony_destructuring_assignment()); |
| ForOfStatement* for_of = stmt->AsForOfStatement(); |
| if (for_of != NULL) { |
| @@ -3375,6 +3376,10 @@ 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) { |
| + assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| + this, assign_each->AsAssignment(), scope_); |
| + } |
| } |
| for_of->Initialize(each, subject, body, |
| @@ -3383,6 +3388,23 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| result_done, |
| assign_each); |
| } else { |
| + if (is_destructuring) { |
| + Variable* temp = |
| + scope_->NewTemporary(ast_value_factory()->empty_string()); |
| + VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| + Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| + this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
| + RelocInfo::kNoPosition), |
| + scope_); |
| + auto block = |
| + factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition); |
| + block->statements()->Add(factory()->NewExpressionStatement( |
| + assign_each, RelocInfo::kNoPosition), |
| + zone()); |
| + block->statements()->Add(body, zone()); |
| + body = block; |
| + each = factory()->NewVariableProxy(temp); |
| + } |
| stmt->Initialize(each, subject, body); |
| } |
| } |
| @@ -3767,7 +3789,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(); |
| @@ -3818,7 +3841,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 = |
| @@ -3828,9 +3852,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); |
| @@ -3851,7 +3883,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(); |
| @@ -3865,6 +3898,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| return loop; |
| } else { |
| + ValidateExpression(&classifier, CHECK_OK); |
|
caitp (gmail)
2015/12/11 11:19:36
The problem was caused by the left-most expression
|
| init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
| } |
| } |
| @@ -4551,10 +4585,8 @@ class InitializerRewriter : public AstExpressionVisitor { |
| expr->AsRewritableAssignmentExpression(); |
| if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return; |
| - bool ok = true; |
| Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, |
| - scope_, &ok); |
| - DCHECK(ok); |
| + scope_); |
| } |
| private: |
| @@ -6523,10 +6555,7 @@ void Parser::RewriteDestructuringAssignments() { |
| Scope* scope = pair.scope; |
| DCHECK_NOT_NULL(to_rewrite); |
| if (!to_rewrite->is_rewritten()) { |
| - bool ok = true; |
| - PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope, |
| - &ok); |
| - DCHECK(ok); |
| + PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope); |
| } |
| } |
| } |