| 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 |