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

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

Issue 656093004: Use scoped_ptr::Pass instead of scoped_ptr::PassAs<T>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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/operators_unittest.cc ('k') | 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 (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 "base/logging.h" 7 #include "base/logging.h"
8 #include "tools/gn/functions.h" 8 #include "tools/gn/functions.h"
9 #include "tools/gn/operators.h" 9 #include "tools/gn/operators.h"
10 #include "tools/gn/token.h" 10 #include "tools/gn/token.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 } 100 }
101 101
102 Parser::~Parser() { 102 Parser::~Parser() {
103 } 103 }
104 104
105 // static 105 // static
106 scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, 106 scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens,
107 Err* err) { 107 Err* err) {
108 Parser p(tokens, err); 108 Parser p(tokens, err);
109 return p.ParseFile().PassAs<ParseNode>(); 109 return p.ParseFile();
110 } 110 }
111 111
112 // static 112 // static
113 scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens, 113 scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens,
114 Err* err) { 114 Err* err) {
115 Parser p(tokens, err); 115 Parser p(tokens, err);
116 return p.ParseExpression().Pass(); 116 return p.ParseExpression().Pass();
117 } 117 }
118 118
119 bool Parser::IsAssignment(const ParseNode* node) const { 119 bool Parser::IsAssignment(const ParseNode* node) const {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 218 }
219 left = (this->*infix)(left.Pass(), token); 219 left = (this->*infix)(left.Pass(), token);
220 if (has_error()) 220 if (has_error())
221 return scoped_ptr<ParseNode>(); 221 return scoped_ptr<ParseNode>();
222 } 222 }
223 223
224 return left.Pass(); 224 return left.Pass();
225 } 225 }
226 226
227 scoped_ptr<ParseNode> Parser::Literal(Token token) { 227 scoped_ptr<ParseNode> Parser::Literal(Token token) {
228 return scoped_ptr<ParseNode>(new LiteralNode(token)).Pass(); 228 return make_scoped_ptr(new LiteralNode(token));
229 } 229 }
230 230
231 scoped_ptr<ParseNode> Parser::Name(Token token) { 231 scoped_ptr<ParseNode> Parser::Name(Token token) {
232 return IdentifierOrCall(scoped_ptr<ParseNode>(), token).Pass(); 232 return IdentifierOrCall(scoped_ptr<ParseNode>(), token).Pass();
233 } 233 }
234 234
235 scoped_ptr<ParseNode> Parser::BlockComment(Token token) { 235 scoped_ptr<ParseNode> Parser::BlockComment(Token token) {
236 scoped_ptr<BlockCommentNode> comment(new BlockCommentNode()); 236 scoped_ptr<BlockCommentNode> comment(new BlockCommentNode());
237 comment->set_comment(token); 237 comment->set_comment(token);
238 return comment.PassAs<ParseNode>(); 238 return comment.Pass();
239 } 239 }
240 240
241 scoped_ptr<ParseNode> Parser::Group(Token token) { 241 scoped_ptr<ParseNode> Parser::Group(Token token) {
242 scoped_ptr<ParseNode> expr = ParseExpression(); 242 scoped_ptr<ParseNode> expr = ParseExpression();
243 if (has_error()) 243 if (has_error())
244 return scoped_ptr<ParseNode>(); 244 return scoped_ptr<ParseNode>();
245 Consume(Token::RIGHT_PAREN, "Expected ')'"); 245 Consume(Token::RIGHT_PAREN, "Expected ')'");
246 return expr.Pass(); 246 return expr.Pass();
247 } 247 }
248 248
249 scoped_ptr<ParseNode> Parser::Not(Token token) { 249 scoped_ptr<ParseNode> Parser::Not(Token token) {
250 scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1); 250 scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1);
251 if (has_error()) 251 if (has_error())
252 return scoped_ptr<ParseNode>(); 252 return scoped_ptr<ParseNode>();
253 scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode); 253 scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode);
254 unary_op->set_op(token); 254 unary_op->set_op(token);
255 unary_op->set_operand(expr.Pass()); 255 unary_op->set_operand(expr.Pass());
256 return unary_op.PassAs<ParseNode>(); 256 return unary_op.Pass();
257 } 257 }
258 258
259 scoped_ptr<ParseNode> Parser::List(Token node) { 259 scoped_ptr<ParseNode> Parser::List(Token node) {
260 scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true)); 260 scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true));
261 if (!has_error() && !at_end()) 261 if (!has_error() && !at_end())
262 Consume(Token::RIGHT_BRACKET, "Expected ']'"); 262 Consume(Token::RIGHT_BRACKET, "Expected ']'");
263 return list.Pass(); 263 return list.Pass();
264 } 264 }
265 265
266 scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left, 266 scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left,
267 Token token) { 267 Token token) {
268 scoped_ptr<ParseNode> right = 268 scoped_ptr<ParseNode> right =
269 ParseExpression(expressions_[token.type()].precedence + 1); 269 ParseExpression(expressions_[token.type()].precedence + 1);
270 if (!right) { 270 if (!right) {
271 *err_ = 271 *err_ =
272 Err(token, 272 Err(token,
273 "Expected right hand side for '" + token.value().as_string() + "'"); 273 "Expected right hand side for '" + token.value().as_string() + "'");
274 return scoped_ptr<ParseNode>(); 274 return scoped_ptr<ParseNode>();
275 } 275 }
276 scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode); 276 scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode);
277 binary_op->set_op(token); 277 binary_op->set_op(token);
278 binary_op->set_left(left.Pass()); 278 binary_op->set_left(left.Pass());
279 binary_op->set_right(right.Pass()); 279 binary_op->set_right(right.Pass());
280 return binary_op.PassAs<ParseNode>(); 280 return binary_op.Pass();
281 } 281 }
282 282
283 scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, 283 scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left,
284 Token token) { 284 Token token) {
285 scoped_ptr<ListNode> list(new ListNode); 285 scoped_ptr<ListNode> list(new ListNode);
286 list->set_begin_token(token); 286 list->set_begin_token(token);
287 list->set_end(make_scoped_ptr(new EndNode(token))); 287 list->set_end(make_scoped_ptr(new EndNode(token)));
288 scoped_ptr<BlockNode> block; 288 scoped_ptr<BlockNode> block;
289 bool has_arg = false; 289 bool has_arg = false;
290 if (LookAhead(Token::LEFT_PAREN)) { 290 if (LookAhead(Token::LEFT_PAREN)) {
(...skipping 18 matching lines...) Expand all
309 309
310 if (!left && !has_arg) { 310 if (!left && !has_arg) {
311 // Not a function call, just a standalone identifier. 311 // Not a function call, just a standalone identifier.
312 return scoped_ptr<ParseNode>(new IdentifierNode(token)).Pass(); 312 return scoped_ptr<ParseNode>(new IdentifierNode(token)).Pass();
313 } 313 }
314 scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode); 314 scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode);
315 func_call->set_function(token); 315 func_call->set_function(token);
316 func_call->set_args(list.Pass()); 316 func_call->set_args(list.Pass());
317 if (block) 317 if (block)
318 func_call->set_block(block.Pass()); 318 func_call->set_block(block.Pass());
319 return func_call.PassAs<ParseNode>(); 319 return func_call.Pass();
320 } 320 }
321 321
322 scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left, 322 scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left,
323 Token token) { 323 Token token) {
324 if (left->AsIdentifier() == NULL) { 324 if (left->AsIdentifier() == NULL) {
325 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier."); 325 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier.");
326 return scoped_ptr<ParseNode>(); 326 return scoped_ptr<ParseNode>();
327 } 327 }
328 scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT); 328 scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT);
329 scoped_ptr<BinaryOpNode> assign(new BinaryOpNode); 329 scoped_ptr<BinaryOpNode> assign(new BinaryOpNode);
330 assign->set_op(token); 330 assign->set_op(token);
331 assign->set_left(left.Pass()); 331 assign->set_left(left.Pass());
332 assign->set_right(value.Pass()); 332 assign->set_right(value.Pass());
333 return assign.PassAs<ParseNode>(); 333 return assign.Pass();
334 } 334 }
335 335
336 scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left, 336 scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left,
337 Token token) { 337 Token token) {
338 // TODO: Maybe support more complex expressions like a[0][0]. This would 338 // TODO: Maybe support more complex expressions like a[0][0]. This would
339 // require work on the evaluator too. 339 // require work on the evaluator too.
340 if (left->AsIdentifier() == NULL) { 340 if (left->AsIdentifier() == NULL) {
341 *err_ = Err(left.get(), "May only subscript identifiers.", 341 *err_ = Err(left.get(), "May only subscript identifiers.",
342 "The thing on the left hand side of the [] must be an identifier\n" 342 "The thing on the left hand side of the [] must be an identifier\n"
343 "and not an expression. If you need this, you'll have to assign the\n" 343 "and not an expression. If you need this, you'll have to assign the\n"
344 "value to a temporary before subscripting. Sorry."); 344 "value to a temporary before subscripting. Sorry.");
345 return scoped_ptr<ParseNode>(); 345 return scoped_ptr<ParseNode>();
346 } 346 }
347 scoped_ptr<ParseNode> value = ParseExpression(); 347 scoped_ptr<ParseNode> value = ParseExpression();
348 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript."); 348 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript.");
349 scoped_ptr<AccessorNode> accessor(new AccessorNode); 349 scoped_ptr<AccessorNode> accessor(new AccessorNode);
350 accessor->set_base(left->AsIdentifier()->value()); 350 accessor->set_base(left->AsIdentifier()->value());
351 accessor->set_index(value.Pass()); 351 accessor->set_index(value.Pass());
352 return accessor.PassAs<ParseNode>(); 352 return accessor.Pass();
353 } 353 }
354 354
355 scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left, 355 scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left,
356 Token token) { 356 Token token) {
357 if (left->AsIdentifier() == NULL) { 357 if (left->AsIdentifier() == NULL) {
358 *err_ = Err(left.get(), "May only use \".\" for identifiers.", 358 *err_ = Err(left.get(), "May only use \".\" for identifiers.",
359 "The thing on the left hand side of the dot must be an identifier\n" 359 "The thing on the left hand side of the dot must be an identifier\n"
360 "and not an expression. If you need this, you'll have to assign the\n" 360 "and not an expression. If you need this, you'll have to assign the\n"
361 "value to a temporary first. Sorry."); 361 "value to a temporary first. Sorry.");
362 return scoped_ptr<ParseNode>(); 362 return scoped_ptr<ParseNode>();
363 } 363 }
364 364
365 scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT); 365 scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT);
366 if (!right || !right->AsIdentifier()) { 366 if (!right || !right->AsIdentifier()) {
367 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"", 367 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"",
368 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()"); 368 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()");
369 return scoped_ptr<ParseNode>(); 369 return scoped_ptr<ParseNode>();
370 } 370 }
371 371
372 scoped_ptr<AccessorNode> accessor(new AccessorNode); 372 scoped_ptr<AccessorNode> accessor(new AccessorNode);
373 accessor->set_base(left->AsIdentifier()->value()); 373 accessor->set_base(left->AsIdentifier()->value());
374 accessor->set_member(scoped_ptr<IdentifierNode>( 374 accessor->set_member(scoped_ptr<IdentifierNode>(
375 static_cast<IdentifierNode*>(right.release()))); 375 static_cast<IdentifierNode*>(right.release())));
376 return accessor.PassAs<ParseNode>(); 376 return accessor.Pass();
377 } 377 }
378 378
379 // Does not Consume the start or end token. 379 // Does not Consume the start or end token.
380 scoped_ptr<ListNode> Parser::ParseList(Token start_token, 380 scoped_ptr<ListNode> Parser::ParseList(Token start_token,
381 Token::Type stop_before, 381 Token::Type stop_before,
382 bool allow_trailing_comma) { 382 bool allow_trailing_comma) {
383 scoped_ptr<ListNode> list(new ListNode); 383 scoped_ptr<ListNode> list(new ListNode);
384 list->set_begin_token(start_token); 384 list->set_begin_token(start_token);
385 bool just_got_comma = false; 385 bool just_got_comma = false;
386 bool first_time = true; 386 bool first_time = true;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 *err_ = Err(cur_token(), "Unexpected here, should be newline."); 435 *err_ = Err(cur_token(), "Unexpected here, should be newline.");
436 if (has_error()) 436 if (has_error())
437 return scoped_ptr<ParseNode>(); 437 return scoped_ptr<ParseNode>();
438 438
439 // TODO(scottmg): If this is measurably expensive, it could be done only 439 // TODO(scottmg): If this is measurably expensive, it could be done only
440 // when necessary (when reformatting, or during tests). Comments are 440 // when necessary (when reformatting, or during tests). Comments are
441 // separate from the parse tree at this point, so downstream code can remain 441 // separate from the parse tree at this point, so downstream code can remain
442 // ignorant of them. 442 // ignorant of them.
443 AssignComments(file.get()); 443 AssignComments(file.get());
444 444
445 return file.PassAs<ParseNode>(); 445 return file.Pass();
446 } 446 }
447 447
448 scoped_ptr<ParseNode> Parser::ParseStatement() { 448 scoped_ptr<ParseNode> Parser::ParseStatement() {
449 if (LookAhead(Token::LEFT_BRACE)) { 449 if (LookAhead(Token::LEFT_BRACE)) {
450 return ParseBlock().PassAs<ParseNode>(); 450 return ParseBlock();
451 } else if (LookAhead(Token::IF)) { 451 } else if (LookAhead(Token::IF)) {
452 return ParseCondition(); 452 return ParseCondition();
453 } else if (LookAhead(Token::BLOCK_COMMENT)) { 453 } else if (LookAhead(Token::BLOCK_COMMENT)) {
454 return BlockComment(Consume()); 454 return BlockComment(Consume());
455 } else { 455 } else {
456 // TODO(scottmg): Is this too strict? Just drop all the testing if we want 456 // TODO(scottmg): Is this too strict? Just drop all the testing if we want
457 // to allow "pointless" expressions and return ParseExpression() directly. 457 // to allow "pointless" expressions and return ParseExpression() directly.
458 scoped_ptr<ParseNode> stmt = ParseExpression(); 458 scoped_ptr<ParseNode> stmt = ParseExpression();
459 if (stmt) { 459 if (stmt) {
460 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) 460 if (stmt->AsFunctionCall() || IsAssignment(stmt.get()))
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'."); 496 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'.");
497 condition->set_condition(ParseExpression()); 497 condition->set_condition(ParseExpression());
498 if (IsAssignment(condition->condition())) 498 if (IsAssignment(condition->condition()))
499 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'."); 499 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'.");
500 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'."); 500 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'.");
501 condition->set_if_true(ParseBlock().Pass()); 501 condition->set_if_true(ParseBlock().Pass());
502 if (Match(Token::ELSE)) 502 if (Match(Token::ELSE))
503 condition->set_if_false(ParseStatement().Pass()); 503 condition->set_if_false(ParseStatement().Pass());
504 if (has_error()) 504 if (has_error())
505 return scoped_ptr<ParseNode>(); 505 return scoped_ptr<ParseNode>();
506 return condition.PassAs<ParseNode>(); 506 return condition.Pass();
507 } 507 }
508 508
509 void Parser::TraverseOrder(const ParseNode* root, 509 void Parser::TraverseOrder(const ParseNode* root,
510 std::vector<const ParseNode*>* pre, 510 std::vector<const ParseNode*>* pre,
511 std::vector<const ParseNode*>* post) { 511 std::vector<const ParseNode*>* post) {
512 if (root) { 512 if (root) {
513 pre->push_back(root); 513 pre->push_back(root);
514 514
515 if (const AccessorNode* accessor = root->AsAccessor()) { 515 if (const AccessorNode* accessor = root->AsAccessor()) {
516 TraverseOrder(accessor->index(), pre, post); 516 TraverseOrder(accessor->index(), pre, post);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 break; 610 break;
611 } 611 }
612 } 612 }
613 613
614 // Suffix comments were assigned in reverse, so if there were multiple on 614 // Suffix comments were assigned in reverse, so if there were multiple on
615 // the same node, they need to be reversed. 615 // the same node, they need to be reversed.
616 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) 616 if ((*i)->comments() && !(*i)->comments()->suffix().empty())
617 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); 617 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix();
618 } 618 }
619 } 619 }
OLDNEW
« no previous file with comments | « tools/gn/operators_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698