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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 int AssessPenalty(const std::string& output); | 174 int AssessPenalty(const std::string& output); |
175 | 175 |
176 // Tests if any lines exceed the maximum width. | 176 // Tests if any lines exceed the maximum width. |
177 bool ExceedsMaximumWidth(const std::string& output); | 177 bool ExceedsMaximumWidth(const std::string& output); |
178 | 178 |
179 // Format a list of values using the given style. | 179 // Format a list of values using the given style. |
180 // |end| holds any trailing comments to be printed just before the closing | 180 // |end| holds any trailing comments to be printed just before the closing |
181 // bracket. | 181 // bracket. |
182 template <class PARSENODE> // Just for const covariance. | 182 template <class PARSENODE> // Just for const covariance. |
183 void Sequence(SequenceStyle style, | 183 void Sequence(SequenceStyle style, |
184 const std::vector<PARSENODE*>& list, | 184 const std::vector<std::unique_ptr<PARSENODE>>& list, |
185 const ParseNode* end, | 185 const ParseNode* end, |
186 bool force_multiline); | 186 bool force_multiline); |
187 | 187 |
188 // Returns the penalty. | 188 // Returns the penalty. |
189 int FunctionCall(const FunctionCallNode* func_call, | 189 int FunctionCall(const FunctionCallNode* func_call, |
190 const std::string& suffix); | 190 const std::string& suffix); |
191 | 191 |
192 // Create a clone of this Printer in a similar state (other than the output, | 192 // Create a clone of this Printer in a similar state (other than the output, |
193 // but including margins, etc.) to be used for dry run measurements. | 193 // but including margins, etc.) to be used for dry run measurements. |
194 void InitializeSub(Printer* sub); | 194 void InitializeSub(Printer* sub); |
195 | 195 |
196 template <class PARSENODE> | 196 template <class PARSENODE> |
197 bool ListWillBeMultiline(const std::vector<PARSENODE*>& list, | 197 bool ListWillBeMultiline(const std::vector<std::unique_ptr<PARSENODE>>& list, |
198 const ParseNode* end); | 198 const ParseNode* end); |
199 | 199 |
200 std::string output_; // Output buffer. | 200 std::string output_; // Output buffer. |
201 std::vector<Token> comments_; // Pending end-of-line comments. | 201 std::vector<Token> comments_; // Pending end-of-line comments. |
202 int margin() const { return stack_.back().margin; } | 202 int margin() const { return stack_.back().margin; } |
203 | 203 |
204 int penalty_depth_; | 204 int penalty_depth_; |
205 int GetPenaltyForLineBreak() const { | 205 int GetPenaltyForLineBreak() const { |
206 return penalty_depth_ * kPenaltyLineBreak; | 206 return penalty_depth_ * kPenaltyLineBreak; |
207 } | 207 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 | 378 |
379 if (block->comments()) { | 379 if (block->comments()) { |
380 for (const auto& c : block->comments()->before()) { | 380 for (const auto& c : block->comments()->before()) { |
381 TrimAndPrintToken(c); | 381 TrimAndPrintToken(c); |
382 Newline(); | 382 Newline(); |
383 } | 383 } |
384 } | 384 } |
385 | 385 |
386 size_t i = 0; | 386 size_t i = 0; |
387 for (const auto& stmt : block->statements()) { | 387 for (const auto& stmt : block->statements()) { |
388 Expr(stmt, kPrecedenceLowest, std::string()); | 388 Expr(stmt.get(), kPrecedenceLowest, std::string()); |
389 Newline(); | 389 Newline(); |
390 if (stmt->comments()) { | 390 if (stmt->comments()) { |
391 // Why are before() not printed here too? before() are handled inside | 391 // Why are before() not printed here too? before() are handled inside |
392 // Expr(), as are suffix() which are queued to the next Newline(). | 392 // Expr(), as are suffix() which are queued to the next Newline(). |
393 // However, because it's a general expression handler, it doesn't insert | 393 // However, because it's a general expression handler, it doesn't insert |
394 // the newline itself, which only happens between block statements. So, | 394 // the newline itself, which only happens between block statements. So, |
395 // the after are handled explicitly here. | 395 // the after are handled explicitly here. |
396 for (const auto& c : stmt->comments()->after()) { | 396 for (const auto& c : stmt->comments()->after()) { |
397 TrimAndPrintToken(c); | 397 TrimAndPrintToken(c); |
398 Newline(); | 398 Newline(); |
399 } | 399 } |
400 } | 400 } |
401 if (i < block->statements().size() - 1 && | 401 if (i < block->statements().size() - 1 && |
402 (ShouldAddBlankLineInBetween(block->statements()[i], | 402 (ShouldAddBlankLineInBetween(block->statements()[i].get(), |
403 block->statements()[i + 1]))) { | 403 block->statements()[i + 1].get()))) { |
404 Newline(); | 404 Newline(); |
405 } | 405 } |
406 ++i; | 406 ++i; |
407 } | 407 } |
408 | 408 |
409 if (block->comments()) { | 409 if (block->comments()) { |
410 for (const auto& c : block->comments()->after()) { | 410 for (const auto& c : block->comments()->after()) { |
411 TrimAndPrintToken(c); | 411 TrimAndPrintToken(c); |
412 Newline(); | 412 Newline(); |
413 } | 413 } |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 } | 641 } |
642 | 642 |
643 Print(at_end); | 643 Print(at_end); |
644 | 644 |
645 penalty_depth_--; | 645 penalty_depth_--; |
646 return penalty; | 646 return penalty; |
647 } | 647 } |
648 | 648 |
649 template <class PARSENODE> | 649 template <class PARSENODE> |
650 void Printer::Sequence(SequenceStyle style, | 650 void Printer::Sequence(SequenceStyle style, |
651 const std::vector<PARSENODE*>& list, | 651 const std::vector<std::unique_ptr<PARSENODE>>& list, |
652 const ParseNode* end, | 652 const ParseNode* end, |
653 bool force_multiline) { | 653 bool force_multiline) { |
654 if (style == kSequenceStyleList) | 654 if (style == kSequenceStyleList) |
655 Print("["); | 655 Print("["); |
656 else if (style == kSequenceStyleBracedBlock) | 656 else if (style == kSequenceStyleBracedBlock) |
657 Print("{"); | 657 Print("{"); |
658 | 658 |
659 if (style == kSequenceStyleBlock || style == kSequenceStyleBracedBlock) | 659 if (style == kSequenceStyleBlock || style == kSequenceStyleBracedBlock) |
660 force_multiline = true; | 660 force_multiline = true; |
661 | 661 |
662 force_multiline |= ListWillBeMultiline(list, end); | 662 force_multiline |= ListWillBeMultiline(list, end); |
663 | 663 |
664 if (list.size() == 0 && !force_multiline) { | 664 if (list.size() == 0 && !force_multiline) { |
665 // No elements, and not forcing newlines, print nothing. | 665 // No elements, and not forcing newlines, print nothing. |
666 } else if (list.size() == 1 && !force_multiline) { | 666 } else if (list.size() == 1 && !force_multiline) { |
667 Print(" "); | 667 Print(" "); |
668 Expr(list[0], kPrecedenceLowest, std::string()); | 668 Expr(list[0].get(), kPrecedenceLowest, std::string()); |
669 CHECK(!list[0]->comments() || list[0]->comments()->after().empty()); | 669 CHECK(!list[0]->comments() || list[0]->comments()->after().empty()); |
670 Print(" "); | 670 Print(" "); |
671 } else { | 671 } else { |
672 stack_.push_back(IndentState(margin() + kIndentSize, | 672 stack_.push_back(IndentState(margin() + kIndentSize, |
673 style == kSequenceStyleList, | 673 style == kSequenceStyleList, |
674 false)); | 674 false)); |
675 size_t i = 0; | 675 size_t i = 0; |
676 for (const auto& x : list) { | 676 for (const auto& x : list) { |
677 Newline(); | 677 Newline(); |
678 // If: | 678 // If: |
679 // - we're going to output some comments, and; | 679 // - we're going to output some comments, and; |
680 // - we haven't just started this multiline list, and; | 680 // - we haven't just started this multiline list, and; |
681 // - there isn't already a blank line here; | 681 // - there isn't already a blank line here; |
682 // Then: insert one. | 682 // Then: insert one. |
683 if (i != 0 && x->comments() && !x->comments()->before().empty() && | 683 if (i != 0 && x->comments() && !x->comments()->before().empty() && |
684 !HaveBlankLine()) { | 684 !HaveBlankLine()) { |
685 Newline(); | 685 Newline(); |
686 } | 686 } |
687 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; | 687 bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList; |
688 bool want_comma = | 688 bool want_comma = |
689 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); | 689 body_of_list && (style == kSequenceStyleList && !x->AsBlockComment()); |
690 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); | 690 Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string()); |
691 CHECK(!x->comments() || x->comments()->after().empty()); | 691 CHECK(!x->comments() || x->comments()->after().empty()); |
692 if (body_of_list) { | 692 if (body_of_list) { |
693 if (i < list.size() - 1 && | 693 if (i < list.size() - 1 && |
694 ShouldAddBlankLineInBetween(list[i], list[i + 1])) | 694 ShouldAddBlankLineInBetween(list[i].get(), list[i + 1].get())) |
695 Newline(); | 695 Newline(); |
696 } | 696 } |
697 ++i; | 697 ++i; |
698 } | 698 } |
699 | 699 |
700 // Trailing comments. | 700 // Trailing comments. |
701 if (end->comments() && !end->comments()->before().empty()) { | 701 if (end->comments() && !end->comments()->before().empty()) { |
702 if (list.size() >= 2) | 702 if (list.size() >= 2) |
703 Newline(); | 703 Newline(); |
704 for (const auto& c : end->comments()->before()) { | 704 for (const auto& c : end->comments()->before()) { |
(...skipping 22 matching lines...) Expand all Loading... |
727 int Printer::FunctionCall(const FunctionCallNode* func_call, | 727 int Printer::FunctionCall(const FunctionCallNode* func_call, |
728 const std::string& suffix) { | 728 const std::string& suffix) { |
729 int start_line = CurrentLine(); | 729 int start_line = CurrentLine(); |
730 int start_column = CurrentColumn(); | 730 int start_column = CurrentColumn(); |
731 Print(func_call->function().value()); | 731 Print(func_call->function().value()); |
732 Print("("); | 732 Print("("); |
733 | 733 |
734 bool have_block = func_call->block() != nullptr; | 734 bool have_block = func_call->block() != nullptr; |
735 bool force_multiline = false; | 735 bool force_multiline = false; |
736 | 736 |
737 const std::vector<const ParseNode*>& list = func_call->args()->contents(); | 737 const auto& list = func_call->args()->contents(); |
738 const ParseNode* end = func_call->args()->End(); | 738 const ParseNode* end = func_call->args()->End(); |
739 | 739 |
740 if (end && end->comments() && !end->comments()->before().empty()) | 740 if (end && end->comments() && !end->comments()->before().empty()) |
741 force_multiline = true; | 741 force_multiline = true; |
742 | 742 |
743 // If there's before line comments, make sure we have a place to put them. | 743 // If there's before line comments, make sure we have a place to put them. |
744 for (const auto& i : list) { | 744 for (const auto& i : list) { |
745 if (i->comments() && !i->comments()->before().empty()) | 745 if (i->comments() && !i->comments()->before().empty()) |
746 force_multiline = true; | 746 force_multiline = true; |
747 } | 747 } |
(...skipping 12 matching lines...) Expand all Loading... |
760 bool continuation_requires_indent = | 760 bool continuation_requires_indent = |
761 list.size() != 1 || !list[0]->AsBinaryOp(); | 761 list.size() != 1 || !list[0]->AsBinaryOp(); |
762 | 762 |
763 // 1: Same line. | 763 // 1: Same line. |
764 Printer sub1; | 764 Printer sub1; |
765 InitializeSub(&sub1); | 765 InitializeSub(&sub1); |
766 sub1.stack_.push_back( | 766 sub1.stack_.push_back( |
767 IndentState(CurrentColumn(), continuation_requires_indent, false)); | 767 IndentState(CurrentColumn(), continuation_requires_indent, false)); |
768 int penalty_one_line = 0; | 768 int penalty_one_line = 0; |
769 for (size_t i = 0; i < list.size(); ++i) { | 769 for (size_t i = 0; i < list.size(); ++i) { |
770 penalty_one_line += sub1.Expr(list[i], kPrecedenceLowest, | 770 penalty_one_line += sub1.Expr(list[i].get(), kPrecedenceLowest, |
771 i < list.size() - 1 ? ", " : std::string()); | 771 i < list.size() - 1 ? ", " : std::string()); |
772 } | 772 } |
773 sub1.Print(terminator); | 773 sub1.Print(terminator); |
774 penalty_one_line += AssessPenalty(sub1.String()); | 774 penalty_one_line += AssessPenalty(sub1.String()); |
775 // This extra penalty prevents a short second argument from being squeezed in | 775 // This extra penalty prevents a short second argument from being squeezed in |
776 // after a first argument that went multiline (and instead preferring a | 776 // after a first argument that went multiline (and instead preferring a |
777 // variant below). | 777 // variant below). |
778 penalty_one_line += | 778 penalty_one_line += |
779 (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner; | 779 (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner; |
780 | 780 |
781 // 2: Starting on same line, broken at commas. | 781 // 2: Starting on same line, broken at commas. |
782 Printer sub2; | 782 Printer sub2; |
783 InitializeSub(&sub2); | 783 InitializeSub(&sub2); |
784 sub2.stack_.push_back( | 784 sub2.stack_.push_back( |
785 IndentState(CurrentColumn(), continuation_requires_indent, false)); | 785 IndentState(CurrentColumn(), continuation_requires_indent, false)); |
786 int penalty_multiline_start_same_line = 0; | 786 int penalty_multiline_start_same_line = 0; |
787 for (size_t i = 0; i < list.size(); ++i) { | 787 for (size_t i = 0; i < list.size(); ++i) { |
788 penalty_multiline_start_same_line += sub2.Expr( | 788 penalty_multiline_start_same_line += |
789 list[i], kPrecedenceLowest, i < list.size() - 1 ? "," : std::string()); | 789 sub2.Expr(list[i].get(), kPrecedenceLowest, |
| 790 i < list.size() - 1 ? "," : std::string()); |
790 if (i < list.size() - 1) { | 791 if (i < list.size() - 1) { |
791 sub2.Newline(); | 792 sub2.Newline(); |
792 } | 793 } |
793 } | 794 } |
794 sub2.Print(terminator); | 795 sub2.Print(terminator); |
795 penalty_multiline_start_same_line += AssessPenalty(sub2.String()); | 796 penalty_multiline_start_same_line += AssessPenalty(sub2.String()); |
796 | 797 |
797 // 3: Starting on next line, broken at commas. | 798 // 3: Starting on next line, broken at commas. |
798 Printer sub3; | 799 Printer sub3; |
799 InitializeSub(&sub3); | 800 InitializeSub(&sub3); |
800 sub3.stack_.push_back(IndentState(margin() + kIndentSize * 2, | 801 sub3.stack_.push_back(IndentState(margin() + kIndentSize * 2, |
801 continuation_requires_indent, false)); | 802 continuation_requires_indent, false)); |
802 sub3.Newline(); | 803 sub3.Newline(); |
803 int penalty_multiline_start_next_line = 0; | 804 int penalty_multiline_start_next_line = 0; |
804 for (size_t i = 0; i < list.size(); ++i) { | 805 for (size_t i = 0; i < list.size(); ++i) { |
805 if (i == 0) { | 806 if (i == 0) { |
806 penalty_multiline_start_next_line += | 807 penalty_multiline_start_next_line += |
807 std::abs(sub3.CurrentColumn() - start_column) * | 808 std::abs(sub3.CurrentColumn() - start_column) * |
808 kPenaltyHorizontalSeparation; | 809 kPenaltyHorizontalSeparation; |
809 } | 810 } |
810 penalty_multiline_start_next_line += sub3.Expr( | 811 penalty_multiline_start_next_line += |
811 list[i], kPrecedenceLowest, i < list.size() - 1 ? "," : std::string()); | 812 sub3.Expr(list[i].get(), kPrecedenceLowest, |
| 813 i < list.size() - 1 ? "," : std::string()); |
812 if (i < list.size() - 1) { | 814 if (i < list.size() - 1) { |
813 sub3.Newline(); | 815 sub3.Newline(); |
814 } | 816 } |
815 } | 817 } |
816 sub3.Print(terminator); | 818 sub3.Print(terminator); |
817 penalty_multiline_start_next_line += AssessPenalty(sub3.String()); | 819 penalty_multiline_start_next_line += AssessPenalty(sub3.String()); |
818 | 820 |
819 int penalty = penalty_multiline_start_next_line; | 821 int penalty = penalty_multiline_start_next_line; |
820 bool fits_on_current_line = false; | 822 bool fits_on_current_line = false; |
821 if (penalty_one_line < penalty_multiline_start_next_line || | 823 if (penalty_one_line < penalty_multiline_start_next_line || |
(...skipping 23 matching lines...) Expand all Loading... |
845 | 847 |
846 for (size_t i = 0; i < list.size(); ++i) { | 848 for (size_t i = 0; i < list.size(); ++i) { |
847 const auto& x = list[i]; | 849 const auto& x = list[i]; |
848 if (i > 0) { | 850 if (i > 0) { |
849 if (fits_on_current_line && !force_multiline) | 851 if (fits_on_current_line && !force_multiline) |
850 Print(" "); | 852 Print(" "); |
851 else | 853 else |
852 Newline(); | 854 Newline(); |
853 } | 855 } |
854 bool want_comma = i < list.size() - 1 && !x->AsBlockComment(); | 856 bool want_comma = i < list.size() - 1 && !x->AsBlockComment(); |
855 Expr(x, kPrecedenceLowest, want_comma ? "," : std::string()); | 857 Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string()); |
856 CHECK(!x->comments() || x->comments()->after().empty()); | 858 CHECK(!x->comments() || x->comments()->after().empty()); |
857 if (i < list.size() - 1) { | 859 if (i < list.size() - 1) { |
858 if (!want_comma) | 860 if (!want_comma) |
859 Newline(); | 861 Newline(); |
860 } | 862 } |
861 } | 863 } |
862 | 864 |
863 // Trailing comments. | 865 // Trailing comments. |
864 if (end->comments() && !end->comments()->before().empty()) { | 866 if (end->comments() && !end->comments()->before().empty()) { |
865 if (!list.empty()) | 867 if (!list.empty()) |
(...skipping 27 matching lines...) Expand all Loading... |
893 } | 895 } |
894 | 896 |
895 void Printer::InitializeSub(Printer* sub) { | 897 void Printer::InitializeSub(Printer* sub) { |
896 sub->stack_ = stack_; | 898 sub->stack_ = stack_; |
897 sub->comments_ = comments_; | 899 sub->comments_ = comments_; |
898 sub->penalty_depth_ = penalty_depth_; | 900 sub->penalty_depth_ = penalty_depth_; |
899 sub->Print(std::string(CurrentColumn(), 'x')); | 901 sub->Print(std::string(CurrentColumn(), 'x')); |
900 } | 902 } |
901 | 903 |
902 template <class PARSENODE> | 904 template <class PARSENODE> |
903 bool Printer::ListWillBeMultiline(const std::vector<PARSENODE*>& list, | 905 bool Printer::ListWillBeMultiline( |
904 const ParseNode* end) { | 906 const std::vector<std::unique_ptr<PARSENODE>>& list, |
| 907 const ParseNode* end) { |
905 if (list.size() > 1) | 908 if (list.size() > 1) |
906 return true; | 909 return true; |
907 | 910 |
908 if (end && end->comments() && !end->comments()->before().empty()) | 911 if (end && end->comments() && !end->comments()->before().empty()) |
909 return true; | 912 return true; |
910 | 913 |
911 // If there's before line comments, make sure we have a place to put them. | 914 // If there's before line comments, make sure we have a place to put them. |
912 for (const auto& i : list) { | 915 for (const auto& i : list) { |
913 if (i->comments() && !i->comments()->before().empty()) | 916 if (i->comments() && !i->comments()->before().empty()) |
914 return true; | 917 return true; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 } | 1071 } |
1069 } else { | 1072 } else { |
1070 printf("%s", output_string.c_str()); | 1073 printf("%s", output_string.c_str()); |
1071 } | 1074 } |
1072 } | 1075 } |
1073 | 1076 |
1074 return 0; | 1077 return 0; |
1075 } | 1078 } |
1076 | 1079 |
1077 } // namespace commands | 1080 } // namespace commands |
OLD | NEW |