| 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") |
| 320 const_cast<ListNode*>(list)->SortAsStringsList(); |
| 321 } |
| 322 } |
| 323 |
| 324 |
| 308 bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a, | 325 bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a, |
| 309 const ParseNode* b) { | 326 const ParseNode* b) { |
| 310 LocationRange a_range = a->GetRange(); | 327 LocationRange a_range = a->GetRange(); |
| 311 LocationRange b_range = b->GetRange(); | 328 LocationRange b_range = b->GetRange(); |
| 312 // If they're already separated by 1 or more lines, then we want to keep a | 329 // If they're already separated by 1 or more lines, then we want to keep a |
| 313 // blank line. | 330 // blank line. |
| 314 return b_range.begin().line_number() > a_range.end().line_number() + 1; | 331 return (b_range.begin().line_number() > a_range.end().line_number() + 1) || |
| 332 // Always put a blank line before a block comment. |
| 333 b->AsBlockComment(); |
| 315 } | 334 } |
| 316 | 335 |
| 317 int Printer::CurrentColumn() const { | 336 int Printer::CurrentColumn() const { |
| 318 int n = 0; | 337 int n = 0; |
| 319 while (n < static_cast<int>(output_.size()) && | 338 while (n < static_cast<int>(output_.size()) && |
| 320 output_[output_.size() - 1 - n] != '\n') { | 339 output_[output_.size() - 1 - n] != '\n') { |
| 321 ++n; | 340 ++n; |
| 322 } | 341 } |
| 323 return n; | 342 return n; |
| 324 } | 343 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 Expr(accessor->member(), kPrecedenceLowest, std::string()); | 453 Expr(accessor->member(), kPrecedenceLowest, std::string()); |
| 435 } else { | 454 } else { |
| 436 CHECK(accessor->index()); | 455 CHECK(accessor->index()); |
| 437 Print("["); | 456 Print("["); |
| 438 Expr(accessor->index(), kPrecedenceLowest, "]"); | 457 Expr(accessor->index(), kPrecedenceLowest, "]"); |
| 439 } | 458 } |
| 440 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { | 459 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { |
| 441 CHECK(precedence_.find(binop->op().value()) != precedence_.end()); | 460 CHECK(precedence_.find(binop->op().value()) != precedence_.end()); |
| 442 AnnotatePreferredMultilineAssignment(binop); | 461 AnnotatePreferredMultilineAssignment(binop); |
| 443 | 462 |
| 463 SortIfSources(binop); |
| 464 |
| 444 Precedence prec = precedence_[binop->op().value()]; | 465 Precedence prec = precedence_[binop->op().value()]; |
| 445 | 466 |
| 446 // Since binary operators format left-to-right, it is ok for the left side | 467 // 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 | 468 // 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 + | 469 // 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 | 470 // (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. | 471 // the right expression as appearing one precedence level higher. |
| 451 // However, because the source parens are not in the parse tree, as a | 472 // 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- | 473 // special case for && and || we insert strictly-redundant-but-helpful-for- |
| 453 // human-readers parentheses. | 474 // 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() && | 662 if (i != 0 && x->comments() && !x->comments()->before().empty() && |
| 642 !HaveBlankLine()) { | 663 !HaveBlankLine()) { |
| 643 Newline(); | 664 Newline(); |
| 644 } | 665 } |
| 645 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; | 666 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; |
| 646 bool want_comma = | 667 bool want_comma = |
| 647 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); | 668 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); |
| 648 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); | 669 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); |
| 649 CHECK(!x->comments() || x->comments()->after().empty()); | 670 CHECK(!x->comments() || x->comments()->after().empty()); |
| 650 if (body_of_list) { | 671 if (body_of_list) { |
| 651 if (!want_comma) { | 672 if (i < list.size() - 1 && |
| 652 if (i < list.size() - 1 && | 673 ShouldAddBlankLineInBetween(list[i], list[i + 1])) |
| 653 ShouldAddBlankLineInBetween(list[i], list[i + 1])) | 674 Newline(); |
| 654 Newline(); | |
| 655 } | |
| 656 } | 675 } |
| 657 ++i; | 676 ++i; |
| 658 } | 677 } |
| 659 | 678 |
| 660 // Trailing comments. | 679 // Trailing comments. |
| 661 if (end->comments() && !end->comments()->before().empty()) { | 680 if (end->comments() && !end->comments()->before().empty()) { |
| 662 if (list.size() >= 2) | 681 if (list.size() >= 2) |
| 663 Newline(); | 682 Newline(); |
| 664 for (const auto& c : end->comments()->before()) { | 683 for (const auto& c : end->comments()->before()) { |
| 665 Newline(); | 684 Newline(); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 } | 1040 } |
| 1022 } else { | 1041 } else { |
| 1023 printf("%s", output_string.c_str()); | 1042 printf("%s", output_string.c_str()); |
| 1024 } | 1043 } |
| 1025 } | 1044 } |
| 1026 | 1045 |
| 1027 return 0; | 1046 return 0; |
| 1028 } | 1047 } |
| 1029 | 1048 |
| 1030 } // namespace commands | 1049 } // namespace commands |
| OLD | NEW |