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 |