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

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: correct loop index 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
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 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 1922
1923 default: 1923 default:
1924 UNREACHABLE(); 1924 UNREACHABLE();
1925 return NULL; 1925 return NULL;
1926 } 1926 }
1927 } 1927 }
1928 1928
1929 1929
1930 VariableProxy* Parser::NewUnresolved(const AstRawString* name, 1930 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1931 VariableMode mode) { 1931 VariableMode mode) {
1932 // If we are inside a function, a declaration of a var/const variable is a 1932 // If we are inside a function, a declaration of a 'var' variable is a
1933 // truly local variable, and the scope of the variable is always the function 1933 // truly local variable, and the scope of the variable is always the function
1934 // scope. 1934 // scope.
1935 // Let/const variables in harmony mode are always added to the immediately 1935 // Let/const variables are always added to the immediately enclosing scope.
1936 // enclosing scope.
1937 Scope* scope = 1936 Scope* scope =
1938 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); 1937 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope();
1939 return scope->NewUnresolved(factory(), name, Variable::NORMAL, 1938 return scope->NewUnresolved(factory(), name, Variable::NORMAL,
1940 scanner()->location().beg_pos, 1939 scanner()->location().beg_pos,
1941 scanner()->location().end_pos); 1940 scanner()->location().end_pos);
1942 } 1941 }
1943 1942
1944 1943
1945 Variable* Parser::Declare(Declaration* declaration, 1944 Variable* Parser::Declare(Declaration* declaration,
1946 DeclarationDescriptor::Kind declaration_kind, 1945 DeclarationDescriptor::Kind declaration_kind,
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 return result; 2318 return result;
2320 } 2319 }
2321 2320
2322 2321
2323 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 2322 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2324 ZoneList<const AstRawString*>* names, 2323 ZoneList<const AstRawString*>* names,
2325 bool* ok) { 2324 bool* ok) {
2326 // VariableStatement :: 2325 // VariableStatement ::
2327 // VariableDeclarations ';' 2326 // VariableDeclarations ';'
2328 2327
2329 // The scope of a var/const declared variable anywhere inside a function 2328 // The scope of a var declared variable anywhere inside a function
2330 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 2329 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2331 // transform a source-level var/const declaration into a (Function) 2330 // transform a source-level var declaration into a (Function) Scope
2332 // Scope declaration, and rewrite the source-level initialization into an 2331 // declaration, and rewrite the source-level initialization into an assignment
2333 // assignment statement. We use a block to collect multiple assignments. 2332 // statement. We use a block to collect multiple assignments.
2334 // 2333 //
2335 // We mark the block as initializer block because we don't want the 2334 // We mark the block as initializer block because we don't want the
2336 // rewriter to add a '.result' assignment to such a block (to get compliant 2335 // rewriter to add a '.result' assignment to such a block (to get compliant
2337 // behavior for code such as print(eval('var x = 7')), and for cosmetic 2336 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2338 // reasons when pretty-printing. Also, unless an assignment (initialization) 2337 // reasons when pretty-printing. Also, unless an assignment (initialization)
2339 // is inside an initializer block, it is ignored. 2338 // is inside an initializer block, it is ignored.
2340 2339
2341 DeclarationParsingResult parsing_result; 2340 DeclarationParsingResult parsing_result;
2342 Block* result = 2341 Block* result =
2343 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); 2342 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 if (is_simple) { 3020 if (is_simple) {
3022 auto proxy = pattern->AsVariableProxy(); 3021 auto proxy = pattern->AsVariableProxy();
3023 scope_->RemoveUnresolved(proxy); 3022 scope_->RemoveUnresolved(proxy);
3024 name = proxy->raw_name(); 3023 name = proxy->raw_name();
3025 } 3024 }
3026 catch_variable = catch_scope->DeclareLocal( 3025 catch_variable = catch_scope->DeclareLocal(
3027 name, VAR, kCreatedInitialized, Variable::NORMAL); 3026 name, VAR, kCreatedInitialized, Variable::NORMAL);
3028 3027
3029 Expect(Token::RPAREN, CHECK_OK); 3028 Expect(Token::RPAREN, CHECK_OK);
3030 3029
3030 ZoneList<const AstRawString*> bound_names(1, zone());
3031
3031 if (!is_simple) { 3032 if (!is_simple) {
3032 DeclarationDescriptor descriptor; 3033 DeclarationDescriptor descriptor;
3033 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 3034 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3034 descriptor.parser = this; 3035 descriptor.parser = this;
3035 descriptor.scope = scope_; 3036 descriptor.scope = scope_;
3036 descriptor.hoist_scope = nullptr; 3037 descriptor.hoist_scope = nullptr;
3037 descriptor.mode = LET; 3038 descriptor.mode = LET;
3038 descriptor.declaration_pos = pattern->position(); 3039 descriptor.declaration_pos = pattern->position();
3039 descriptor.initialization_pos = pattern->position(); 3040 descriptor.initialization_pos = pattern->position();
3040 3041
3041 DeclarationParsingResult::Declaration decl( 3042 DeclarationParsingResult::Declaration decl(
3042 pattern, pattern->position(), 3043 pattern, pattern->position(),
3043 factory()->NewVariableProxy(catch_variable)); 3044 factory()->NewVariableProxy(catch_variable));
3044 3045
3045 Block* init_block = 3046 Block* init_block =
3046 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); 3047 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
3047 PatternRewriter::DeclareAndInitializeVariables( 3048 PatternRewriter::DeclareAndInitializeVariables(
3048 init_block, &descriptor, &decl, nullptr, CHECK_OK); 3049 init_block, &descriptor, &decl, &bound_names, CHECK_OK);
3049 catch_block->statements()->Add(init_block, zone()); 3050 catch_block->statements()->Add(init_block, zone());
3051 } else {
3052 bound_names.Add(name, zone());
3050 } 3053 }
3051 3054
3052 // TODO(adamk): This should call ParseBlock in order to properly 3055 Block* inner_block = ParseBlock(nullptr, CHECK_OK);
3053 // add an additional block scope for the catch body. 3056 catch_block->statements()->Add(inner_block, zone());
3054 Expect(Token::LBRACE, CHECK_OK); 3057
3055 while (peek() != Token::RBRACE) { 3058 // Check for `catch(e) { let e; }` and similar errors.
3056 Statement* stat = ParseStatementListItem(CHECK_OK); 3059 Scope* inner_block_scope = inner_block->scope();
3057 if (stat && !stat->IsEmpty()) { 3060 if (inner_block_scope != nullptr) {
3058 catch_block->statements()->Add(stat, zone()); 3061 Declaration* decl =
3062 inner_block_scope->CheckLexDeclarationsConflictingWith(
3063 &bound_names);
3064 if (decl != nullptr) {
3065 const AstRawString* name = decl->proxy()->raw_name();
3066 int position = decl->proxy()->position();
3067 Scanner::Location location =
3068 position == kNoSourcePosition
adamk 2016/07/01 19:14:04 When does this hold?
3069 ? Scanner::Location::invalid()
3070 : Scanner::Location(position, position + 1);
3071 ParserTraits::ReportMessageAt(
3072 location, MessageTemplate::kVarRedeclaration, name);
3073 *ok = false;
3074 return nullptr;
3059 } 3075 }
3060 } 3076 }
3061 Consume(Token::RBRACE);
3062 } 3077 }
3063 block_scope->set_end_position(scanner()->location().end_pos); 3078 block_scope->set_end_position(scanner()->location().end_pos);
3064 block_scope = block_scope->FinalizeBlockScope(); 3079 block_scope = block_scope->FinalizeBlockScope();
3065 catch_block->set_scope(block_scope); 3080 catch_block->set_scope(block_scope);
3066 } 3081 }
3067 3082
3068 catch_scope->set_end_position(scanner()->location().end_pos); 3083 catch_scope->set_end_position(scanner()->location().end_pos);
3069 tok = peek(); 3084 tok = peek();
3070 } 3085 }
3071 3086
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
3551 body_scope = body_scope->FinalizeBlockScope(); 3566 body_scope = body_scope->FinalizeBlockScope();
3552 block->set_scope(body_scope); 3567 block->set_scope(body_scope);
3553 return block; 3568 return block;
3554 } 3569 }
3555 } 3570 }
3556 3571
3557 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3572 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3558 bool* ok) { 3573 bool* ok) {
3559 int stmt_pos = peek_position(); 3574 int stmt_pos = peek_position();
3560 Statement* init = NULL; 3575 Statement* init = NULL;
3561 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3576 ZoneList<const AstRawString*> bound_names(1, zone());
3577 bool bound_names_are_lexical = false;
3562 3578
3563 // Create an in-between scope for let-bound iteration variables. 3579 // Create an in-between scope for let-bound iteration variables.
3564 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3580 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3565 3581
3566 BlockState block_state(&scope_, for_scope); 3582 BlockState block_state(&scope_, for_scope);
3567 Expect(Token::FOR, CHECK_OK); 3583 Expect(Token::FOR, CHECK_OK);
3568 Expect(Token::LPAREN, CHECK_OK); 3584 Expect(Token::LPAREN, CHECK_OK);
3569 for_scope->set_start_position(scanner()->location().beg_pos); 3585 for_scope->set_start_position(scanner()->location().beg_pos);
3570 for_scope->set_is_hidden(); 3586 for_scope->set_is_hidden();
3571 DeclarationParsingResult parsing_result; 3587 DeclarationParsingResult parsing_result;
(...skipping 30 matching lines...) Expand all
3602 } 3618 }
3603 ParserTraits::ReportMessageAt( 3619 ParserTraits::ReportMessageAt(
3604 parsing_result.first_initializer_loc, 3620 parsing_result.first_initializer_loc,
3605 MessageTemplate::kForInOfLoopInitializer, 3621 MessageTemplate::kForInOfLoopInitializer,
3606 ForEachStatement::VisitModeString(mode)); 3622 ForEachStatement::VisitModeString(mode));
3607 *ok = false; 3623 *ok = false;
3608 return nullptr; 3624 return nullptr;
3609 } 3625 }
3610 3626
3611 Block* init_block = nullptr; 3627 Block* init_block = nullptr;
3628 bound_names_are_lexical =
3629 IsLexicalVariableMode(parsing_result.descriptor.mode);
3612 3630
3613 // special case for legacy for (var/const x =.... in) 3631 // special case for legacy for (var ... = ... in ...)
3614 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && 3632 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() &&
3615 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { 3633 decl.initializer != nullptr) {
3616 DCHECK(!allow_harmony_for_in()); 3634 DCHECK(!allow_harmony_for_in());
3617 ++use_counts_[v8::Isolate::kForInInitializer]; 3635 ++use_counts_[v8::Isolate::kForInInitializer];
3618 const AstRawString* name = 3636 const AstRawString* name =
3619 decl.pattern->AsVariableProxy()->raw_name(); 3637 decl.pattern->AsVariableProxy()->raw_name();
3620 VariableProxy* single_var = scope_->NewUnresolved( 3638 VariableProxy* single_var = scope_->NewUnresolved(
3621 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); 3639 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos);
3622 init_block = factory()->NewBlock( 3640 init_block = factory()->NewBlock(
3623 nullptr, 2, true, parsing_result.descriptor.declaration_pos); 3641 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3624 init_block->statements()->Add( 3642 init_block->statements()->Add(
3625 factory()->NewExpressionStatement( 3643 factory()->NewExpressionStatement(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3678 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 3696 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3679 3697
3680 auto each_initialization_block = 3698 auto each_initialization_block =
3681 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 3699 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3682 { 3700 {
3683 auto descriptor = parsing_result.descriptor; 3701 auto descriptor = parsing_result.descriptor;
3684 descriptor.declaration_pos = kNoSourcePosition; 3702 descriptor.declaration_pos = kNoSourcePosition;
3685 descriptor.initialization_pos = kNoSourcePosition; 3703 descriptor.initialization_pos = kNoSourcePosition;
3686 decl.initializer = factory()->NewVariableProxy(temp); 3704 decl.initializer = factory()->NewVariableProxy(temp);
3687 3705
3706 bool is_for_var_of =
3707 mode == ForEachStatement::ITERATE &&
3708 parsing_result.descriptor.mode == VariableMode::VAR;
3709
3688 PatternRewriter::DeclareAndInitializeVariables( 3710 PatternRewriter::DeclareAndInitializeVariables(
3689 each_initialization_block, &descriptor, &decl, 3711 each_initialization_block, &descriptor, &decl,
3690 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3712 bound_names_are_lexical || is_for_var_of ? &bound_names
3691 : nullptr, 3713 : nullptr,
3692 CHECK_OK); 3714 CHECK_OK);
3715
3716 // Annex B.3.5 prohibits the form
3717 // `try {} catch(e) { for (var e of {}); }`
3718 // So if we are parsing a statement like `for (var ... of ...)`
3719 // we need to walk up the scope chain and look for catch scopes
3720 // which have a simple binding, then compare their binding against
3721 // all of the names declared in the init of the for-of we're
3722 // parsing.
3723 if (is_for_var_of) {
3724 Scope* catch_scope = scope_;
3725 while (catch_scope != nullptr &&
3726 !catch_scope->is_declaration_scope()) {
3727 if (catch_scope->is_catch_scope()) {
3728 auto name = catch_scope->catch_variable_name();
3729 if (name !=
3730 ast_value_factory()
3731 ->dot_catch_string()) { // i.e. is a simple binding
3732 if (bound_names.Contains(name)) {
3733 ParserTraits::ReportMessageAt(
3734 parsing_result.bindings_loc,
3735 MessageTemplate::kVarRedeclaration, name);
3736 *ok = false;
3737 return nullptr;
3738 }
3739 }
3740 }
3741 catch_scope = catch_scope->outer_scope();
3742 }
3743 }
3693 } 3744 }
3694 3745
3695 body_block->statements()->Add(each_initialization_block, zone()); 3746 body_block->statements()->Add(each_initialization_block, zone());
3696 body_block->statements()->Add(body, zone()); 3747 body_block->statements()->Add(body, zone());
3697 VariableProxy* temp_proxy = 3748 VariableProxy* temp_proxy =
3698 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3749 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3699 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, 3750 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3700 each_keyword_position); 3751 each_keyword_position);
3701 } 3752 }
3702 body_scope->set_end_position(scanner()->location().end_pos); 3753 body_scope->set_end_position(scanner()->location().end_pos);
3703 body_scope = body_scope->FinalizeBlockScope(); 3754 body_scope = body_scope->FinalizeBlockScope();
3704 body_block->set_scope(body_scope); 3755 body_block->set_scope(body_scope);
3705 3756
3706 // Create a TDZ for any lexically-bound names. 3757 // Create a TDZ for any lexically-bound names.
3707 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3758 if (bound_names_are_lexical) {
3708 DCHECK_NULL(init_block); 3759 DCHECK_NULL(init_block);
3709 3760
3710 init_block = 3761 init_block =
3711 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3762 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3712 3763
3713 for (int i = 0; i < lexical_bindings.length(); ++i) { 3764 for (int i = 0; i < bound_names.length(); ++i) {
3714 // TODO(adamk): This needs to be some sort of special 3765 // TODO(adamk): This needs to be some sort of special
3715 // INTERNAL variable that's invisible to the debugger 3766 // INTERNAL variable that's invisible to the debugger
3716 // but visible to everything else. 3767 // but visible to everything else.
3717 VariableProxy* tdz_proxy = 3768 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET);
3718 NewUnresolved(lexical_bindings[i], LET);
3719 Declaration* tdz_decl = factory()->NewVariableDeclaration( 3769 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3720 tdz_proxy, LET, scope_, kNoSourcePosition); 3770 tdz_proxy, LET, scope_, kNoSourcePosition);
3721 Variable* tdz_var = Declare( 3771 Variable* tdz_var = Declare(
3722 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3772 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3723 tdz_var->set_initializer_position(position()); 3773 tdz_var->set_initializer_position(position());
3724 } 3774 }
3725 } 3775 }
3726 3776
3727 Statement* final_loop = 3777 Statement* final_loop =
3728 loop->IsForOfStatement() 3778 loop->IsForOfStatement()
3729 ? FinalizeForOfStatement(loop->AsForOfStatement(), 3779 ? FinalizeForOfStatement(loop->AsForOfStatement(),
3730 kNoSourcePosition) 3780 kNoSourcePosition)
3731 : loop; 3781 : loop;
3732 3782
3733 for_scope->set_end_position(scanner()->location().end_pos); 3783 for_scope->set_end_position(scanner()->location().end_pos);
3734 for_scope = for_scope->FinalizeBlockScope(); 3784 for_scope = for_scope->FinalizeBlockScope();
3735 // Parsed for-in loop w/ variable declarations. 3785 // Parsed for-in loop w/ variable declarations.
3736 if (init_block != nullptr) { 3786 if (init_block != nullptr) {
3737 init_block->statements()->Add(final_loop, zone()); 3787 init_block->statements()->Add(final_loop, zone());
3738 init_block->set_scope(for_scope); 3788 init_block->set_scope(for_scope);
3739 return init_block; 3789 return init_block;
3740 } else { 3790 } else {
3741 DCHECK_NULL(for_scope); 3791 DCHECK_NULL(for_scope);
3742 return final_loop; 3792 return final_loop;
3743 } 3793 }
3744 } else { 3794 } else {
3795 bound_names_are_lexical =
3796 IsLexicalVariableMode(parsing_result.descriptor.mode);
3745 init = parsing_result.BuildInitializationBlock( 3797 init = parsing_result.BuildInitializationBlock(
3746 IsLexicalVariableMode(parsing_result.descriptor.mode) 3798 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK);
3747 ? &lexical_bindings
3748 : nullptr,
3749 CHECK_OK);
3750 } 3799 }
3751 } else { 3800 } else {
3752 int lhs_beg_pos = peek_position(); 3801 int lhs_beg_pos = peek_position();
3753 ExpressionClassifier classifier(this); 3802 ExpressionClassifier classifier(this);
3754 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); 3803 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3755 int lhs_end_pos = scanner()->location().end_pos; 3804 int lhs_end_pos = scanner()->location().end_pos;
3756 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3805 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3757 3806
3758 bool is_for_each = CheckInOrOf(&mode, ok); 3807 bool is_for_each = CheckInOrOf(&mode, ok);
3759 if (!*ok) return nullptr; 3808 if (!*ok) return nullptr;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3820 // Parsed initializer at this point. 3869 // Parsed initializer at this point.
3821 Expect(Token::SEMICOLON, CHECK_OK); 3870 Expect(Token::SEMICOLON, CHECK_OK);
3822 3871
3823 Expression* cond = NULL; 3872 Expression* cond = NULL;
3824 Statement* next = NULL; 3873 Statement* next = NULL;
3825 Statement* body = NULL; 3874 Statement* body = NULL;
3826 3875
3827 // If there are let bindings, then condition and the next statement of the 3876 // If there are let bindings, then condition and the next statement of the
3828 // for loop must be parsed in a new scope. 3877 // for loop must be parsed in a new scope.
3829 Scope* inner_scope = scope_; 3878 Scope* inner_scope = scope_;
3830 if (lexical_bindings.length() > 0) { 3879 if (bound_names_are_lexical && bound_names.length() > 0) {
3831 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3880 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3832 inner_scope->set_start_position(scanner()->location().beg_pos); 3881 inner_scope->set_start_position(scanner()->location().beg_pos);
3833 } 3882 }
3834 { 3883 {
3835 BlockState block_state(&scope_, inner_scope); 3884 BlockState block_state(&scope_, inner_scope);
3836 3885
3837 if (peek() != Token::SEMICOLON) { 3886 if (peek() != Token::SEMICOLON) {
3838 cond = ParseExpression(true, CHECK_OK); 3887 cond = ParseExpression(true, CHECK_OK);
3839 } 3888 }
3840 Expect(Token::SEMICOLON, CHECK_OK); 3889 Expect(Token::SEMICOLON, CHECK_OK);
3841 3890
3842 if (peek() != Token::RPAREN) { 3891 if (peek() != Token::RPAREN) {
3843 Expression* exp = ParseExpression(true, CHECK_OK); 3892 Expression* exp = ParseExpression(true, CHECK_OK);
3844 next = factory()->NewExpressionStatement(exp, exp->position()); 3893 next = factory()->NewExpressionStatement(exp, exp->position());
3845 } 3894 }
3846 Expect(Token::RPAREN, CHECK_OK); 3895 Expect(Token::RPAREN, CHECK_OK);
3847 3896
3848 body = ParseScopedStatement(NULL, true, CHECK_OK); 3897 body = ParseScopedStatement(NULL, true, CHECK_OK);
3849 } 3898 }
3850 3899
3851 Statement* result = NULL; 3900 Statement* result = NULL;
3852 if (lexical_bindings.length() > 0) { 3901 if (bound_names_are_lexical && bound_names.length() > 0) {
3853 BlockState block_state(&scope_, for_scope); 3902 BlockState block_state(&scope_, for_scope);
3854 result = DesugarLexicalBindingsInForStatement( 3903 result = DesugarLexicalBindingsInForStatement(
3855 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, 3904 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
3856 init, cond, next, body, CHECK_OK); 3905 cond, next, body, CHECK_OK);
3857 for_scope->set_end_position(scanner()->location().end_pos); 3906 for_scope->set_end_position(scanner()->location().end_pos);
3858 } else { 3907 } else {
3859 for_scope->set_end_position(scanner()->location().end_pos); 3908 for_scope->set_end_position(scanner()->location().end_pos);
3860 for_scope = for_scope->FinalizeBlockScope(); 3909 for_scope = for_scope->FinalizeBlockScope();
3861 if (for_scope) { 3910 if (for_scope) {
3862 // Rewrite a for statement of the form 3911 // Rewrite a for statement of the form
3863 // for (const x = i; c; n) b 3912 // for (const x = i; c; n) b
3864 // 3913 //
3865 // into 3914 // into
3866 // 3915 //
(...skipping 3151 matching lines...) Expand 10 before | Expand all | Expand 10 after
7018 try_block, target); 7067 try_block, target);
7019 final_loop = target; 7068 final_loop = target;
7020 } 7069 }
7021 7070
7022 return final_loop; 7071 return final_loop;
7023 } 7072 }
7024 7073
7025 7074
7026 } // namespace internal 7075 } // namespace internal
7027 } // namespace v8 7076 } // namespace v8
OLDNEW
« src/ast/scopes.cc ('K') | « src/ast/scopes.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698