 Chromium Code Reviews
 Chromium Code Reviews Issue 962003002:
  gn format: Have format sort sources  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 962003002:
  gn format: Have format sort sources  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <sstream> | 5 #include <sstream> | 
| 6 | 6 | 
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" | 
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" | 
| 9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" | 
| 10 #include "tools/gn/commands.h" | 10 #include "tools/gn/commands.h" | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 | 122 | 
| 123 // Remove trailing spaces from the current line. | 123 // Remove trailing spaces from the current line. | 
| 124 void Trim(); | 124 void Trim(); | 
| 125 | 125 | 
| 126 // Whether there's a blank separator line at the current position. | 126 // Whether there's a blank separator line at the current position. | 
| 127 bool HaveBlankLine(); | 127 bool HaveBlankLine(); | 
| 128 | 128 | 
| 129 // Flag assignments to sources, deps, etc. to make their RHSs multiline. | 129 // Flag assignments to sources, deps, etc. to make their RHSs multiline. | 
| 130 void AnnotatePreferredMultilineAssignment(const BinaryOpNode* binop); | 130 void AnnotatePreferredMultilineAssignment(const BinaryOpNode* binop); | 
| 131 | 131 | 
| 132 // Alphabetically a list on the RHS if the LHS is 'sources'. | |
| 133 void SortIfSources(const BinaryOpNode* binop); | |
| 134 | |
| 132 // Heuristics to decide if there should be a blank line added between two | 135 // Heuristics to decide if there should be a blank line added between two | 
| 133 // items. For various "small" items, it doesn't look nice if there's too much | 136 // items. For various "small" items, it doesn't look nice if there's too much | 
| 134 // vertical whitespace added. | 137 // vertical whitespace added. | 
| 135 bool ShouldAddBlankLineInBetween(const ParseNode* a, const ParseNode* b); | 138 bool ShouldAddBlankLineInBetween(const ParseNode* a, const ParseNode* b); | 
| 136 | 139 | 
| 137 // Get the 0-based x position on the current line. | 140 // Get the 0-based x position on the current line. | 
| 138 int CurrentColumn() const; | 141 int CurrentColumn() const; | 
| 139 | 142 | 
| 140 // Get the current line in the output; | 143 // Get the current line in the output; | 
| 141 int CurrentLine() const; | 144 int CurrentLine() const; | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 if (binop->op().value() == "=" && ident && list) { | 301 if (binop->op().value() == "=" && ident && list) { | 
| 299 const base::StringPiece lhs = ident->value().value(); | 302 const base::StringPiece lhs = ident->value().value(); | 
| 300 if (lhs == "data" || lhs == "datadeps" || lhs == "deps" || | 303 if (lhs == "data" || lhs == "datadeps" || lhs == "deps" || | 
| 301 lhs == "inputs" || lhs == "outputs" || lhs == "public" || | 304 lhs == "inputs" || lhs == "outputs" || lhs == "public" || | 
| 302 lhs == "public_deps" || lhs == "sources") { | 305 lhs == "public_deps" || lhs == "sources") { | 
| 303 const_cast<ListNode*>(list)->set_prefer_multiline(true); | 306 const_cast<ListNode*>(list)->set_prefer_multiline(true); | 
| 304 } | 307 } | 
| 305 } | 308 } | 
| 306 } | 309 } | 
| 307 | 310 | 
| 311 void Printer::SortIfSources(const BinaryOpNode* binop) { | |
| 312 const IdentifierNode* ident = binop->left()->AsIdentifier(); | |
| 313 const ListNode* list = binop->right()->AsList(); | |
| 314 // TODO(scottmg): Sort more than 'sources'? | |
| 315 if ((binop->op().value() == "=" || binop->op().value() == "+=" || | |
| 316 binop->op().value() == "-=") && | |
| 317 ident && list) { | |
| 318 const base::StringPiece lhs = ident->value().value(); | |
| 319 if (lhs == "sources") { | |
| 
brettw
2015/02/27 22:27:26
No {} to match style
 
scottmg
2015/02/27 23:17:44
Done.
 | |
| 320 const_cast<ListNode*>(list)->SortAsStringsList(); | |
| 321 } | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 | |
| 308 bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a, | 326 bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a, | 
| 309 const ParseNode* b) { | 327 const ParseNode* b) { | 
| 310 LocationRange a_range = a->GetRange(); | 328 LocationRange a_range = a->GetRange(); | 
| 311 LocationRange b_range = b->GetRange(); | 329 LocationRange b_range = b->GetRange(); | 
| 312 // If they're already separated by 1 or more lines, then we want to keep a | 330 // If they're already separated by 1 or more lines, then we want to keep a | 
| 313 // blank line. | 331 // blank line. | 
| 314 return b_range.begin().line_number() > a_range.end().line_number() + 1; | 332 return (b_range.begin().line_number() > a_range.end().line_number() + 1) || | 
| 333 // Always put a blank line before a block comment. | |
| 334 b->AsBlockComment(); | |
| 315 } | 335 } | 
| 316 | 336 | 
| 317 int Printer::CurrentColumn() const { | 337 int Printer::CurrentColumn() const { | 
| 318 int n = 0; | 338 int n = 0; | 
| 319 while (n < static_cast<int>(output_.size()) && | 339 while (n < static_cast<int>(output_.size()) && | 
| 320 output_[output_.size() - 1 - n] != '\n') { | 340 output_[output_.size() - 1 - n] != '\n') { | 
| 321 ++n; | 341 ++n; | 
| 322 } | 342 } | 
| 323 return n; | 343 return n; | 
| 324 } | 344 } | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 Expr(accessor->member(), kPrecedenceLowest, std::string()); | 454 Expr(accessor->member(), kPrecedenceLowest, std::string()); | 
| 435 } else { | 455 } else { | 
| 436 CHECK(accessor->index()); | 456 CHECK(accessor->index()); | 
| 437 Print("["); | 457 Print("["); | 
| 438 Expr(accessor->index(), kPrecedenceLowest, "]"); | 458 Expr(accessor->index(), kPrecedenceLowest, "]"); | 
| 439 } | 459 } | 
| 440 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { | 460 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { | 
| 441 CHECK(precedence_.find(binop->op().value()) != precedence_.end()); | 461 CHECK(precedence_.find(binop->op().value()) != precedence_.end()); | 
| 442 AnnotatePreferredMultilineAssignment(binop); | 462 AnnotatePreferredMultilineAssignment(binop); | 
| 443 | 463 | 
| 464 SortIfSources(binop); | |
| 465 | |
| 444 Precedence prec = precedence_[binop->op().value()]; | 466 Precedence prec = precedence_[binop->op().value()]; | 
| 445 | 467 | 
| 446 // Since binary operators format left-to-right, it is ok for the left side | 468 // Since binary operators format left-to-right, it is ok for the left side | 
| 447 // use the same operator without parentheses, so the left uses prec. For the | 469 // use the same operator without parentheses, so the left uses prec. For the | 
| 448 // same reason, the right side cannot reuse the same operator, or else "x + | 470 // same reason, the right side cannot reuse the same operator, or else "x + | 
| 449 // (y + z)" would format as "x + y + z" which means "(x + y) + z". So, treat | 471 // (y + z)" would format as "x + y + z" which means "(x + y) + z". So, treat | 
| 450 // the right expression as appearing one precedence level higher. | 472 // the right expression as appearing one precedence level higher. | 
| 451 // However, because the source parens are not in the parse tree, as a | 473 // However, because the source parens are not in the parse tree, as a | 
| 452 // special case for && and || we insert strictly-redundant-but-helpful-for- | 474 // special case for && and || we insert strictly-redundant-but-helpful-for- | 
| 453 // human-readers parentheses. | 475 // human-readers parentheses. | 
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 if (i != 0 && x->comments() && !x->comments()->before().empty() && | 663 if (i != 0 && x->comments() && !x->comments()->before().empty() && | 
| 642 !HaveBlankLine()) { | 664 !HaveBlankLine()) { | 
| 643 Newline(); | 665 Newline(); | 
| 644 } | 666 } | 
| 645 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; | 667 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; | 
| 646 bool want_comma = | 668 bool want_comma = | 
| 647 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); | 669 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); | 
| 648 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); | 670 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); | 
| 649 CHECK(!x->comments() || x->comments()->after().empty()); | 671 CHECK(!x->comments() || x->comments()->after().empty()); | 
| 650 if (body_of_list) { | 672 if (body_of_list) { | 
| 651 if (!want_comma) { | 673 if (i < list.size() - 1 && | 
| 652 if (i < list.size() - 1 && | 674 ShouldAddBlankLineInBetween(list[i], list[i + 1])) | 
| 653 ShouldAddBlankLineInBetween(list[i], list[i + 1])) | 675 Newline(); | 
| 654 Newline(); | |
| 655 } | |
| 656 } | 676 } | 
| 657 ++i; | 677 ++i; | 
| 658 } | 678 } | 
| 659 | 679 | 
| 660 // Trailing comments. | 680 // Trailing comments. | 
| 661 if (end->comments() && !end->comments()->before().empty()) { | 681 if (end->comments() && !end->comments()->before().empty()) { | 
| 662 if (list.size() >= 2) | 682 if (list.size() >= 2) | 
| 663 Newline(); | 683 Newline(); | 
| 664 for (const auto& c : end->comments()->before()) { | 684 for (const auto& c : end->comments()->before()) { | 
| 665 Newline(); | 685 Newline(); | 
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1021 } | 1041 } | 
| 1022 } else { | 1042 } else { | 
| 1023 printf("%s", output_string.c_str()); | 1043 printf("%s", output_string.c_str()); | 
| 1024 } | 1044 } | 
| 1025 } | 1045 } | 
| 1026 | 1046 | 
| 1027 return 0; | 1047 return 0; | 
| 1028 } | 1048 } | 
| 1029 | 1049 | 
| 1030 } // namespace commands | 1050 } // namespace commands | 
| OLD | NEW |