Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1532)

Unified Diff: tools/gn/command_format.cc

Issue 756413002: gn format: Fix and enable a few more tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gn-wrap-fix
Patch Set: x64 Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/gn/command_format_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/command_format.cc
diff --git a/tools/gn/command_format.cc b/tools/gn/command_format.cc
index 593c150139016949dbe4722d17d7ebde6fb92985..f30984a14503cfef553c57623afa2f339d1879e2 100644
--- a/tools/gn/command_format.cc
+++ b/tools/gn/command_format.cc
@@ -59,7 +59,7 @@ const int kMaximumWidth = 80;
const int kPenaltyLineBreak = 500;
const int kPenaltyHorizontalSeparation = 100;
const int kPenaltyExcess = 10000;
-const int kPenaltyBrokenLineOnOneLiner = 1000;
+const int kPenaltyBrokenLineOnOneLiner = 5000;
enum Precedence {
kPrecedenceLowest,
@@ -72,6 +72,12 @@ enum Precedence {
kPrecedenceUnary,
};
+int CountLines(const std::string& str) {
+ std::vector<std::string> lines;
+ base::SplitStringDontTrim(str, '\n', &lines);
+ return static_cast<int>(lines.size());
+}
+
class Printer {
public:
Printer();
@@ -151,12 +157,17 @@ class Printer {
bool force_multiline);
// Returns the penalty.
- int FunctionCall(const FunctionCallNode* func_call);
+ int FunctionCall(const FunctionCallNode* func_call,
+ const std::string& suffix);
// Create a clone of this Printer in a similar state (other than the output,
// but including margins, etc.) to be used for dry run measurements.
void InitializeSub(Printer* sub);
+ template <class PARSENODE>
+ bool ListWillBeMultiline(const std::vector<PARSENODE*>& list,
+ const ParseNode* end);
+
std::string output_; // Output buffer.
std::vector<Token> comments_; // Pending end-of-line comments.
int margin() const { return stack_.back().margin; }
@@ -367,6 +378,7 @@ void Printer::AddParen(int prec, int outer_prec, bool* parenthesized) {
int Printer::Expr(const ParseNode* root,
int outer_prec,
const std::string& suffix) {
+ std::string at_end = suffix;
int penalty = 0;
penalty_depth_++;
@@ -405,32 +417,55 @@ int Printer::Expr(const ParseNode* root,
AddParen(prec, outer_prec, &parenthesized);
int start_line = CurrentLine();
int start_column = CurrentColumn();
+ bool is_assignment = binop->op().value() == "=" ||
+ binop->op().value() == "+=" ||
+ binop->op().value() == "-=";
+ // A sort of funny special case for the long lists that are common in .gn
+ // files, don't indent them + 4, even though they're just continuations when
+ // they're simple lists like "x = [ a, b, c, ... ]"
+ const ListNode* right_as_list = binop->right()->AsList();
int indent_column =
- (binop->op().value() == "=" || binop->op().value() == "+=" ||
- binop->op().value() == "-=")
+ (is_assignment &&
+ (!right_as_list || (!right_as_list->prefer_multiline() &&
+ !ListWillBeMultiline(right_as_list->contents(),
+ right_as_list->End()))))
? margin() + kIndentSize * 2
: start_column;
if (stack_.back().continuation_requires_indent)
indent_column += kIndentSize * 2;
- Expr(binop->left(),
- prec,
- std::string(" ") + binop->op().value().as_string());
+ stack_.push_back(IndentState(indent_column, false));
+ Printer sub_left;
+ InitializeSub(&sub_left);
+ sub_left.Expr(binop->left(),
+ prec,
+ std::string(" ") + binop->op().value().as_string());
+ bool left_is_multiline = CountLines(sub_left.String()) > 1;
+ // Avoid walking the whole left redundantly times (see timing of Format.046)
+ // so pull the output and comments from subprinter.
+ Print(sub_left.String().substr(start_column));
+ std::copy(sub_left.comments_.begin(),
+ sub_left.comments_.end(),
+ std::back_inserter(comments_));
// Single line.
Printer sub1;
InitializeSub(&sub1);
- sub1.stack_.push_back(IndentState(indent_column, false));
sub1.Print(" ");
int penalty_current_line =
sub1.Expr(binop->right(), prec + 1, std::string());
sub1.Print(suffix);
penalty_current_line += AssessPenalty(sub1.String());
+ if (!is_assignment && left_is_multiline) {
+ // In e.g. xxx + yyy, if xxx is already multiline, then we want a penalty
+ // for trying to continue as if this were one line.
+ penalty_current_line +=
+ (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;
+ }
// Break after operator.
Printer sub2;
InitializeSub(&sub2);
- sub2.stack_.push_back(IndentState(indent_column, false));
sub2.Newline();
int penalty_next_line = sub2.Expr(binop->right(), prec + 1, std::string());
sub2.Print(suffix);
@@ -441,13 +476,12 @@ int Printer::Expr(const ParseNode* root,
Expr(binop->right(), prec + 1, std::string());
} else {
// Otherwise, put first argument and op, and indent next.
- stack_.push_back(IndentState(indent_column, false));
Newline();
penalty += std::abs(CurrentColumn() - start_column) *
kPenaltyHorizontalSeparation;
Expr(binop->right(), prec + 1, std::string());
- stack_.pop_back();
}
+ stack_.pop_back();
penalty += (CurrentLine() - start_line) * GetPenaltyForLineBreak();
} else if (const BlockNode* block = root->AsBlock()) {
Sequence(
@@ -470,11 +504,13 @@ int Printer::Expr(const ParseNode* root,
} else {
Sequence(kSequenceStyleBracedBlock,
condition->if_false()->AsBlock()->statements(),
- condition->if_false()->AsBlock()->End(), false);
+ condition->if_false()->AsBlock()->End(),
+ false);
}
}
} else if (const FunctionCallNode* func_call = root->AsFunctionCall()) {
- penalty += FunctionCall(func_call);
+ penalty += FunctionCall(func_call, at_end);
+ at_end = "";
} else if (const IdentifierNode* identifier = root->AsIdentifier()) {
Print(identifier->value().value());
} else if (const ListNode* list = root->AsList()) {
@@ -505,7 +541,7 @@ int Printer::Expr(const ParseNode* root,
std::back_inserter(comments_));
}
- Print(suffix);
+ Print(at_end);
penalty_depth_--;
return penalty;
@@ -524,14 +560,7 @@ void Printer::Sequence(SequenceStyle style,
if (style == kSequenceStyleBlock || style == kSequenceStyleBracedBlock)
force_multiline = true;
- if (end && end->comments() && !end->comments()->before().empty())
- force_multiline = true;
-
- // If there's before line comments, make sure we have a place to put them.
- for (const auto& i : list) {
- if (i->comments() && !i->comments()->before().empty())
- force_multiline = true;
- }
+ force_multiline |= ListWillBeMultiline(list, end);
if (list.size() == 0 && !force_multiline) {
// No elements, and not forcing newlines, print nothing.
@@ -571,7 +600,7 @@ void Printer::Sequence(SequenceStyle style,
}
// Trailing comments.
- if (end->comments()) {
+ if (end->comments() && !end->comments()->before().empty()) {
if (list.size() >= 2)
Newline();
for (const auto& c : end->comments()->before()) {
@@ -597,7 +626,8 @@ void Printer::Sequence(SequenceStyle style,
Print("}");
}
-int Printer::FunctionCall(const FunctionCallNode* func_call) {
+int Printer::FunctionCall(const FunctionCallNode* func_call,
+ const std::string& suffix) {
int start_line = CurrentLine();
int start_column = CurrentColumn();
Print(func_call->function().value());
@@ -625,6 +655,7 @@ int Printer::FunctionCall(const FunctionCallNode* func_call) {
std::string terminator = ")";
if (have_block)
terminator += " {";
+ terminator += suffix;
// 1: Same line.
Printer sub1;
@@ -637,13 +668,11 @@ int Printer::FunctionCall(const FunctionCallNode* func_call) {
}
sub1.Print(terminator);
penalty_one_line += AssessPenalty(sub1.String());
- std::vector<std::string> lines;
- base::SplitStringDontTrim(sub1.String(), '\n', &lines);
// This extra penalty prevents a short second argument from being squeezed in
// after a first argument that went multiline (and instead preferring a
// variant below).
- if (lines.size() > 1)
- penalty_one_line += kPenaltyBrokenLineOnOneLiner;
+ penalty_one_line +=
+ (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;
// 2: Starting on same line, broken at commas.
Printer sub2;
@@ -742,6 +771,7 @@ int Printer::FunctionCall(const FunctionCallNode* func_call) {
}
Print(")");
+ Print(suffix);
if (have_block) {
Print(" ");
@@ -760,6 +790,24 @@ void Printer::InitializeSub(Printer* sub) {
sub->Print(std::string(CurrentColumn(), 'x'));
}
+template <class PARSENODE>
+bool Printer::ListWillBeMultiline(const std::vector<PARSENODE*>& list,
+ const ParseNode* end) {
+ if (list.size() > 1)
+ return true;
+
+ if (end && end->comments() && !end->comments()->before().empty())
+ return true;
+
+ // If there's before line comments, make sure we have a place to put them.
+ for (const auto& i : list) {
+ if (i->comments() && !i->comments()->before().empty())
+ return true;
+ }
+
+ return false;
+}
+
void DoFormat(const ParseNode* root, bool dump_tree, std::string* output) {
if (dump_tree) {
std::ostringstream os;
« no previous file with comments | « no previous file | tools/gn/command_format_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698