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

Side by Side Diff: tools/gn/parser.cc

Issue 1544333002: Convert Pass()→std::move() in //tools (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 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 | « tools/gn/parse_tree_unittest.cc ('k') | tools/gn/scope.h » ('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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium 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 "tools/gn/parser.h" 5 #include "tools/gn/parser.h"
6 6
7 #include <utility>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "tools/gn/functions.h" 10 #include "tools/gn/functions.h"
9 #include "tools/gn/operators.h" 11 #include "tools/gn/operators.h"
10 #include "tools/gn/token.h" 12 #include "tools/gn/token.h"
11 13
12 const char kGrammar_Help[] = 14 const char kGrammar_Help[] =
13 "GN build language grammar\n" 15 "GN build language grammar\n"
14 "\n" 16 "\n"
15 "Tokens\n" 17 "Tokens\n"
16 "\n" 18 "\n"
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 210
209 // static 211 // static
210 scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens, 212 scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens,
211 Err* err) { 213 Err* err) {
212 Parser p(tokens, err); 214 Parser p(tokens, err);
213 scoped_ptr<ParseNode> expr = p.ParseExpression(); 215 scoped_ptr<ParseNode> expr = p.ParseExpression();
214 if (!p.at_end() && !err->has_error()) { 216 if (!p.at_end() && !err->has_error()) {
215 *err = Err(p.cur_token(), "Trailing garbage"); 217 *err = Err(p.cur_token(), "Trailing garbage");
216 return nullptr; 218 return nullptr;
217 } 219 }
218 return expr.Pass(); 220 return expr;
219 } 221 }
220 222
221 // static 223 // static
222 scoped_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens, 224 scoped_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens,
223 Err* err) { 225 Err* err) {
224 for (const Token& token : tokens) { 226 for (const Token& token : tokens) {
225 switch (token.type()) { 227 switch (token.type()) {
226 case Token::INTEGER: 228 case Token::INTEGER:
227 case Token::STRING: 229 case Token::STRING:
228 case Token::TRUE_TOKEN: 230 case Token::TRUE_TOKEN:
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 323
322 if (prefix == nullptr) { 324 if (prefix == nullptr) {
323 *err_ = Err(token, 325 *err_ = Err(token,
324 std::string("Unexpected token '") + token.value().as_string() + 326 std::string("Unexpected token '") + token.value().as_string() +
325 std::string("'")); 327 std::string("'"));
326 return scoped_ptr<ParseNode>(); 328 return scoped_ptr<ParseNode>();
327 } 329 }
328 330
329 scoped_ptr<ParseNode> left = (this->*prefix)(token); 331 scoped_ptr<ParseNode> left = (this->*prefix)(token);
330 if (has_error()) 332 if (has_error())
331 return left.Pass(); 333 return left;
332 334
333 while (!at_end() && !IsStatementBreak(cur_token().type()) && 335 while (!at_end() && !IsStatementBreak(cur_token().type()) &&
334 precedence <= expressions_[cur_token().type()].precedence) { 336 precedence <= expressions_[cur_token().type()].precedence) {
335 token = Consume(); 337 token = Consume();
336 InfixFunc infix = expressions_[token.type()].infix; 338 InfixFunc infix = expressions_[token.type()].infix;
337 if (infix == nullptr) { 339 if (infix == nullptr) {
338 *err_ = Err(token, 340 *err_ = Err(token,
339 std::string("Unexpected token '") + 341 std::string("Unexpected token '") +
340 token.value().as_string() + std::string("'")); 342 token.value().as_string() + std::string("'"));
341 return scoped_ptr<ParseNode>(); 343 return scoped_ptr<ParseNode>();
342 } 344 }
343 left = (this->*infix)(left.Pass(), token); 345 left = (this->*infix)(std::move(left), token);
344 if (has_error()) 346 if (has_error())
345 return scoped_ptr<ParseNode>(); 347 return scoped_ptr<ParseNode>();
346 } 348 }
347 349
348 return left.Pass(); 350 return left;
349 } 351 }
350 352
351 scoped_ptr<ParseNode> Parser::Literal(Token token) { 353 scoped_ptr<ParseNode> Parser::Literal(Token token) {
352 return make_scoped_ptr(new LiteralNode(token)); 354 return make_scoped_ptr(new LiteralNode(token));
353 } 355 }
354 356
355 scoped_ptr<ParseNode> Parser::Name(Token token) { 357 scoped_ptr<ParseNode> Parser::Name(Token token) {
356 return IdentifierOrCall(scoped_ptr<ParseNode>(), token).Pass(); 358 return IdentifierOrCall(scoped_ptr<ParseNode>(), token);
357 } 359 }
358 360
359 scoped_ptr<ParseNode> Parser::BlockComment(Token token) { 361 scoped_ptr<ParseNode> Parser::BlockComment(Token token) {
360 scoped_ptr<BlockCommentNode> comment(new BlockCommentNode()); 362 scoped_ptr<BlockCommentNode> comment(new BlockCommentNode());
361 comment->set_comment(token); 363 comment->set_comment(token);
362 return comment.Pass(); 364 return std::move(comment);
363 } 365 }
364 366
365 scoped_ptr<ParseNode> Parser::Group(Token token) { 367 scoped_ptr<ParseNode> Parser::Group(Token token) {
366 scoped_ptr<ParseNode> expr = ParseExpression(); 368 scoped_ptr<ParseNode> expr = ParseExpression();
367 if (has_error()) 369 if (has_error())
368 return scoped_ptr<ParseNode>(); 370 return scoped_ptr<ParseNode>();
369 Consume(Token::RIGHT_PAREN, "Expected ')'"); 371 Consume(Token::RIGHT_PAREN, "Expected ')'");
370 return expr.Pass(); 372 return expr;
371 } 373 }
372 374
373 scoped_ptr<ParseNode> Parser::Not(Token token) { 375 scoped_ptr<ParseNode> Parser::Not(Token token) {
374 scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1); 376 scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1);
375 if (has_error()) 377 if (has_error())
376 return scoped_ptr<ParseNode>(); 378 return scoped_ptr<ParseNode>();
377 if (!expr) { 379 if (!expr) {
378 if (!has_error()) 380 if (!has_error())
379 *err_ = Err(token, "Expected right-hand side for '!'."); 381 *err_ = Err(token, "Expected right-hand side for '!'.");
380 return scoped_ptr<ParseNode>(); 382 return scoped_ptr<ParseNode>();
381 } 383 }
382 scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode); 384 scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode);
383 unary_op->set_op(token); 385 unary_op->set_op(token);
384 unary_op->set_operand(expr.Pass()); 386 unary_op->set_operand(std::move(expr));
385 return unary_op.Pass(); 387 return std::move(unary_op);
386 } 388 }
387 389
388 scoped_ptr<ParseNode> Parser::List(Token node) { 390 scoped_ptr<ParseNode> Parser::List(Token node) {
389 scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true)); 391 scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true));
390 if (!has_error() && !at_end()) 392 if (!has_error() && !at_end())
391 Consume(Token::RIGHT_BRACKET, "Expected ']'"); 393 Consume(Token::RIGHT_BRACKET, "Expected ']'");
392 return list.Pass(); 394 return list;
393 } 395 }
394 396
395 scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left, 397 scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left,
396 Token token) { 398 Token token) {
397 scoped_ptr<ParseNode> right = 399 scoped_ptr<ParseNode> right =
398 ParseExpression(expressions_[token.type()].precedence + 1); 400 ParseExpression(expressions_[token.type()].precedence + 1);
399 if (!right) { 401 if (!right) {
400 if (!has_error()) { 402 if (!has_error()) {
401 *err_ = Err(token, "Expected right-hand side for '" + 403 *err_ = Err(token, "Expected right-hand side for '" +
402 token.value().as_string() + "'"); 404 token.value().as_string() + "'");
403 } 405 }
404 return scoped_ptr<ParseNode>(); 406 return scoped_ptr<ParseNode>();
405 } 407 }
406 scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode); 408 scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode);
407 binary_op->set_op(token); 409 binary_op->set_op(token);
408 binary_op->set_left(left.Pass()); 410 binary_op->set_left(std::move(left));
409 binary_op->set_right(right.Pass()); 411 binary_op->set_right(std::move(right));
410 return binary_op.Pass(); 412 return std::move(binary_op);
411 } 413 }
412 414
413 scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, 415 scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left,
414 Token token) { 416 Token token) {
415 scoped_ptr<ListNode> list(new ListNode); 417 scoped_ptr<ListNode> list(new ListNode);
416 list->set_begin_token(token); 418 list->set_begin_token(token);
417 list->set_end(make_scoped_ptr(new EndNode(token))); 419 list->set_end(make_scoped_ptr(new EndNode(token)));
418 scoped_ptr<BlockNode> block; 420 scoped_ptr<BlockNode> block;
419 bool has_arg = false; 421 bool has_arg = false;
420 if (LookAhead(Token::LEFT_PAREN)) { 422 if (LookAhead(Token::LEFT_PAREN)) {
(...skipping 11 matching lines...) Expand all
432 // Optionally with a scope. 434 // Optionally with a scope.
433 if (LookAhead(Token::LEFT_BRACE)) { 435 if (LookAhead(Token::LEFT_BRACE)) {
434 block = ParseBlock(); 436 block = ParseBlock();
435 if (has_error()) 437 if (has_error())
436 return scoped_ptr<ParseNode>(); 438 return scoped_ptr<ParseNode>();
437 } 439 }
438 } 440 }
439 441
440 if (!left && !has_arg) { 442 if (!left && !has_arg) {
441 // Not a function call, just a standalone identifier. 443 // Not a function call, just a standalone identifier.
442 return scoped_ptr<ParseNode>(new IdentifierNode(token)).Pass(); 444 return scoped_ptr<ParseNode>(new IdentifierNode(token));
443 } 445 }
444 scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode); 446 scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode);
445 func_call->set_function(token); 447 func_call->set_function(token);
446 func_call->set_args(list.Pass()); 448 func_call->set_args(std::move(list));
447 if (block) 449 if (block)
448 func_call->set_block(block.Pass()); 450 func_call->set_block(std::move(block));
449 return func_call.Pass(); 451 return std::move(func_call);
450 } 452 }
451 453
452 scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left, 454 scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left,
453 Token token) { 455 Token token) {
454 if (left->AsIdentifier() == nullptr) { 456 if (left->AsIdentifier() == nullptr) {
455 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier."); 457 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier.");
456 return scoped_ptr<ParseNode>(); 458 return scoped_ptr<ParseNode>();
457 } 459 }
458 scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT); 460 scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT);
459 if (!value) { 461 if (!value) {
460 if (!has_error()) 462 if (!has_error())
461 *err_ = Err(token, "Expected right-hand side for assignment."); 463 *err_ = Err(token, "Expected right-hand side for assignment.");
462 return scoped_ptr<ParseNode>(); 464 return scoped_ptr<ParseNode>();
463 } 465 }
464 scoped_ptr<BinaryOpNode> assign(new BinaryOpNode); 466 scoped_ptr<BinaryOpNode> assign(new BinaryOpNode);
465 assign->set_op(token); 467 assign->set_op(token);
466 assign->set_left(left.Pass()); 468 assign->set_left(std::move(left));
467 assign->set_right(value.Pass()); 469 assign->set_right(std::move(value));
468 return assign.Pass(); 470 return std::move(assign);
469 } 471 }
470 472
471 scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left, 473 scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left,
472 Token token) { 474 Token token) {
473 // TODO: Maybe support more complex expressions like a[0][0]. This would 475 // TODO: Maybe support more complex expressions like a[0][0]. This would
474 // require work on the evaluator too. 476 // require work on the evaluator too.
475 if (left->AsIdentifier() == nullptr) { 477 if (left->AsIdentifier() == nullptr) {
476 *err_ = Err(left.get(), "May only subscript identifiers.", 478 *err_ = Err(left.get(), "May only subscript identifiers.",
477 "The thing on the left hand side of the [] must be an identifier\n" 479 "The thing on the left hand side of the [] must be an identifier\n"
478 "and not an expression. If you need this, you'll have to assign the\n" 480 "and not an expression. If you need this, you'll have to assign the\n"
479 "value to a temporary before subscripting. Sorry."); 481 "value to a temporary before subscripting. Sorry.");
480 return scoped_ptr<ParseNode>(); 482 return scoped_ptr<ParseNode>();
481 } 483 }
482 scoped_ptr<ParseNode> value = ParseExpression(); 484 scoped_ptr<ParseNode> value = ParseExpression();
483 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript."); 485 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript.");
484 scoped_ptr<AccessorNode> accessor(new AccessorNode); 486 scoped_ptr<AccessorNode> accessor(new AccessorNode);
485 accessor->set_base(left->AsIdentifier()->value()); 487 accessor->set_base(left->AsIdentifier()->value());
486 accessor->set_index(value.Pass()); 488 accessor->set_index(std::move(value));
487 return accessor.Pass(); 489 return std::move(accessor);
488 } 490 }
489 491
490 scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left, 492 scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left,
491 Token token) { 493 Token token) {
492 if (left->AsIdentifier() == nullptr) { 494 if (left->AsIdentifier() == nullptr) {
493 *err_ = Err(left.get(), "May only use \".\" for identifiers.", 495 *err_ = Err(left.get(), "May only use \".\" for identifiers.",
494 "The thing on the left hand side of the dot must be an identifier\n" 496 "The thing on the left hand side of the dot must be an identifier\n"
495 "and not an expression. If you need this, you'll have to assign the\n" 497 "and not an expression. If you need this, you'll have to assign the\n"
496 "value to a temporary first. Sorry."); 498 "value to a temporary first. Sorry.");
497 return scoped_ptr<ParseNode>(); 499 return scoped_ptr<ParseNode>();
498 } 500 }
499 501
500 scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT); 502 scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT);
501 if (!right || !right->AsIdentifier()) { 503 if (!right || !right->AsIdentifier()) {
502 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"", 504 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"",
503 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()"); 505 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()");
504 return scoped_ptr<ParseNode>(); 506 return scoped_ptr<ParseNode>();
505 } 507 }
506 508
507 scoped_ptr<AccessorNode> accessor(new AccessorNode); 509 scoped_ptr<AccessorNode> accessor(new AccessorNode);
508 accessor->set_base(left->AsIdentifier()->value()); 510 accessor->set_base(left->AsIdentifier()->value());
509 accessor->set_member(scoped_ptr<IdentifierNode>( 511 accessor->set_member(scoped_ptr<IdentifierNode>(
510 static_cast<IdentifierNode*>(right.release()))); 512 static_cast<IdentifierNode*>(right.release())));
511 return accessor.Pass(); 513 return std::move(accessor);
512 } 514 }
513 515
514 // Does not Consume the start or end token. 516 // Does not Consume the start or end token.
515 scoped_ptr<ListNode> Parser::ParseList(Token start_token, 517 scoped_ptr<ListNode> Parser::ParseList(Token start_token,
516 Token::Type stop_before, 518 Token::Type stop_before,
517 bool allow_trailing_comma) { 519 bool allow_trailing_comma) {
518 scoped_ptr<ListNode> list(new ListNode); 520 scoped_ptr<ListNode> list(new ListNode);
519 list->set_begin_token(start_token); 521 list->set_begin_token(start_token);
520 bool just_got_comma = false; 522 bool just_got_comma = false;
521 bool first_time = true; 523 bool first_time = true;
(...skipping 24 matching lines...) Expand all
546 just_got_comma = allow_trailing_comma; 548 just_got_comma = allow_trailing_comma;
547 } else { 549 } else {
548 just_got_comma = Match(Token::COMMA); 550 just_got_comma = Match(Token::COMMA);
549 } 551 }
550 } 552 }
551 if (just_got_comma && !allow_trailing_comma) { 553 if (just_got_comma && !allow_trailing_comma) {
552 *err_ = Err(cur_token(), "Trailing comma"); 554 *err_ = Err(cur_token(), "Trailing comma");
553 return scoped_ptr<ListNode>(); 555 return scoped_ptr<ListNode>();
554 } 556 }
555 list->set_end(make_scoped_ptr(new EndNode(cur_token()))); 557 list->set_end(make_scoped_ptr(new EndNode(cur_token())));
556 return list.Pass(); 558 return list;
557 } 559 }
558 560
559 scoped_ptr<ParseNode> Parser::ParseFile() { 561 scoped_ptr<ParseNode> Parser::ParseFile() {
560 scoped_ptr<BlockNode> file(new BlockNode); 562 scoped_ptr<BlockNode> file(new BlockNode);
561 for (;;) { 563 for (;;) {
562 if (at_end()) 564 if (at_end())
563 break; 565 break;
564 scoped_ptr<ParseNode> statement = ParseStatement(); 566 scoped_ptr<ParseNode> statement = ParseStatement();
565 if (!statement) 567 if (!statement)
566 break; 568 break;
567 file->append_statement(statement.Pass()); 569 file->append_statement(std::move(statement));
568 } 570 }
569 if (!at_end() && !has_error()) 571 if (!at_end() && !has_error())
570 *err_ = Err(cur_token(), "Unexpected here, should be newline."); 572 *err_ = Err(cur_token(), "Unexpected here, should be newline.");
571 if (has_error()) 573 if (has_error())
572 return scoped_ptr<ParseNode>(); 574 return scoped_ptr<ParseNode>();
573 575
574 // TODO(scottmg): If this is measurably expensive, it could be done only 576 // TODO(scottmg): If this is measurably expensive, it could be done only
575 // when necessary (when reformatting, or during tests). Comments are 577 // when necessary (when reformatting, or during tests). Comments are
576 // separate from the parse tree at this point, so downstream code can remain 578 // separate from the parse tree at this point, so downstream code can remain
577 // ignorant of them. 579 // ignorant of them.
578 AssignComments(file.get()); 580 AssignComments(file.get());
579 581
580 return file.Pass(); 582 return std::move(file);
581 } 583 }
582 584
583 scoped_ptr<ParseNode> Parser::ParseStatement() { 585 scoped_ptr<ParseNode> Parser::ParseStatement() {
584 if (LookAhead(Token::IF)) { 586 if (LookAhead(Token::IF)) {
585 return ParseCondition(); 587 return ParseCondition();
586 } else if (LookAhead(Token::BLOCK_COMMENT)) { 588 } else if (LookAhead(Token::BLOCK_COMMENT)) {
587 return BlockComment(Consume()); 589 return BlockComment(Consume());
588 } else { 590 } else {
589 // TODO(scottmg): Is this too strict? Just drop all the testing if we want 591 // TODO(scottmg): Is this too strict? Just drop all the testing if we want
590 // to allow "pointless" expressions and return ParseExpression() directly. 592 // to allow "pointless" expressions and return ParseExpression() directly.
591 scoped_ptr<ParseNode> stmt = ParseExpression(); 593 scoped_ptr<ParseNode> stmt = ParseExpression();
592 if (stmt) { 594 if (stmt) {
593 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) 595 if (stmt->AsFunctionCall() || IsAssignment(stmt.get()))
594 return stmt.Pass(); 596 return stmt;
595 } 597 }
596 if (!has_error()) { 598 if (!has_error()) {
597 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); 599 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token();
598 *err_ = Err(token, "Expecting assignment or function call."); 600 *err_ = Err(token, "Expecting assignment or function call.");
599 } 601 }
600 return scoped_ptr<ParseNode>(); 602 return scoped_ptr<ParseNode>();
601 } 603 }
602 } 604 }
603 605
604 scoped_ptr<BlockNode> Parser::ParseBlock() { 606 scoped_ptr<BlockNode> Parser::ParseBlock() {
605 Token begin_token = 607 Token begin_token =
606 Consume(Token::LEFT_BRACE, "Expected '{' to start a block."); 608 Consume(Token::LEFT_BRACE, "Expected '{' to start a block.");
607 if (has_error()) 609 if (has_error())
608 return scoped_ptr<BlockNode>(); 610 return scoped_ptr<BlockNode>();
609 scoped_ptr<BlockNode> block(new BlockNode); 611 scoped_ptr<BlockNode> block(new BlockNode);
610 block->set_begin_token(begin_token); 612 block->set_begin_token(begin_token);
611 613
612 for (;;) { 614 for (;;) {
613 if (LookAhead(Token::RIGHT_BRACE)) { 615 if (LookAhead(Token::RIGHT_BRACE)) {
614 block->set_end(make_scoped_ptr(new EndNode(Consume()))); 616 block->set_end(make_scoped_ptr(new EndNode(Consume())));
615 break; 617 break;
616 } 618 }
617 619
618 scoped_ptr<ParseNode> statement = ParseStatement(); 620 scoped_ptr<ParseNode> statement = ParseStatement();
619 if (!statement) 621 if (!statement)
620 return scoped_ptr<BlockNode>(); 622 return scoped_ptr<BlockNode>();
621 block->append_statement(statement.Pass()); 623 block->append_statement(std::move(statement));
622 } 624 }
623 return block.Pass(); 625 return block;
624 } 626 }
625 627
626 scoped_ptr<ParseNode> Parser::ParseCondition() { 628 scoped_ptr<ParseNode> Parser::ParseCondition() {
627 scoped_ptr<ConditionNode> condition(new ConditionNode); 629 scoped_ptr<ConditionNode> condition(new ConditionNode);
628 condition->set_if_token(Consume(Token::IF, "Expected 'if'")); 630 condition->set_if_token(Consume(Token::IF, "Expected 'if'"));
629 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'."); 631 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'.");
630 condition->set_condition(ParseExpression()); 632 condition->set_condition(ParseExpression());
631 if (IsAssignment(condition->condition())) 633 if (IsAssignment(condition->condition()))
632 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'."); 634 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'.");
633 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'."); 635 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'.");
634 condition->set_if_true(ParseBlock().Pass()); 636 condition->set_if_true(ParseBlock());
635 if (Match(Token::ELSE)) { 637 if (Match(Token::ELSE)) {
636 if (LookAhead(Token::LEFT_BRACE)) { 638 if (LookAhead(Token::LEFT_BRACE)) {
637 condition->set_if_false(ParseBlock().Pass()); 639 condition->set_if_false(ParseBlock());
638 } else if (LookAhead(Token::IF)) { 640 } else if (LookAhead(Token::IF)) {
639 condition->set_if_false(ParseStatement().Pass()); 641 condition->set_if_false(ParseStatement());
640 } else { 642 } else {
641 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); 643 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'.");
642 return scoped_ptr<ParseNode>(); 644 return scoped_ptr<ParseNode>();
643 } 645 }
644 } 646 }
645 if (has_error()) 647 if (has_error())
646 return scoped_ptr<ParseNode>(); 648 return scoped_ptr<ParseNode>();
647 return condition.Pass(); 649 return std::move(condition);
648 } 650 }
649 651
650 void Parser::TraverseOrder(const ParseNode* root, 652 void Parser::TraverseOrder(const ParseNode* root,
651 std::vector<const ParseNode*>* pre, 653 std::vector<const ParseNode*>* pre,
652 std::vector<const ParseNode*>* post) { 654 std::vector<const ParseNode*>* post) {
653 if (root) { 655 if (root) {
654 pre->push_back(root); 656 pre->push_back(root);
655 657
656 if (const AccessorNode* accessor = root->AsAccessor()) { 658 if (const AccessorNode* accessor = root->AsAccessor()) {
657 TraverseOrder(accessor->index(), pre, post); 659 TraverseOrder(accessor->index(), pre, post);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 break; 753 break;
752 } 754 }
753 } 755 }
754 756
755 // Suffix comments were assigned in reverse, so if there were multiple on 757 // Suffix comments were assigned in reverse, so if there were multiple on
756 // the same node, they need to be reversed. 758 // the same node, they need to be reversed.
757 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) 759 if ((*i)->comments() && !(*i)->comments()->suffix().empty())
758 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); 760 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix();
759 } 761 }
760 } 762 }
OLDNEW
« no previous file with comments | « tools/gn/parse_tree_unittest.cc ('k') | tools/gn/scope.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698