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

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

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