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

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

Issue 2109733003: Add errors for declarations which conflict with catch parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « src/ast/scopes.h ('k') | test/mjsunit/es6/block-conflicts.js » ('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-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 Expect(Token::LBRACE, CHECK_OK); 3056 Expect(Token::LBRACE, CHECK_OK);
3057 while (peek() != Token::RBRACE) { 3057 while (peek() != Token::RBRACE) {
3058 Statement* stat = ParseStatementListItem(CHECK_OK); 3058 Statement* stat = ParseStatementListItem(CHECK_OK);
3059 if (stat && !stat->IsEmpty()) { 3059 if (stat && !stat->IsEmpty()) {
3060 catch_block->statements()->Add(stat, zone()); 3060 catch_block->statements()->Add(stat, zone());
3061 } 3061 }
3062 } 3062 }
3063 Consume(Token::RBRACE); 3063 Consume(Token::RBRACE);
3064 } 3064 }
3065 block_scope->set_end_position(scanner()->location().end_pos); 3065 block_scope->set_end_position(scanner()->location().end_pos);
3066 if (is_simple) {
3067 // Check for `catch(e) { let e; }` and similar errors.
3068 // The BindingPattern case is handled elsewhere, because
3069 // the names created by destructuring being lexical.
3070 Variable* var = block_scope->LookupLocal(name);
3071 if (var != nullptr && IsLexicalVariableMode(var->mode())) {
3072 auto position = pattern->position();
3073 Scanner::Location location =
3074 position == RelocInfo::kNoPosition
3075 ? Scanner::Location::invalid()
3076 : Scanner::Location(position, position + 1);
3077 ParserTraits::ReportMessageAt(
3078 location, MessageTemplate::kVarRedeclaration, name);
3079 *ok = false;
3080 return NULL;
3081 }
3082 }
3066 block_scope = block_scope->FinalizeBlockScope(); 3083 block_scope = block_scope->FinalizeBlockScope();
3067 catch_block->set_scope(block_scope); 3084 catch_block->set_scope(block_scope);
3068 } 3085 }
3069 3086
3070 catch_scope->set_end_position(scanner()->location().end_pos); 3087 catch_scope->set_end_position(scanner()->location().end_pos);
3071 tok = peek(); 3088 tok = peek();
3072 } 3089 }
3073 3090
3074 Block* finally_block = NULL; 3091 Block* finally_block = NULL;
3075 DCHECK(tok == Token::FINALLY || catch_block != NULL); 3092 DCHECK(tok == Token::FINALLY || catch_block != NULL);
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 body_scope = body_scope->FinalizeBlockScope(); 3578 body_scope = body_scope->FinalizeBlockScope();
3562 block->set_scope(body_scope); 3579 block->set_scope(body_scope);
3563 return block; 3580 return block;
3564 } 3581 }
3565 } 3582 }
3566 3583
3567 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3584 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3568 bool* ok) { 3585 bool* ok) {
3569 int stmt_pos = peek_position(); 3586 int stmt_pos = peek_position();
3570 Statement* init = NULL; 3587 Statement* init = NULL;
3571 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3588 ZoneList<const AstRawString*> bound_names(1, zone());
3589 bool bound_names_are_lexical = false;
3572 3590
3573 // Create an in-between scope for let-bound iteration variables. 3591 // Create an in-between scope for let-bound iteration variables.
3574 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3592 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3575 3593
3576 BlockState block_state(&scope_, for_scope); 3594 BlockState block_state(&scope_, for_scope);
3577 Expect(Token::FOR, CHECK_OK); 3595 Expect(Token::FOR, CHECK_OK);
3578 Expect(Token::LPAREN, CHECK_OK); 3596 Expect(Token::LPAREN, CHECK_OK);
3579 for_scope->set_start_position(scanner()->location().beg_pos); 3597 for_scope->set_start_position(scanner()->location().beg_pos);
3580 for_scope->set_is_hidden(); 3598 for_scope->set_is_hidden();
3581 DeclarationParsingResult parsing_result; 3599 DeclarationParsingResult parsing_result;
(...skipping 30 matching lines...) Expand all
3612 } 3630 }
3613 ParserTraits::ReportMessageAt( 3631 ParserTraits::ReportMessageAt(
3614 parsing_result.first_initializer_loc, 3632 parsing_result.first_initializer_loc,
3615 MessageTemplate::kForInOfLoopInitializer, 3633 MessageTemplate::kForInOfLoopInitializer,
3616 ForEachStatement::VisitModeString(mode)); 3634 ForEachStatement::VisitModeString(mode));
3617 *ok = false; 3635 *ok = false;
3618 return nullptr; 3636 return nullptr;
3619 } 3637 }
3620 3638
3621 Block* init_block = nullptr; 3639 Block* init_block = nullptr;
3640 bound_names_are_lexical =
3641 IsLexicalVariableMode(parsing_result.descriptor.mode);
3622 3642
3623 // special case for legacy for (var/const x =.... in) 3643 // special case for legacy for (var/const x =.... in)
Dan Ehrenberg 2016/06/29 20:24:32 It's only var at this point, right? Could you chan
bakkot 2016/06/29 21:10:13 Done, and in a few other places.
3624 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && 3644 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() &&
3625 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { 3645 decl.initializer != nullptr) {
3626 DCHECK(!allow_harmony_for_in()); 3646 DCHECK(!allow_harmony_for_in());
3627 ++use_counts_[v8::Isolate::kForInInitializer]; 3647 ++use_counts_[v8::Isolate::kForInInitializer];
3628 const AstRawString* name = 3648 const AstRawString* name =
3629 decl.pattern->AsVariableProxy()->raw_name(); 3649 decl.pattern->AsVariableProxy()->raw_name();
3630 VariableProxy* single_var = scope_->NewUnresolved( 3650 VariableProxy* single_var = scope_->NewUnresolved(
3631 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); 3651 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos);
3632 init_block = factory()->NewBlock( 3652 init_block = factory()->NewBlock(
3633 nullptr, 2, true, parsing_result.descriptor.declaration_pos); 3653 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3634 init_block->statements()->Add( 3654 init_block->statements()->Add(
3635 factory()->NewExpressionStatement( 3655 factory()->NewExpressionStatement(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3691 auto each_initialization_block = 3711 auto each_initialization_block =
3692 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 3712 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3693 { 3713 {
3694 auto descriptor = parsing_result.descriptor; 3714 auto descriptor = parsing_result.descriptor;
3695 descriptor.declaration_pos = RelocInfo::kNoPosition; 3715 descriptor.declaration_pos = RelocInfo::kNoPosition;
3696 descriptor.initialization_pos = RelocInfo::kNoPosition; 3716 descriptor.initialization_pos = RelocInfo::kNoPosition;
3697 decl.initializer = factory()->NewVariableProxy(temp); 3717 decl.initializer = factory()->NewVariableProxy(temp);
3698 3718
3699 PatternRewriter::DeclareAndInitializeVariables( 3719 PatternRewriter::DeclareAndInitializeVariables(
3700 each_initialization_block, &descriptor, &decl, 3720 each_initialization_block, &descriptor, &decl,
3701 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3721 bound_names_are_lexical ||
3702 : nullptr, 3722 (mode == ForEachStatement::ITERATE &&
3723 parsing_result.descriptor.mode == VariableMode::VAR)
Dan Ehrenberg 2016/06/29 20:24:32 Minor cleanup suggestion: since it occurs multiple
bakkot 2016/06/29 21:10:13 Done.
3724 ? &bound_names
3725 : nullptr,
3703 CHECK_OK); 3726 CHECK_OK);
3727
3728 // Annex B.3.5 prohibits the form
3729 // `try {} catch(e) { for (var e of {}); }`
3730 // So if we are parsing a statement like `for (var ... of ...)`
3731 // we need to walk up the scope chain and look for catch scopes
3732 // which have a simple binding, then compare their binding against
3733 // all of the names declared in the init of the for-of we're
3734 // parsing.
3735 if (mode == ForEachStatement::ITERATE &&
3736 parsing_result.descriptor.mode == VariableMode::VAR) {
3737 Scope* catch_scope = scope_;
3738 while (catch_scope != nullptr &&
3739 !catch_scope->is_declaration_scope()) {
3740 if (catch_scope->is_catch_scope()) {
3741 auto name = catch_scope->catch_variable_name();
3742 if (name !=
3743 ast_value_factory()
3744 ->dot_catch_string()) { // i.e. is a simple binding
3745 if (bound_names.Contains(name)) {
3746 ParserTraits::ReportMessageAt(
3747 parsing_result.bindings_loc,
3748 MessageTemplate::kVarRedeclaration, name);
3749 *ok = false;
3750 return nullptr;
3751 }
3752 }
3753 }
3754 catch_scope = catch_scope->outer_scope();
3755 }
3756 }
3704 } 3757 }
3705 3758
3706 body_block->statements()->Add(each_initialization_block, zone()); 3759 body_block->statements()->Add(each_initialization_block, zone());
3707 body_block->statements()->Add(body, zone()); 3760 body_block->statements()->Add(body, zone());
3708 VariableProxy* temp_proxy = 3761 VariableProxy* temp_proxy =
3709 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3762 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3710 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, 3763 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3711 each_keyword_position); 3764 each_keyword_position);
3712 } 3765 }
3713 body_scope->set_end_position(scanner()->location().end_pos); 3766 body_scope->set_end_position(scanner()->location().end_pos);
3714 body_scope = body_scope->FinalizeBlockScope(); 3767 body_scope = body_scope->FinalizeBlockScope();
3715 body_block->set_scope(body_scope); 3768 body_block->set_scope(body_scope);
3716 3769
3717 // Create a TDZ for any lexically-bound names. 3770 // Create a TDZ for any lexically-bound names.
3718 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3771 if (bound_names_are_lexical) {
3719 DCHECK_NULL(init_block); 3772 DCHECK_NULL(init_block);
3720 3773
3721 init_block = 3774 init_block =
3722 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); 3775 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3723 3776
3724 for (int i = 0; i < lexical_bindings.length(); ++i) { 3777 for (int i = 0; i < bound_names.length(); ++i) {
3725 // TODO(adamk): This needs to be some sort of special 3778 // TODO(adamk): This needs to be some sort of special
3726 // INTERNAL variable that's invisible to the debugger 3779 // INTERNAL variable that's invisible to the debugger
3727 // but visible to everything else. 3780 // but visible to everything else.
3728 VariableProxy* tdz_proxy = 3781 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET);
3729 NewUnresolved(lexical_bindings[i], LET);
3730 Declaration* tdz_decl = factory()->NewVariableDeclaration( 3782 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3731 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); 3783 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3732 Variable* tdz_var = Declare( 3784 Variable* tdz_var = Declare(
3733 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3785 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3734 tdz_var->set_initializer_position(position()); 3786 tdz_var->set_initializer_position(position());
3735 } 3787 }
3736 } 3788 }
3737 3789
3738 Statement* final_loop = loop->IsForOfStatement() 3790 Statement* final_loop = loop->IsForOfStatement()
3739 ? FinalizeForOfStatement( 3791 ? FinalizeForOfStatement(
3740 loop->AsForOfStatement(), RelocInfo::kNoPosition) 3792 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3741 : loop; 3793 : loop;
3742 3794
3743 for_scope->set_end_position(scanner()->location().end_pos); 3795 for_scope->set_end_position(scanner()->location().end_pos);
3744 for_scope = for_scope->FinalizeBlockScope(); 3796 for_scope = for_scope->FinalizeBlockScope();
3745 // Parsed for-in loop w/ variable declarations. 3797 // Parsed for-in loop w/ variable declarations.
3746 if (init_block != nullptr) { 3798 if (init_block != nullptr) {
3747 init_block->statements()->Add(final_loop, zone()); 3799 init_block->statements()->Add(final_loop, zone());
3748 init_block->set_scope(for_scope); 3800 init_block->set_scope(for_scope);
3749 return init_block; 3801 return init_block;
3750 } else { 3802 } else {
3751 DCHECK_NULL(for_scope); 3803 DCHECK_NULL(for_scope);
3752 return final_loop; 3804 return final_loop;
3753 } 3805 }
3754 } else { 3806 } else {
3807 bound_names_are_lexical =
3808 IsLexicalVariableMode(parsing_result.descriptor.mode);
3755 init = parsing_result.BuildInitializationBlock( 3809 init = parsing_result.BuildInitializationBlock(
3756 IsLexicalVariableMode(parsing_result.descriptor.mode) 3810 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK);
3757 ? &lexical_bindings
3758 : nullptr,
3759 CHECK_OK);
3760 } 3811 }
3761 } else { 3812 } else {
3762 int lhs_beg_pos = peek_position(); 3813 int lhs_beg_pos = peek_position();
3763 ExpressionClassifier classifier(this); 3814 ExpressionClassifier classifier(this);
3764 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); 3815 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3765 int lhs_end_pos = scanner()->location().end_pos; 3816 int lhs_end_pos = scanner()->location().end_pos;
3766 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3817 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3767 3818
3768 bool is_for_each = CheckInOrOf(&mode, ok); 3819 bool is_for_each = CheckInOrOf(&mode, ok);
3769 if (!*ok) return nullptr; 3820 if (!*ok) return nullptr;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3829 // Parsed initializer at this point. 3880 // Parsed initializer at this point.
3830 Expect(Token::SEMICOLON, CHECK_OK); 3881 Expect(Token::SEMICOLON, CHECK_OK);
3831 3882
3832 Expression* cond = NULL; 3883 Expression* cond = NULL;
3833 Statement* next = NULL; 3884 Statement* next = NULL;
3834 Statement* body = NULL; 3885 Statement* body = NULL;
3835 3886
3836 // If there are let bindings, then condition and the next statement of the 3887 // If there are let bindings, then condition and the next statement of the
3837 // for loop must be parsed in a new scope. 3888 // for loop must be parsed in a new scope.
3838 Scope* inner_scope = scope_; 3889 Scope* inner_scope = scope_;
3839 if (lexical_bindings.length() > 0) { 3890 if (bound_names_are_lexical && bound_names.length() > 0) {
3840 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3891 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3841 inner_scope->set_start_position(scanner()->location().beg_pos); 3892 inner_scope->set_start_position(scanner()->location().beg_pos);
3842 } 3893 }
3843 { 3894 {
3844 BlockState block_state(&scope_, inner_scope); 3895 BlockState block_state(&scope_, inner_scope);
3845 3896
3846 if (peek() != Token::SEMICOLON) { 3897 if (peek() != Token::SEMICOLON) {
3847 cond = ParseExpression(true, CHECK_OK); 3898 cond = ParseExpression(true, CHECK_OK);
3848 } 3899 }
3849 Expect(Token::SEMICOLON, CHECK_OK); 3900 Expect(Token::SEMICOLON, CHECK_OK);
3850 3901
3851 if (peek() != Token::RPAREN) { 3902 if (peek() != Token::RPAREN) {
3852 Expression* exp = ParseExpression(true, CHECK_OK); 3903 Expression* exp = ParseExpression(true, CHECK_OK);
3853 next = factory()->NewExpressionStatement(exp, exp->position()); 3904 next = factory()->NewExpressionStatement(exp, exp->position());
3854 } 3905 }
3855 Expect(Token::RPAREN, CHECK_OK); 3906 Expect(Token::RPAREN, CHECK_OK);
3856 3907
3857 body = ParseScopedStatement(NULL, true, CHECK_OK); 3908 body = ParseScopedStatement(NULL, true, CHECK_OK);
3858 } 3909 }
3859 3910
3860 Statement* result = NULL; 3911 Statement* result = NULL;
3861 if (lexical_bindings.length() > 0) { 3912 if (bound_names_are_lexical && bound_names.length() > 0) {
3862 BlockState block_state(&scope_, for_scope); 3913 BlockState block_state(&scope_, for_scope);
3863 result = DesugarLexicalBindingsInForStatement( 3914 result = DesugarLexicalBindingsInForStatement(
3864 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, 3915 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
3865 init, cond, next, body, CHECK_OK); 3916 cond, next, body, CHECK_OK);
3866 for_scope->set_end_position(scanner()->location().end_pos); 3917 for_scope->set_end_position(scanner()->location().end_pos);
3867 } else { 3918 } else {
3868 for_scope->set_end_position(scanner()->location().end_pos); 3919 for_scope->set_end_position(scanner()->location().end_pos);
3869 for_scope = for_scope->FinalizeBlockScope(); 3920 for_scope = for_scope->FinalizeBlockScope();
3870 if (for_scope) { 3921 if (for_scope) {
3871 // Rewrite a for statement of the form 3922 // Rewrite a for statement of the form
3872 // for (const x = i; c; n) b 3923 // for (const x = i; c; n) b
3873 // 3924 //
3874 // into 3925 // into
3875 // 3926 //
(...skipping 3113 matching lines...) Expand 10 before | Expand all | Expand 10 after
6989 try_block, target); 7040 try_block, target);
6990 final_loop = target; 7041 final_loop = target;
6991 } 7042 }
6992 7043
6993 return final_loop; 7044 return final_loop;
6994 } 7045 }
6995 7046
6996 7047
6997 } // namespace internal 7048 } // namespace internal
6998 } // namespace v8 7049 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | test/mjsunit/es6/block-conflicts.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698