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

Side by Side Diff: src/parsing/parser.cc

Issue 1517973002: [es6] support AssignmentPattern as LHS in for-in/of loops (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Centralize the error validation to a single place, to ease confusion 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 unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-visitor.h" 9 #include "src/ast/ast-expression-visitor.h"
10 #include "src/ast/ast-literal-reindexer.h" 10 #include "src/ast/ast-literal-reindexer.h"
(...skipping 3304 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 3315 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3316 3316
3317 return factory()->NewBinaryOperation( 3317 return factory()->NewBinaryOperation(
3318 Token::AND, 3318 Token::AND,
3319 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 3319 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3320 throw_call, pos); 3320 throw_call, pos);
3321 } 3321 }
3322 3322
3323 3323
3324 void Parser::InitializeForEachStatement(ForEachStatement* stmt, 3324 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3325 Expression* each, 3325 Expression* each, Expression* subject,
3326 Expression* subject, 3326 Statement* body,
3327 Statement* body) { 3327 bool is_destructuring) {
3328 DCHECK(!is_destructuring || allow_harmony_destructuring_assignment());
3328 ForOfStatement* for_of = stmt->AsForOfStatement(); 3329 ForOfStatement* for_of = stmt->AsForOfStatement();
3329 3330
3330 if (for_of != NULL) { 3331 if (for_of != NULL) {
3331 Variable* iterator = scope_->NewTemporary( 3332 Variable* iterator = scope_->NewTemporary(
3332 ast_value_factory()->dot_iterator_string()); 3333 ast_value_factory()->dot_iterator_string());
3333 Variable* result = scope_->NewTemporary( 3334 Variable* result = scope_->NewTemporary(
3334 ast_value_factory()->dot_result_string()); 3335 ast_value_factory()->dot_result_string());
3335 3336
3336 Expression* assign_iterator; 3337 Expression* assign_iterator;
3337 Expression* next_result; 3338 Expression* next_result;
(...skipping 30 matching lines...) Expand all
3368 3369
3369 // each = result.value 3370 // each = result.value
3370 { 3371 {
3371 Expression* value_literal = factory()->NewStringLiteral( 3372 Expression* value_literal = factory()->NewStringLiteral(
3372 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 3373 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3373 Expression* result_proxy = factory()->NewVariableProxy(result); 3374 Expression* result_proxy = factory()->NewVariableProxy(result);
3374 Expression* result_value = factory()->NewProperty( 3375 Expression* result_value = factory()->NewProperty(
3375 result_proxy, value_literal, RelocInfo::kNoPosition); 3376 result_proxy, value_literal, RelocInfo::kNoPosition);
3376 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3377 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3377 RelocInfo::kNoPosition); 3378 RelocInfo::kNoPosition);
3379 if (is_destructuring) {
3380 assign_each = PatternRewriter::RewriteDestructuringAssignment(
3381 this, assign_each->AsAssignment(), scope_);
3382 }
3378 } 3383 }
3379 3384
3380 for_of->Initialize(each, subject, body, 3385 for_of->Initialize(each, subject, body,
3381 assign_iterator, 3386 assign_iterator,
3382 next_result, 3387 next_result,
3383 result_done, 3388 result_done,
3384 assign_each); 3389 assign_each);
3385 } else { 3390 } else {
3391 if (is_destructuring) {
3392 Variable* temp =
3393 scope_->NewTemporary(ast_value_factory()->empty_string());
3394 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3395 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
3396 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
3397 RelocInfo::kNoPosition),
3398 scope_);
3399 auto block =
3400 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
3401 block->statements()->Add(factory()->NewExpressionStatement(
3402 assign_each, RelocInfo::kNoPosition),
3403 zone());
3404 block->statements()->Add(body, zone());
3405 body = block;
3406 each = factory()->NewVariableProxy(temp);
3407 }
3386 stmt->Initialize(each, subject, body); 3408 stmt->Initialize(each, subject, body);
3387 } 3409 }
3388 } 3410 }
3389 3411
3390 3412
3391 Statement* Parser::DesugarLexicalBindingsInForStatement( 3413 Statement* Parser::DesugarLexicalBindingsInForStatement(
3392 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3414 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3393 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3415 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3394 Statement* body, bool* ok) { 3416 Statement* body, bool* ok) {
3395 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 3417 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
3760 each_initialization_block, &descriptor, &decl, 3782 each_initialization_block, &descriptor, &decl,
3761 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3783 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3762 : nullptr, 3784 : nullptr,
3763 CHECK_OK); 3785 CHECK_OK);
3764 } 3786 }
3765 3787
3766 body_block->statements()->Add(each_initialization_block, zone()); 3788 body_block->statements()->Add(each_initialization_block, zone());
3767 body_block->statements()->Add(body, zone()); 3789 body_block->statements()->Add(body, zone());
3768 VariableProxy* temp_proxy = 3790 VariableProxy* temp_proxy =
3769 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3791 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3770 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3792 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3793 false);
3771 scope_ = for_scope; 3794 scope_ = for_scope;
3772 body_scope->set_end_position(scanner()->location().end_pos); 3795 body_scope->set_end_position(scanner()->location().end_pos);
3773 body_scope = body_scope->FinalizeBlockScope(); 3796 body_scope = body_scope->FinalizeBlockScope();
3774 if (body_scope != nullptr) { 3797 if (body_scope != nullptr) {
3775 body_block->set_scope(body_scope); 3798 body_block->set_scope(body_scope);
3776 } 3799 }
3777 3800
3778 // Create a TDZ for any lexically-bound names. 3801 // Create a TDZ for any lexically-bound names.
3779 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3802 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3780 DCHECK_NULL(init_block); 3803 DCHECK_NULL(init_block);
(...skipping 30 matching lines...) Expand all
3811 } 3834 }
3812 } else { 3835 } else {
3813 init = parsing_result.BuildInitializationBlock( 3836 init = parsing_result.BuildInitializationBlock(
3814 IsLexicalVariableMode(parsing_result.descriptor.mode) 3837 IsLexicalVariableMode(parsing_result.descriptor.mode)
3815 ? &lexical_bindings 3838 ? &lexical_bindings
3816 : nullptr, 3839 : nullptr,
3817 CHECK_OK); 3840 CHECK_OK);
3818 } 3841 }
3819 } else { 3842 } else {
3820 int lhs_beg_pos = peek_position(); 3843 int lhs_beg_pos = peek_position();
3821 Expression* expression = ParseExpression(false, CHECK_OK); 3844 ExpressionClassifier classifier;
3845 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3822 int lhs_end_pos = scanner()->location().end_pos; 3846 int lhs_end_pos = scanner()->location().end_pos;
3823 ForEachStatement::VisitMode mode; 3847 ForEachStatement::VisitMode mode;
3824 is_let_identifier_expression = 3848 is_let_identifier_expression =
3825 expression->IsVariableProxy() && 3849 expression->IsVariableProxy() &&
3826 expression->AsVariableProxy()->raw_name() == 3850 expression->AsVariableProxy()->raw_name() ==
3827 ast_value_factory()->let_string(); 3851 ast_value_factory()->let_string();
3828 3852
3829 if (CheckInOrOf(&mode, ok)) { 3853 bool is_for_each = CheckInOrOf(&mode, ok);
3830 if (!*ok) return nullptr; 3854 if (!*ok) return nullptr;
3831 expression = this->CheckAndRewriteReferenceExpression( 3855 bool is_destructuring =
3832 expression, lhs_beg_pos, lhs_end_pos, 3856 is_for_each && allow_harmony_destructuring_assignment() &&
3833 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); 3857 (expression->IsArrayLiteral() || expression->IsObjectLiteral());
3858
3859 if (is_destructuring) {
3860 ValidateAssignmentPattern(&classifier, CHECK_OK);
3861 } else {
3862 ValidateExpression(&classifier, CHECK_OK);
3863 }
3864
3865 if (is_for_each) {
3866 if (!is_destructuring) {
3867 expression = this->CheckAndRewriteReferenceExpression(
3868 expression, lhs_beg_pos, lhs_end_pos,
3869 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3870 }
3834 3871
3835 ForEachStatement* loop = 3872 ForEachStatement* loop =
3836 factory()->NewForEachStatement(mode, labels, stmt_pos); 3873 factory()->NewForEachStatement(mode, labels, stmt_pos);
3837 Target target(&this->target_stack_, loop); 3874 Target target(&this->target_stack_, loop);
3838 3875
3839 Expression* enumerable = ParseExpression(true, CHECK_OK); 3876 Expression* enumerable = ParseExpression(true, CHECK_OK);
3840 Expect(Token::RPAREN, CHECK_OK); 3877 Expect(Token::RPAREN, CHECK_OK);
3841 3878
3842 // Make a block around the statement in case a lexical binding 3879 // Make a block around the statement in case a lexical binding
3843 // is introduced, e.g. by a FunctionDeclaration. 3880 // is introduced, e.g. by a FunctionDeclaration.
3844 // This block must not use for_scope as its scope because if a 3881 // This block must not use for_scope as its scope because if a
3845 // lexical binding is introduced which overlaps with the for-in/of, 3882 // lexical binding is introduced which overlaps with the for-in/of,
3846 // expressions in head of the loop should actually have variables 3883 // expressions in head of the loop should actually have variables
3847 // resolved in the outer scope. 3884 // resolved in the outer scope.
3848 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); 3885 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3849 scope_ = body_scope; 3886 scope_ = body_scope;
3850 Block* block = 3887 Block* block =
3851 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3888 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3852 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3889 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3853 block->statements()->Add(body, zone()); 3890 block->statements()->Add(body, zone());
3854 InitializeForEachStatement(loop, expression, enumerable, block); 3891 InitializeForEachStatement(loop, expression, enumerable, block,
3892 is_destructuring);
3855 scope_ = saved_scope; 3893 scope_ = saved_scope;
3856 body_scope->set_end_position(scanner()->location().end_pos); 3894 body_scope->set_end_position(scanner()->location().end_pos);
3857 body_scope = body_scope->FinalizeBlockScope(); 3895 body_scope = body_scope->FinalizeBlockScope();
3858 if (body_scope != nullptr) { 3896 if (body_scope != nullptr) {
3859 block->set_scope(body_scope); 3897 block->set_scope(body_scope);
3860 } 3898 }
3861 for_scope->set_end_position(scanner()->location().end_pos); 3899 for_scope->set_end_position(scanner()->location().end_pos);
3862 for_scope = for_scope->FinalizeBlockScope(); 3900 for_scope = for_scope->FinalizeBlockScope();
3863 DCHECK(for_scope == nullptr); 3901 DCHECK(for_scope == nullptr);
3864 // Parsed for-in loop. 3902 // Parsed for-in loop.
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 : AstExpressionVisitor(stack_limit, root), 4582 : AstExpressionVisitor(stack_limit, root),
4545 parser_(parser), 4583 parser_(parser),
4546 scope_(scope) {} 4584 scope_(scope) {}
4547 4585
4548 private: 4586 private:
4549 void VisitExpression(Expression* expr) { 4587 void VisitExpression(Expression* expr) {
4550 RewritableAssignmentExpression* to_rewrite = 4588 RewritableAssignmentExpression* to_rewrite =
4551 expr->AsRewritableAssignmentExpression(); 4589 expr->AsRewritableAssignmentExpression();
4552 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return; 4590 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
4553 4591
4554 bool ok = true;
4555 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, 4592 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
4556 scope_, &ok); 4593 scope_);
4557 DCHECK(ok);
4558 } 4594 }
4559 4595
4560 private: 4596 private:
4561 Parser* parser_; 4597 Parser* parser_;
4562 Scope* scope_; 4598 Scope* scope_;
4563 }; 4599 };
4564 4600
4565 4601
4566 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { 4602 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
4567 InitializerRewriter rewriter(stack_limit_, expr, this, scope); 4603 InitializerRewriter rewriter(stack_limit_, expr, this, scope);
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after
6516 func->destructuring_assignments_to_rewrite(); 6552 func->destructuring_assignments_to_rewrite();
6517 for (int i = assignments.length() - 1; i >= 0; --i) { 6553 for (int i = assignments.length() - 1; i >= 0; --i) {
6518 // Rewrite list in reverse, so that nested assignment patterns are rewritten 6554 // Rewrite list in reverse, so that nested assignment patterns are rewritten
6519 // correctly. 6555 // correctly.
6520 DestructuringAssignment pair = assignments.at(i); 6556 DestructuringAssignment pair = assignments.at(i);
6521 RewritableAssignmentExpression* to_rewrite = 6557 RewritableAssignmentExpression* to_rewrite =
6522 pair.assignment->AsRewritableAssignmentExpression(); 6558 pair.assignment->AsRewritableAssignmentExpression();
6523 Scope* scope = pair.scope; 6559 Scope* scope = pair.scope;
6524 DCHECK_NOT_NULL(to_rewrite); 6560 DCHECK_NOT_NULL(to_rewrite);
6525 if (!to_rewrite->is_rewritten()) { 6561 if (!to_rewrite->is_rewritten()) {
6526 bool ok = true; 6562 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
6527 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope,
6528 &ok);
6529 DCHECK(ok);
6530 } 6563 }
6531 } 6564 }
6532 } 6565 }
6533 6566
6534 6567
6535 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 6568 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
6536 DCHECK(expr->IsRewritableAssignmentExpression()); 6569 DCHECK(expr->IsRewritableAssignmentExpression());
6537 parser_->function_state_->AddDestructuringAssignment( 6570 parser_->function_state_->AddDestructuringAssignment(
6538 Parser::DestructuringAssignment(expr, parser_->scope_)); 6571 Parser::DestructuringAssignment(expr, parser_->scope_));
6539 } 6572 }
6540 6573
6541 6574
6542 } // namespace internal 6575 } // namespace internal
6543 } // namespace v8 6576 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698