Index: tools/gn/parser.cc |
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc |
index d3e2f0ff2efec7fa9cb33efac51f31d856239f4c..33abfd0b2f0e7378c5b11cb8dde83ac60d5684a5 100644 |
--- a/tools/gn/parser.cc |
+++ b/tools/gn/parser.cc |
@@ -7,6 +7,7 @@ |
#include <utility> |
#include "base/logging.h" |
+#include "base/memory/ptr_util.h" |
#include "tools/gn/functions.h" |
#include "tools/gn/operators.h" |
#include "tools/gn/token.h" |
@@ -206,17 +207,18 @@ Parser::~Parser() { |
} |
// static |
-scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, |
- Err* err) { |
+std::unique_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, |
+ Err* err) { |
Parser p(tokens, err); |
return p.ParseFile(); |
} |
// static |
-scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens, |
- Err* err) { |
+std::unique_ptr<ParseNode> Parser::ParseExpression( |
+ const std::vector<Token>& tokens, |
+ Err* err) { |
Parser p(tokens, err); |
- scoped_ptr<ParseNode> expr = p.ParseExpression(); |
+ std::unique_ptr<ParseNode> expr = p.ParseExpression(); |
if (!p.at_end() && !err->has_error()) { |
*err = Err(p.cur_token(), "Trailing garbage"); |
return nullptr; |
@@ -225,8 +227,8 @@ scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens, |
} |
// static |
-scoped_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens, |
- Err* err) { |
+std::unique_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens, |
+ Err* err) { |
for (const Token& token : tokens) { |
switch (token.type()) { |
case Token::INTEGER: |
@@ -314,13 +316,13 @@ Token Parser::Consume() { |
return tokens_[cur_++]; |
} |
-scoped_ptr<ParseNode> Parser::ParseExpression() { |
+std::unique_ptr<ParseNode> Parser::ParseExpression() { |
return ParseExpression(0); |
} |
-scoped_ptr<ParseNode> Parser::ParseExpression(int precedence) { |
+std::unique_ptr<ParseNode> Parser::ParseExpression(int precedence) { |
if (at_end()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
Token token = Consume(); |
PrefixFunc prefix = expressions_[token.type()].prefix; |
@@ -329,10 +331,10 @@ scoped_ptr<ParseNode> Parser::ParseExpression(int precedence) { |
*err_ = Err(token, |
std::string("Unexpected token '") + token.value().as_string() + |
std::string("'")); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<ParseNode> left = (this->*prefix)(token); |
+ std::unique_ptr<ParseNode> left = (this->*prefix)(token); |
if (has_error()) |
return left; |
@@ -344,84 +346,86 @@ scoped_ptr<ParseNode> Parser::ParseExpression(int precedence) { |
*err_ = Err(token, |
std::string("Unexpected token '") + |
token.value().as_string() + std::string("'")); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
left = (this->*infix)(std::move(left), token); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
return left; |
} |
-scoped_ptr<ParseNode> Parser::Literal(Token token) { |
- return make_scoped_ptr(new LiteralNode(token)); |
+std::unique_ptr<ParseNode> Parser::Literal(Token token) { |
+ return base::WrapUnique(new LiteralNode(token)); |
} |
-scoped_ptr<ParseNode> Parser::Name(Token token) { |
- return IdentifierOrCall(scoped_ptr<ParseNode>(), token); |
+std::unique_ptr<ParseNode> Parser::Name(Token token) { |
+ return IdentifierOrCall(std::unique_ptr<ParseNode>(), token); |
} |
-scoped_ptr<ParseNode> Parser::BlockComment(Token token) { |
- scoped_ptr<BlockCommentNode> comment(new BlockCommentNode()); |
+std::unique_ptr<ParseNode> Parser::BlockComment(Token token) { |
+ std::unique_ptr<BlockCommentNode> comment(new BlockCommentNode()); |
comment->set_comment(token); |
return std::move(comment); |
} |
-scoped_ptr<ParseNode> Parser::Group(Token token) { |
- scoped_ptr<ParseNode> expr = ParseExpression(); |
+std::unique_ptr<ParseNode> Parser::Group(Token token) { |
+ std::unique_ptr<ParseNode> expr = ParseExpression(); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
Consume(Token::RIGHT_PAREN, "Expected ')'"); |
return expr; |
} |
-scoped_ptr<ParseNode> Parser::Not(Token token) { |
- scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1); |
+std::unique_ptr<ParseNode> Parser::Not(Token token) { |
+ std::unique_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
if (!expr) { |
if (!has_error()) |
*err_ = Err(token, "Expected right-hand side for '!'."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode); |
+ std::unique_ptr<UnaryOpNode> unary_op(new UnaryOpNode); |
unary_op->set_op(token); |
unary_op->set_operand(std::move(expr)); |
return std::move(unary_op); |
} |
-scoped_ptr<ParseNode> Parser::List(Token node) { |
- scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true)); |
+std::unique_ptr<ParseNode> Parser::List(Token node) { |
+ std::unique_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true)); |
if (!has_error() && !at_end()) |
Consume(Token::RIGHT_BRACKET, "Expected ']'"); |
return list; |
} |
-scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left, |
- Token token) { |
- scoped_ptr<ParseNode> right = |
+std::unique_ptr<ParseNode> Parser::BinaryOperator( |
+ std::unique_ptr<ParseNode> left, |
+ Token token) { |
+ std::unique_ptr<ParseNode> right = |
ParseExpression(expressions_[token.type()].precedence + 1); |
if (!right) { |
if (!has_error()) { |
*err_ = Err(token, "Expected right-hand side for '" + |
token.value().as_string() + "'"); |
} |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode); |
+ std::unique_ptr<BinaryOpNode> binary_op(new BinaryOpNode); |
binary_op->set_op(token); |
binary_op->set_left(std::move(left)); |
binary_op->set_right(std::move(right)); |
return std::move(binary_op); |
} |
-scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, |
- Token token) { |
- scoped_ptr<ListNode> list(new ListNode); |
+std::unique_ptr<ParseNode> Parser::IdentifierOrCall( |
+ std::unique_ptr<ParseNode> left, |
+ Token token) { |
+ std::unique_ptr<ListNode> list(new ListNode); |
list->set_begin_token(token); |
- list->set_end(make_scoped_ptr(new EndNode(token))); |
- scoped_ptr<BlockNode> block; |
+ list->set_end(base::WrapUnique(new EndNode(token))); |
+ std::unique_ptr<BlockNode> block; |
bool has_arg = false; |
if (LookAhead(Token::LEFT_PAREN)) { |
Token start_token = Consume(); |
@@ -432,22 +436,22 @@ scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, |
} else { |
list = ParseList(start_token, Token::RIGHT_PAREN, false); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
Consume(Token::RIGHT_PAREN, "Expected ')' after call"); |
} |
// Optionally with a scope. |
if (LookAhead(Token::LEFT_BRACE)) { |
block = ParseBlock(); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
} |
if (!left && !has_arg) { |
// Not a function call, just a standalone identifier. |
- return scoped_ptr<ParseNode>(new IdentifierNode(token)); |
+ return std::unique_ptr<ParseNode>(new IdentifierNode(token)); |
} |
- scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode); |
+ std::unique_ptr<FunctionCallNode> func_call(new FunctionCallNode); |
func_call->set_function(token); |
func_call->set_args(std::move(list)); |
if (block) |
@@ -455,27 +459,27 @@ scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, |
return std::move(func_call); |
} |
-scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left, |
- Token token) { |
+std::unique_ptr<ParseNode> Parser::Assignment(std::unique_ptr<ParseNode> left, |
+ Token token) { |
if (left->AsIdentifier() == nullptr) { |
*err_ = Err(left.get(), "Left-hand side of assignment must be identifier."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT); |
+ std::unique_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT); |
if (!value) { |
if (!has_error()) |
*err_ = Err(token, "Expected right-hand side for assignment."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<BinaryOpNode> assign(new BinaryOpNode); |
+ std::unique_ptr<BinaryOpNode> assign(new BinaryOpNode); |
assign->set_op(token); |
assign->set_left(std::move(left)); |
assign->set_right(std::move(value)); |
return std::move(assign); |
} |
-scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left, |
- Token token) { |
+std::unique_ptr<ParseNode> Parser::Subscript(std::unique_ptr<ParseNode> left, |
+ Token token) { |
// TODO: Maybe support more complex expressions like a[0][0]. This would |
// require work on the evaluator too. |
if (left->AsIdentifier() == nullptr) { |
@@ -483,45 +487,45 @@ scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left, |
"The thing on the left hand side of the [] must be an identifier\n" |
"and not an expression. If you need this, you'll have to assign the\n" |
"value to a temporary before subscripting. Sorry."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<ParseNode> value = ParseExpression(); |
+ std::unique_ptr<ParseNode> value = ParseExpression(); |
Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript."); |
- scoped_ptr<AccessorNode> accessor(new AccessorNode); |
+ std::unique_ptr<AccessorNode> accessor(new AccessorNode); |
accessor->set_base(left->AsIdentifier()->value()); |
accessor->set_index(std::move(value)); |
return std::move(accessor); |
} |
-scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left, |
- Token token) { |
+std::unique_ptr<ParseNode> Parser::DotOperator(std::unique_ptr<ParseNode> left, |
+ Token token) { |
if (left->AsIdentifier() == nullptr) { |
*err_ = Err(left.get(), "May only use \".\" for identifiers.", |
"The thing on the left hand side of the dot must be an identifier\n" |
"and not an expression. If you need this, you'll have to assign the\n" |
"value to a temporary first. Sorry."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT); |
+ std::unique_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT); |
if (!right || !right->AsIdentifier()) { |
*err_ = Err(token, "Expected identifier for right-hand-side of \".\"", |
"Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()"); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
- scoped_ptr<AccessorNode> accessor(new AccessorNode); |
+ std::unique_ptr<AccessorNode> accessor(new AccessorNode); |
accessor->set_base(left->AsIdentifier()->value()); |
- accessor->set_member(scoped_ptr<IdentifierNode>( |
+ accessor->set_member(std::unique_ptr<IdentifierNode>( |
static_cast<IdentifierNode*>(right.release()))); |
return std::move(accessor); |
} |
// Does not Consume the start or end token. |
-scoped_ptr<ListNode> Parser::ParseList(Token start_token, |
- Token::Type stop_before, |
- bool allow_trailing_comma) { |
- scoped_ptr<ListNode> list(new ListNode); |
+std::unique_ptr<ListNode> Parser::ParseList(Token start_token, |
+ Token::Type stop_before, |
+ bool allow_trailing_comma) { |
+ std::unique_ptr<ListNode> list(new ListNode); |
list->set_begin_token(start_token); |
bool just_got_comma = false; |
bool first_time = true; |
@@ -530,7 +534,7 @@ scoped_ptr<ListNode> Parser::ParseList(Token start_token, |
if (!just_got_comma) { |
// Require commas separate things in lists. |
*err_ = Err(cur_token(), "Expected comma between items."); |
- return scoped_ptr<ListNode>(); |
+ return std::unique_ptr<ListNode>(); |
} |
} |
first_time = false; |
@@ -540,11 +544,11 @@ scoped_ptr<ListNode> Parser::ParseList(Token start_token, |
// boolean expressions (the lowest of which is OR), but above assignments. |
list->append_item(ParseExpression(PRECEDENCE_OR)); |
if (has_error()) |
- return scoped_ptr<ListNode>(); |
+ return std::unique_ptr<ListNode>(); |
if (at_end()) { |
*err_ = |
Err(tokens_[tokens_.size() - 1], "Unexpected end of file in list."); |
- return scoped_ptr<ListNode>(); |
+ return std::unique_ptr<ListNode>(); |
} |
if (list->contents().back()->AsBlockComment()) { |
// If there was a comment inside the list, we don't need a comma to the |
@@ -556,18 +560,18 @@ scoped_ptr<ListNode> Parser::ParseList(Token start_token, |
} |
if (just_got_comma && !allow_trailing_comma) { |
*err_ = Err(cur_token(), "Trailing comma"); |
- return scoped_ptr<ListNode>(); |
+ return std::unique_ptr<ListNode>(); |
} |
- list->set_end(make_scoped_ptr(new EndNode(cur_token()))); |
+ list->set_end(base::WrapUnique(new EndNode(cur_token()))); |
return list; |
} |
-scoped_ptr<ParseNode> Parser::ParseFile() { |
- scoped_ptr<BlockNode> file(new BlockNode); |
+std::unique_ptr<ParseNode> Parser::ParseFile() { |
+ std::unique_ptr<BlockNode> file(new BlockNode); |
for (;;) { |
if (at_end()) |
break; |
- scoped_ptr<ParseNode> statement = ParseStatement(); |
+ std::unique_ptr<ParseNode> statement = ParseStatement(); |
if (!statement) |
break; |
file->append_statement(std::move(statement)); |
@@ -575,7 +579,7 @@ scoped_ptr<ParseNode> Parser::ParseFile() { |
if (!at_end() && !has_error()) |
*err_ = Err(cur_token(), "Unexpected here, should be newline."); |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
// TODO(scottmg): If this is measurably expensive, it could be done only |
// when necessary (when reformatting, or during tests). Comments are |
@@ -586,7 +590,7 @@ scoped_ptr<ParseNode> Parser::ParseFile() { |
return std::move(file); |
} |
-scoped_ptr<ParseNode> Parser::ParseStatement() { |
+std::unique_ptr<ParseNode> Parser::ParseStatement() { |
if (LookAhead(Token::IF)) { |
return ParseCondition(); |
} else if (LookAhead(Token::BLOCK_COMMENT)) { |
@@ -594,7 +598,7 @@ scoped_ptr<ParseNode> Parser::ParseStatement() { |
} else { |
// TODO(scottmg): Is this too strict? Just drop all the testing if we want |
// to allow "pointless" expressions and return ParseExpression() directly. |
- scoped_ptr<ParseNode> stmt = ParseExpression(); |
+ std::unique_ptr<ParseNode> stmt = ParseExpression(); |
if (stmt) { |
if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) |
return stmt; |
@@ -603,34 +607,34 @@ scoped_ptr<ParseNode> Parser::ParseStatement() { |
Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); |
*err_ = Err(token, "Expecting assignment or function call."); |
} |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
} |
-scoped_ptr<BlockNode> Parser::ParseBlock() { |
+std::unique_ptr<BlockNode> Parser::ParseBlock() { |
Token begin_token = |
Consume(Token::LEFT_BRACE, "Expected '{' to start a block."); |
if (has_error()) |
- return scoped_ptr<BlockNode>(); |
- scoped_ptr<BlockNode> block(new BlockNode); |
+ return std::unique_ptr<BlockNode>(); |
+ std::unique_ptr<BlockNode> block(new BlockNode); |
block->set_begin_token(begin_token); |
for (;;) { |
if (LookAhead(Token::RIGHT_BRACE)) { |
- block->set_end(make_scoped_ptr(new EndNode(Consume()))); |
+ block->set_end(base::WrapUnique(new EndNode(Consume()))); |
break; |
} |
- scoped_ptr<ParseNode> statement = ParseStatement(); |
+ std::unique_ptr<ParseNode> statement = ParseStatement(); |
if (!statement) |
- return scoped_ptr<BlockNode>(); |
+ return std::unique_ptr<BlockNode>(); |
block->append_statement(std::move(statement)); |
} |
return block; |
} |
-scoped_ptr<ParseNode> Parser::ParseCondition() { |
- scoped_ptr<ConditionNode> condition(new ConditionNode); |
+std::unique_ptr<ParseNode> Parser::ParseCondition() { |
+ std::unique_ptr<ConditionNode> condition(new ConditionNode); |
condition->set_if_token(Consume(Token::IF, "Expected 'if'")); |
Consume(Token::LEFT_PAREN, "Expected '(' after 'if'."); |
condition->set_condition(ParseExpression()); |
@@ -645,11 +649,11 @@ scoped_ptr<ParseNode> Parser::ParseCondition() { |
condition->set_if_false(ParseStatement()); |
} else { |
*err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
} |
} |
if (has_error()) |
- return scoped_ptr<ParseNode>(); |
+ return std::unique_ptr<ParseNode>(); |
return std::move(condition); |
} |