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

Side by Side Diff: src/parsing/parser-base.h

Issue 2645353002: [parser] Refactor ParseForStatement. (Closed)
Patch Set: code review (adamk@ and uninitialized value fix) Created 3 years, 10 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 | « no previous file | no next file » | 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 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 bool* ok); 1295 bool* ok);
1296 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 1296 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1297 bool* ok); 1297 bool* ok);
1298 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, 1298 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1299 bool* ok); 1299 bool* ok);
1300 StatementT ParseThrowStatement(bool* ok); 1300 StatementT ParseThrowStatement(bool* ok);
1301 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 1301 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1302 bool* ok); 1302 bool* ok);
1303 StatementT ParseTryStatement(bool* ok); 1303 StatementT ParseTryStatement(bool* ok);
1304 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); 1304 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1305 StatementT ParseForEachStatementWithDeclarations(
1306 int stmt_pos, ForInfo* for_info, BlockState* for_state,
1307 ZoneList<const AstRawString*>* labels, bool* ok);
1308 StatementT ParseForEachStatementWithoutDeclarations(
1309 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1310 ForInfo* for_info, BlockState* for_state,
1311 ZoneList<const AstRawString*>* labels, bool* ok);
1312
1313 // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }'
1314 StatementT ParseStandardForLoop(int stmt_pos, StatementT init,
1315 bool bound_names_are_lexical,
1316 ForInfo* for_info, BlockState* for_state,
1317 ZoneList<const AstRawString*>* labels,
1318 bool* ok);
1305 1319
1306 bool IsNextLetKeyword(); 1320 bool IsNextLetKeyword();
1307 bool IsTrivialExpression(); 1321 bool IsTrivialExpression();
1308 1322
1309 // Checks if the expression is a valid reference expression (e.g., on the 1323 // Checks if the expression is a valid reference expression (e.g., on the
1310 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1324 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1311 // we allow calls for web compatibility and rewrite them to a runtime throw. 1325 // we allow calls for web compatibility and rewrite them to a runtime throw.
1312 ExpressionT CheckAndRewriteReferenceExpression( 1326 ExpressionT CheckAndRewriteReferenceExpression(
1313 ExpressionT expression, int beg_pos, int end_pos, 1327 ExpressionT expression, int beg_pos, int end_pos,
1314 MessageTemplate::Template message, bool* ok); 1328 MessageTemplate::Template message, bool* ok);
(...skipping 4058 matching lines...) Expand 10 before | Expand all | Expand 10 after
5373 bool bound_names_are_lexical = false; 5387 bool bound_names_are_lexical = false;
5374 5388
5375 // Create an in-between scope for let-bound iteration variables. 5389 // Create an in-between scope for let-bound iteration variables.
5376 BlockState for_state(zone(), &scope_state_); 5390 BlockState for_state(zone(), &scope_state_);
5377 Expect(Token::FOR, CHECK_OK); 5391 Expect(Token::FOR, CHECK_OK);
5378 Expect(Token::LPAREN, CHECK_OK); 5392 Expect(Token::LPAREN, CHECK_OK);
5379 for_state.set_start_position(scanner()->location().beg_pos); 5393 for_state.set_start_position(scanner()->location().beg_pos);
5380 for_state.set_is_hidden(); 5394 for_state.set_is_hidden();
5381 5395
5382 StatementT init = impl()->NullStatement(); 5396 StatementT init = impl()->NullStatement();
5383 if (peek() != Token::SEMICOLON) {
5384 // An initializer is present.
5385 if (peek() == Token::VAR || peek() == Token::CONST ||
5386 (peek() == Token::LET && IsNextLetKeyword())) {
5387 // The initializer contains declarations.
5388 ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5389 nullptr, CHECK_OK);
5390 bound_names_are_lexical =
5391 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode);
5392 for_info.position = scanner()->location().beg_pos;
5393 5397
5394 if (CheckInOrOf(&for_info.mode)) { 5398 if (peek() == Token::VAR || peek() == Token::CONST ||
5395 // Just one declaration followed by in/of. 5399 (peek() == Token::LET && IsNextLetKeyword())) {
5396 if (for_info.parsing_result.declarations.length() != 1) { 5400 // The initializer contains declarations.
5397 impl()->ReportMessageAt( 5401 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr,
5398 for_info.parsing_result.bindings_loc, 5402 CHECK_OK);
5399 MessageTemplate::kForInOfLoopMultiBindings, 5403 bound_names_are_lexical =
5400 ForEachStatement::VisitModeString(for_info.mode)); 5404 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode);
5401 *ok = false; 5405 for_info.position = scanner()->location().beg_pos;
5402 return impl()->NullStatement();
5403 }
5404 if (for_info.parsing_result.first_initializer_loc.IsValid() &&
5405 (is_strict(language_mode()) ||
5406 for_info.mode == ForEachStatement::ITERATE ||
5407 bound_names_are_lexical ||
5408 !impl()->IsIdentifier(
5409 for_info.parsing_result.declarations[0].pattern))) {
5410 impl()->ReportMessageAt(
5411 for_info.parsing_result.first_initializer_loc,
5412 MessageTemplate::kForInOfLoopInitializer,
5413 ForEachStatement::VisitModeString(for_info.mode));
5414 *ok = false;
5415 return impl()->NullStatement();
5416 }
5417 5406
5418 BlockT init_block = impl()->RewriteForVarInLegacy(for_info); 5407 if (CheckInOrOf(&for_info.mode)) {
5408 return ParseForEachStatementWithDeclarations(stmt_pos, &for_info,
5409 &for_state, labels, ok);
5410 }
5419 5411
5420 auto loop = 5412 // One or more declaration not followed by in/of.
5421 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos); 5413 init = impl()->BuildInitializationBlock(
5422 typename Types::Target target(this, loop); 5414 &for_info.parsing_result,
5415 bound_names_are_lexical ? &for_info.bound_names : nullptr, CHECK_OK);
5416 } else if (peek() != Token::SEMICOLON) {
5417 // The initializer does not contain declarations.
5418 int lhs_beg_pos = peek_position();
5419 ExpressionClassifier classifier(this);
5420 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
5421 int lhs_end_pos = scanner()->location().end_pos;
5423 5422
5424 int each_keyword_pos = scanner()->location().beg_pos; 5423 bool is_for_each = CheckInOrOf(&for_info.mode);
5424 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
5425 expression->IsObjectLiteral());
5425 5426
5426 ExpressionT enumerable = impl()->EmptyExpression(); 5427 if (is_destructuring) {
5427 if (for_info.mode == ForEachStatement::ITERATE) { 5428 ValidateAssignmentPattern(CHECK_OK);
5428 ExpressionClassifier classifier(this); 5429 } else {
5429 enumerable = ParseAssignmentExpression(true, CHECK_OK); 5430 impl()->RewriteNonPattern(CHECK_OK);
5430 impl()->RewriteNonPattern(CHECK_OK); 5431 }
5431 } else {
5432 enumerable = ParseExpression(true, CHECK_OK);
5433 }
5434 5432
5435 Expect(Token::RPAREN, CHECK_OK); 5433 if (is_for_each) {
5436 5434 return ParseForEachStatementWithoutDeclarations(
5437 StatementT final_loop = impl()->NullStatement(); 5435 stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, &for_state,
5438 { 5436 labels, ok);
5439 ReturnExprScope no_tail_calls(function_state_,
5440 ReturnExprContext::kInsideForInOfBody);
5441 BlockState block_state(zone(), &scope_state_);
5442 block_state.set_start_position(scanner()->location().beg_pos);
5443
5444 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5445
5446 BlockT body_block = impl()->NullBlock();
5447 ExpressionT each_variable = impl()->EmptyExpression();
5448 impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
5449 &each_variable, CHECK_OK);
5450 body_block->statements()->Add(body, zone());
5451 final_loop = impl()->InitializeForEachStatement(
5452 loop, each_variable, enumerable, body_block, each_keyword_pos);
5453
5454 block_state.set_end_position(scanner()->location().end_pos);
5455 body_block->set_scope(block_state.FinalizedBlockScope());
5456 }
5457
5458 init_block =
5459 impl()->CreateForEachStatementTDZ(init_block, for_info, ok);
5460
5461 for_state.set_end_position(scanner()->location().end_pos);
5462 Scope* for_scope = for_state.FinalizedBlockScope();
5463 // Parsed for-in loop w/ variable declarations.
5464 if (!impl()->IsNullStatement(init_block)) {
5465 init_block->statements()->Add(final_loop, zone());
5466 init_block->set_scope(for_scope);
5467 return init_block;
5468 } else {
5469 DCHECK_NULL(for_scope);
5470 return final_loop;
5471 }
5472 } else {
5473 // One or more declaration not followed by in/of.
5474 init = impl()->BuildInitializationBlock(
5475 &for_info.parsing_result,
5476 bound_names_are_lexical ? &for_info.bound_names : nullptr,
5477 CHECK_OK);
5478 }
5479 } else {
5480 // The initializer does not contain declarations.
5481 int lhs_beg_pos = peek_position();
5482 ExpressionClassifier classifier(this);
5483 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
5484 int lhs_end_pos = scanner()->location().end_pos;
5485
5486 bool is_for_each = CheckInOrOf(&for_info.mode);
5487 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
5488 expression->IsObjectLiteral());
5489
5490 if (is_destructuring) {
5491 ValidateAssignmentPattern(CHECK_OK);
5492 } else {
5493 impl()->RewriteNonPattern(CHECK_OK);
5494 }
5495
5496 if (is_for_each) {
5497 // Initializer is reference followed by in/of.
5498 if (!is_destructuring) {
5499 expression = impl()->CheckAndRewriteReferenceExpression(
5500 expression, lhs_beg_pos, lhs_end_pos,
5501 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
5502 }
5503
5504 auto loop =
5505 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5506 typename Types::Target target(this, loop);
5507
5508 int each_keyword_pos = scanner()->location().beg_pos;
5509
5510 ExpressionT enumerable = impl()->EmptyExpression();
5511 if (for_info.mode == ForEachStatement::ITERATE) {
5512 ExpressionClassifier classifier(this);
5513 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5514 impl()->RewriteNonPattern(CHECK_OK);
5515 } else {
5516 enumerable = ParseExpression(true, CHECK_OK);
5517 }
5518
5519 Expect(Token::RPAREN, CHECK_OK);
5520
5521 {
5522 ReturnExprScope no_tail_calls(function_state_,
5523 ReturnExprContext::kInsideForInOfBody);
5524 BlockState block_state(zone(), &scope_state_);
5525 block_state.set_start_position(scanner()->location().beg_pos);
5526
5527 // For legacy compat reasons, give for loops similar treatment to
5528 // if statements in allowing a function declaration for a body
5529 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5530 block_state.set_end_position(scanner()->location().end_pos);
5531 StatementT final_loop = impl()->InitializeForEachStatement(
5532 loop, expression, enumerable, body, each_keyword_pos);
5533
5534 Scope* for_scope = for_state.FinalizedBlockScope();
5535 DCHECK_NULL(for_scope);
5536 USE(for_scope);
5537 Scope* block_scope = block_state.FinalizedBlockScope();
5538 DCHECK_NULL(block_scope);
5539 USE(block_scope);
5540 return final_loop;
5541 }
5542 } else {
5543 // Initializer is just an expression.
5544 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
5545 }
5546 } 5437 }
5438 // Initializer is just an expression.
5439 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
5547 } 5440 }
5548 5441
5549 // Standard 'for' loop, we have parsed the initializer at this point. 5442 // Standard 'for' loop, we have parsed the initializer at this point.
5443 return ParseStandardForLoop(stmt_pos, init, bound_names_are_lexical,
5444 &for_info, &for_state, labels, ok);
5445 }
5446
5447 template <typename Impl>
5448 typename ParserBase<Impl>::StatementT
5449 ParserBase<Impl>::ParseForEachStatementWithDeclarations(
5450 int stmt_pos, ForInfo* for_info, BlockState* for_state,
5451 ZoneList<const AstRawString*>* labels, bool* ok) {
5452 // Just one declaration followed by in/of.
5453 if (for_info->parsing_result.declarations.length() != 1) {
5454 impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
5455 MessageTemplate::kForInOfLoopMultiBindings,
5456 ForEachStatement::VisitModeString(for_info->mode));
5457 *ok = false;
5458 return impl()->NullStatement();
5459 }
5460 if (for_info->parsing_result.first_initializer_loc.IsValid() &&
5461 (is_strict(language_mode()) ||
5462 for_info->mode == ForEachStatement::ITERATE ||
5463 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
5464 !impl()->IsIdentifier(
5465 for_info->parsing_result.declarations[0].pattern))) {
5466 impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc,
5467 MessageTemplate::kForInOfLoopInitializer,
5468 ForEachStatement::VisitModeString(for_info->mode));
5469 *ok = false;
5470 return impl()->NullStatement();
5471 }
5472
5473 BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
5474
5475 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos);
5476 typename Types::Target target(this, loop);
5477
5478 int each_keyword_pos = scanner()->location().beg_pos;
5479
5480 ExpressionT enumerable = impl()->EmptyExpression();
5481 if (for_info->mode == ForEachStatement::ITERATE) {
5482 ExpressionClassifier classifier(this);
5483 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5484 impl()->RewriteNonPattern(CHECK_OK);
5485 } else {
5486 enumerable = ParseExpression(true, CHECK_OK);
5487 }
5488
5489 Expect(Token::RPAREN, CHECK_OK);
5490
5491 StatementT final_loop = impl()->NullStatement();
5492 {
5493 ReturnExprScope no_tail_calls(function_state_,
5494 ReturnExprContext::kInsideForInOfBody);
5495 BlockState block_state(zone(), &scope_state_);
5496 block_state.set_start_position(scanner()->location().beg_pos);
5497
5498 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5499
5500 BlockT body_block = impl()->NullBlock();
5501 ExpressionT each_variable = impl()->EmptyExpression();
5502 impl()->DesugarBindingInForEachStatement(for_info, &body_block,
5503 &each_variable, CHECK_OK);
5504 body_block->statements()->Add(body, zone());
5505 final_loop = impl()->InitializeForEachStatement(
5506 loop, each_variable, enumerable, body_block, each_keyword_pos);
5507
5508 block_state.set_end_position(scanner()->location().end_pos);
5509 body_block->set_scope(block_state.FinalizedBlockScope());
5510 }
5511
5512 init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info, ok);
5513
5514 for_state->set_end_position(scanner()->location().end_pos);
5515 Scope* for_scope = for_state->FinalizedBlockScope();
5516 // Parsed for-in loop w/ variable declarations.
5517 if (!impl()->IsNullStatement(init_block)) {
5518 init_block->statements()->Add(final_loop, zone());
5519 init_block->set_scope(for_scope);
5520 return init_block;
5521 }
5522
5523 DCHECK_NULL(for_scope);
5524 return final_loop;
5525 }
5526
5527 template <typename Impl>
5528 typename ParserBase<Impl>::StatementT
5529 ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
5530 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
5531 ForInfo* for_info, BlockState* for_state,
5532 ZoneList<const AstRawString*>* labels, bool* ok) {
5533 // Initializer is reference followed by in/of.
5534 if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) {
5535 expression = impl()->CheckAndRewriteReferenceExpression(
5536 expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
5537 kSyntaxError, CHECK_OK);
5538 }
5539
5540 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos);
5541 typename Types::Target target(this, loop);
5542
5543 int each_keyword_pos = scanner()->location().beg_pos;
5544
5545 ExpressionT enumerable = impl()->EmptyExpression();
5546 if (for_info->mode == ForEachStatement::ITERATE) {
5547 ExpressionClassifier classifier(this);
5548 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5549 impl()->RewriteNonPattern(CHECK_OK);
5550 } else {
5551 enumerable = ParseExpression(true, CHECK_OK);
5552 }
5553
5554 Expect(Token::RPAREN, CHECK_OK);
5555
5556 {
5557 ReturnExprScope no_tail_calls(function_state_,
5558 ReturnExprContext::kInsideForInOfBody);
5559 BlockState block_state(zone(), &scope_state_);
5560 block_state.set_start_position(scanner()->location().beg_pos);
5561
5562 // For legacy compat reasons, give for loops similar treatment to
5563 // if statements in allowing a function declaration for a body
5564 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5565 block_state.set_end_position(scanner()->location().end_pos);
5566 StatementT final_loop = impl()->InitializeForEachStatement(
5567 loop, expression, enumerable, body, each_keyword_pos);
5568
5569 Scope* for_scope = for_state->FinalizedBlockScope();
5570 DCHECK_NULL(for_scope);
5571 USE(for_scope);
5572 Scope* block_scope = block_state.FinalizedBlockScope();
5573 DCHECK_NULL(block_scope);
5574 USE(block_scope);
5575 return final_loop;
5576 }
5577 }
5578
5579 template <typename Impl>
5580 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop(
5581 int stmt_pos, StatementT init, bool bound_names_are_lexical,
5582 ForInfo* for_info, BlockState* for_state,
5583 ZoneList<const AstRawString*>* labels, bool* ok) {
5550 auto loop = factory()->NewForStatement(labels, stmt_pos); 5584 auto loop = factory()->NewForStatement(labels, stmt_pos);
5551 typename Types::Target target(this, loop); 5585 typename Types::Target target(this, loop);
5552 5586
5553 Expect(Token::SEMICOLON, CHECK_OK); 5587 Expect(Token::SEMICOLON, CHECK_OK);
5554 5588
5555 ExpressionT cond = impl()->EmptyExpression(); 5589 ExpressionT cond = impl()->EmptyExpression();
5556 StatementT next = impl()->NullStatement(); 5590 StatementT next = impl()->NullStatement();
5557 StatementT body = impl()->NullStatement(); 5591 StatementT body = impl()->NullStatement();
5558 5592
5559 // If there are let bindings, then condition and the next statement of the 5593 // If there are let bindings, then condition and the next statement of the
5560 // for loop must be parsed in a new scope. 5594 // for loop must be parsed in a new scope.
5561 Scope* inner_scope = scope(); 5595 Scope* inner_scope = scope();
5562 // TODO(verwaest): Allocate this through a ScopeState as well. 5596 // TODO(verwaest): Allocate this through a ScopeState as well.
5563 if (bound_names_are_lexical && for_info.bound_names.length() > 0) { 5597 if (bound_names_are_lexical && for_info->bound_names.length() > 0) {
5564 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); 5598 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
5565 inner_scope->set_start_position(scanner()->location().beg_pos); 5599 inner_scope->set_start_position(scanner()->location().beg_pos);
5566 } 5600 }
5567 { 5601 {
5568 BlockState block_state(&scope_state_, inner_scope); 5602 BlockState block_state(&scope_state_, inner_scope);
5569 5603
5570 if (peek() != Token::SEMICOLON) { 5604 if (peek() != Token::SEMICOLON) {
5571 cond = ParseExpression(true, CHECK_OK); 5605 cond = ParseExpression(true, CHECK_OK);
5572 } 5606 }
5573 Expect(Token::SEMICOLON, CHECK_OK); 5607 Expect(Token::SEMICOLON, CHECK_OK);
5574 5608
5575 if (peek() != Token::RPAREN) { 5609 if (peek() != Token::RPAREN) {
5576 ExpressionT exp = ParseExpression(true, CHECK_OK); 5610 ExpressionT exp = ParseExpression(true, CHECK_OK);
5577 next = factory()->NewExpressionStatement(exp, exp->position()); 5611 next = factory()->NewExpressionStatement(exp, exp->position());
5578 } 5612 }
5579 Expect(Token::RPAREN, CHECK_OK); 5613 Expect(Token::RPAREN, CHECK_OK);
5580 5614
5581 body = ParseScopedStatement(nullptr, true, CHECK_OK); 5615 body = ParseScopedStatement(nullptr, true, CHECK_OK);
5582 } 5616 }
5583 5617
5584 if (bound_names_are_lexical && for_info.bound_names.length() > 0) { 5618 if (bound_names_are_lexical && for_info->bound_names.length() > 0) {
5585 auto result = impl()->DesugarLexicalBindingsInForStatement( 5619 auto result = impl()->DesugarLexicalBindingsInForStatement(
5586 loop, init, cond, next, body, inner_scope, for_info, CHECK_OK); 5620 loop, init, cond, next, body, inner_scope, *for_info, CHECK_OK);
5587 for_state.set_end_position(scanner()->location().end_pos); 5621 for_state->set_end_position(scanner()->location().end_pos);
5588 return result; 5622 return result;
5589 } else { 5623 }
5590 for_state.set_end_position(scanner()->location().end_pos); 5624
5591 Scope* for_scope = for_state.FinalizedBlockScope(); 5625 for_state->set_end_position(scanner()->location().end_pos);
5592 if (for_scope != nullptr) { 5626 Scope* for_scope = for_state->FinalizedBlockScope();
5593 // Rewrite a for statement of the form 5627 if (for_scope != nullptr) {
5594 // for (const x = i; c; n) b 5628 // Rewrite a for statement of the form
5595 // 5629 // for (const x = i; c; n) b
5596 // into 5630 //
5597 // 5631 // into
5598 // { 5632 //
5599 // const x = i; 5633 // {
5600 // for (; c; n) b 5634 // const x = i;
5601 // } 5635 // for (; c; n) b
5602 // 5636 // }
5603 // or, desugar 5637 //
5604 // for (; c; n) b 5638 // or, desugar
5605 // into 5639 // for (; c; n) b
5606 // { 5640 // into
5607 // for (; c; n) b 5641 // {
5608 // } 5642 // for (; c; n) b
5609 // just in case b introduces a lexical binding some other way, e.g., if b 5643 // }
5610 // is a FunctionDeclaration. 5644 // just in case b introduces a lexical binding some other way, e.g., if b
5611 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); 5645 // is a FunctionDeclaration.
5612 if (!impl()->IsNullStatement(init)) { 5646 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
5613 block->statements()->Add(init, zone()); 5647 if (!impl()->IsNullStatement(init)) {
5614 } 5648 block->statements()->Add(init, zone());
5615 block->statements()->Add(loop, zone());
5616 block->set_scope(for_scope);
5617 loop->Initialize(init, cond, next, body);
5618 return block;
5619 } else {
5620 loop->Initialize(init, cond, next, body);
5621 return loop;
5622 } 5649 }
5650 block->statements()->Add(loop, zone());
5651 block->set_scope(for_scope);
5652 loop->Initialize(init, cond, next, body);
5653 return block;
5623 } 5654 }
5655
5656 loop->Initialize(init, cond, next, body);
5657 return loop;
5624 } 5658 }
5625 5659
5626 #undef CHECK_OK 5660 #undef CHECK_OK
5627 #undef CHECK_OK_CUSTOM 5661 #undef CHECK_OK_CUSTOM
5628 5662
5629 template <typename Impl> 5663 template <typename Impl>
5630 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 5664 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5631 Token::Value property) { 5665 Token::Value property) {
5632 if (property == Token::SMI || property == Token::NUMBER) return; 5666 if (property == Token::SMI || property == Token::NUMBER) return;
5633 5667
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5675 return; 5709 return;
5676 } 5710 }
5677 } 5711 }
5678 5712
5679 #undef CHECK_OK_VOID 5713 #undef CHECK_OK_VOID
5680 5714
5681 } // namespace internal 5715 } // namespace internal
5682 } // namespace v8 5716 } // namespace v8
5683 5717
5684 #endif // V8_PARSING_PARSER_BASE_H 5718 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698