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/file_util.h" | 8 #include "base/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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 106 |
107 // End the current line, flushing end of line comments. | 107 // End the current line, flushing end of line comments. |
108 void Newline(); | 108 void Newline(); |
109 | 109 |
110 // Remove trailing spaces from the current line. | 110 // Remove trailing spaces from the current line. |
111 void Trim(); | 111 void Trim(); |
112 | 112 |
113 // Whether there's a blank separator line at the current position. | 113 // Whether there's a blank separator line at the current position. |
114 bool HaveBlankLine(); | 114 bool HaveBlankLine(); |
115 | 115 |
| 116 bool IsAssignment(const ParseNode* node); |
| 117 |
| 118 // Heuristics to decide if there should be a blank line added between two |
| 119 // items. For various "small" items, it doesn't look nice if there's too much |
| 120 // vertical whitespace added. |
| 121 bool ShouldAddBlankLineInBetween(const ParseNode* a, const ParseNode* b); |
| 122 |
116 // Get the 0-based x position on the current line. | 123 // Get the 0-based x position on the current line. |
117 int CurrentColumn(); | 124 int CurrentColumn(); |
118 | 125 |
119 // Adds an opening ( if prec is less than the outers (to maintain evalution | 126 // Adds an opening ( if prec is less than the outers (to maintain evalution |
120 // order for a subexpression). If an opening paren is emitted, *parenthesized | 127 // order for a subexpression). If an opening paren is emitted, *parenthesized |
121 // will be set so it can be closed at the end of the expression. | 128 // will be set so it can be closed at the end of the expression. |
122 void AddParen(int prec, int outer_prec, bool* parenthesized); | 129 void AddParen(int prec, int outer_prec, bool* parenthesized); |
123 | 130 |
124 // Print the expression to the output buffer. Returns the type of element | 131 // Print the expression to the output buffer. Returns the type of element |
125 // added to the output. The value of outer_prec gives the precedence of the | 132 // added to the output. The value of outer_prec gives the precedence of the |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 output_.resize(n); | 227 output_.resize(n); |
221 } | 228 } |
222 | 229 |
223 bool Printer::HaveBlankLine() { | 230 bool Printer::HaveBlankLine() { |
224 size_t n = output_.size(); | 231 size_t n = output_.size(); |
225 while (n > 0 && output_[n - 1] == ' ') | 232 while (n > 0 && output_[n - 1] == ' ') |
226 --n; | 233 --n; |
227 return n > 2 && output_[n - 1] == '\n' && output_[n - 2] == '\n'; | 234 return n > 2 && output_[n - 1] == '\n' && output_[n - 2] == '\n'; |
228 } | 235 } |
229 | 236 |
| 237 bool Printer::IsAssignment(const ParseNode* node) { |
| 238 return node->AsBinaryOp() && (node->AsBinaryOp()->op().value() == "=" || |
| 239 node->AsBinaryOp()->op().value() == "+=" || |
| 240 node->AsBinaryOp()->op().value() == "-="); |
| 241 } |
| 242 |
| 243 bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a, |
| 244 const ParseNode* b) { |
| 245 // A bunch of imports looks silly at the top of a file separated by blank |
| 246 // lines, even though they are statements. |
| 247 if (a->AsFunctionCall() && b->AsFunctionCall() && |
| 248 a->AsFunctionCall()->function().value() == "import" && |
| 249 b->AsFunctionCall()->function().value() == "import") { |
| 250 return false; |
| 251 } |
| 252 |
| 253 if (IsAssignment(a) && IsAssignment(b)) { |
| 254 Metrics first = GetLengthOfExpr(a, kPrecedenceLowest); |
| 255 Metrics second = GetLengthOfExpr(b, kPrecedenceLowest); |
| 256 if (!first.multiline && !second.multiline) |
| 257 return false; |
| 258 } |
| 259 return true; |
| 260 } |
| 261 |
230 int Printer::CurrentColumn() { | 262 int Printer::CurrentColumn() { |
231 int n = 0; | 263 int n = 0; |
232 while (n < static_cast<int>(output_.size()) && | 264 while (n < static_cast<int>(output_.size()) && |
233 output_[output_.size() - 1 - n] != '\n') { | 265 output_[output_.size() - 1 - n] != '\n') { |
234 ++n; | 266 ++n; |
235 } | 267 } |
236 return n; | 268 return n; |
237 } | 269 } |
238 | 270 |
239 void Printer::Block(const ParseNode* root) { | 271 void Printer::Block(const ParseNode* root) { |
(...skipping 14 matching lines...) Expand all Loading... |
254 // Why are before() not printed here too? before() are handled inside | 286 // Why are before() not printed here too? before() are handled inside |
255 // Expr(), as are suffix() which are queued to the next Newline(). | 287 // Expr(), as are suffix() which are queued to the next Newline(). |
256 // However, because it's a general expression handler, it doesn't insert | 288 // However, because it's a general expression handler, it doesn't insert |
257 // the newline itself, which only happens between block statements. So, | 289 // the newline itself, which only happens between block statements. So, |
258 // the after are handled explicitly here. | 290 // the after are handled explicitly here. |
259 for (const auto& c : stmt->comments()->after()) { | 291 for (const auto& c : stmt->comments()->after()) { |
260 TrimAndPrintToken(c); | 292 TrimAndPrintToken(c); |
261 Newline(); | 293 Newline(); |
262 } | 294 } |
263 } | 295 } |
264 if (i < block->statements().size() - 1) | 296 if (i < block->statements().size() - 1 && |
| 297 (ShouldAddBlankLineInBetween(block->statements()[i], |
| 298 block->statements()[i + 1]))) { |
265 Newline(); | 299 Newline(); |
| 300 } |
266 ++i; | 301 ++i; |
267 } | 302 } |
268 | 303 |
269 if (block->comments()) { | 304 if (block->comments()) { |
270 for (const auto& c : block->comments()->after()) { | 305 for (const auto& c : block->comments()->after()) { |
271 TrimAndPrintToken(c); | 306 TrimAndPrintToken(c); |
272 Newline(); | 307 Newline(); |
273 } | 308 } |
274 } | 309 } |
275 } | 310 } |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str()); | 759 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str()); |
725 } else { | 760 } else { |
726 printf("%s", output_string.c_str()); | 761 printf("%s", output_string.c_str()); |
727 } | 762 } |
728 } | 763 } |
729 | 764 |
730 return 0; | 765 return 0; |
731 } | 766 } |
732 | 767 |
733 } // namespace commands | 768 } // namespace commands |
OLD | NEW |