Index: tools/gn/command_format.cc |
diff --git a/tools/gn/command_format.cc b/tools/gn/command_format.cc |
index c3396474fc7759a1c469b58f4aa310009b934f02..efba348c28ac4396d37166fb6330194e4b414873 100644 |
--- a/tools/gn/command_format.cc |
+++ b/tools/gn/command_format.cc |
@@ -10,6 +10,7 @@ |
#include "tools/gn/commands.h" |
#include "tools/gn/filesystem_utils.h" |
#include "tools/gn/input_file.h" |
+#include "tools/gn/line_breaker.h" |
#include "tools/gn/parser.h" |
#include "tools/gn/scheduler.h" |
#include "tools/gn/setup.h" |
@@ -53,20 +54,6 @@ const char kFormat_Help[] = |
namespace { |
-const int kIndentSize = 2; |
-const int kMaximumWidth = 80; |
- |
-enum Precedence { |
- kPrecedenceLowest, |
- kPrecedenceAssign, |
- kPrecedenceOr, |
- kPrecedenceAnd, |
- kPrecedenceCompare, |
- kPrecedenceAdd, |
- kPrecedenceSuffix, |
- kPrecedenceUnary, |
-}; |
- |
class Printer { |
public: |
Printer(); |
@@ -154,32 +141,17 @@ class Printer { |
void FunctionCall(const FunctionCallNode* func_call); |
+ bool IsStartOfStatement(const ParseNode* node); |
+ |
std::string output_; // Output buffer. |
std::vector<Token> comments_; // Pending end-of-line comments. |
int margin_; // Left margin (number of spaces). |
- // Gives the precedence for operators in a BinaryOpNode. |
- std::map<base::StringPiece, Precedence> precedence_; |
- |
DISALLOW_COPY_AND_ASSIGN(Printer); |
}; |
Printer::Printer() : margin_(0) { |
output_.reserve(100 << 10); |
- precedence_["="] = kPrecedenceAssign; |
- precedence_["+="] = kPrecedenceAssign; |
- precedence_["-="] = kPrecedenceAssign; |
- precedence_["||"] = kPrecedenceOr; |
- precedence_["&&"] = kPrecedenceAnd; |
- precedence_["<"] = kPrecedenceCompare; |
- precedence_[">"] = kPrecedenceCompare; |
- precedence_["=="] = kPrecedenceCompare; |
- precedence_["!="] = kPrecedenceCompare; |
- precedence_["<="] = kPrecedenceCompare; |
- precedence_[">="] = kPrecedenceCompare; |
- precedence_["+"] = kPrecedenceAdd; |
- precedence_["-"] = kPrecedenceAdd; |
- precedence_["!"] = kPrecedenceUnary; |
} |
Printer::~Printer() { |
@@ -287,6 +259,9 @@ void Printer::Block(const ParseNode* root) { |
size_t i = 0; |
for (const auto& stmt : block->statements()) { |
+ std::stringstream tmp; |
+ stmt->Print(tmp, 0); |
+ fprintf(stderr, "stmt: %s\n", tmp.str().c_str()); |
Expr(stmt, kPrecedenceLowest, false); |
Newline(); |
if (stmt->comments()) { |
@@ -340,6 +315,40 @@ void Printer::AddParen(int prec, int outer_prec, bool* parenthesized) { |
} |
} |
+// This determines if the given node is something "statement-like". Generally |
+// these are an assignment like 'sources = ["x"]' or a standalone function call |
+// like 'import("xyz.gni")'. Some cases are slightly involved because the parse |
+// tree is generic across binary operators which include both assignments that |
+// are standalone statements, but also operators link &&, || which are not. |
+// Additionally, function calls can mark statement boundaries when they're a |
+// statement inside a block, but they may also be embedded for their return |
+// value into the body of an expression (say, a rebase_path() in an expression). |
+// |
+// TODO: Maybe all the above is overly complicated, and it's just all the |
+// direct children of BlockNodes + the false branch of ConditionNode. |
+// |
+// Breaking up into statements is used to segment into chunks. Line breaking and |
+// indenting is done on a chunk basis, and one chunk does not affect another. |
+bool Printer::IsStartOfStatement(const ParseNode* node) { |
+ // Is start of statement: |
+ // AccessorNode; // No |
+ // BinaryOpNode; // For =, +=, -=: Yes, else: No. |
+ // BlockCommentNode; // Yes |
+ // BlockNode; // No (?) just its statements. |
+ // ConditionNode; // Yes both arms. |
+ // EndNode; // No |
+ // FunctionCallNode; // Sometimes. This one is tricky. Maybe only when it's |
+ // // the immediate child of a BlockNode? |
+ // IdentifierNode; // No |
+ // ListNode; // No |
+ // LiteralNode; // No |
+ // UnaryOpNode; // No |
+ return false; |
+} |
+ |
+void DetermineLineBreaksForChunk() { |
+} |
+ |
Printer::ExprStyle Printer::Expr(const ParseNode* root, |
int outer_prec, |
bool prefer_multiline) { |
@@ -374,9 +383,9 @@ Printer::ExprStyle Printer::Expr(const ParseNode* root, |
Print("]"); |
} |
} else if (const BinaryOpNode* binop = root->AsBinaryOp()) { |
- CHECK(precedence_.find(binop->op().value()) != precedence_.end()); |
- Precedence prec = precedence_[binop->op().value()]; |
+ Precedence prec = GetPrecedence(binop->op().value()); |
AddParen(prec, outer_prec, &parenthesized); |
+ //FindLineBreakLocation(binop); |
Metrics right = GetLengthOfExpr( |
binop->right(), prec + 1, IsAlwaysMultilineAssignment(binop)); |
int op_length = static_cast<int>(binop->op().value().size()) + 2; |
@@ -414,6 +423,9 @@ Printer::ExprStyle Printer::Expr(const ParseNode* root, |
// ConditionNode::Execute. |
bool is_else_if = condition->if_false()->AsBlock() == NULL; |
if (is_else_if) { |
+std::stringstream tmp; |
+condition->if_false()->Print(tmp, 0); |
+fprintf(stderr, "stmt4: %s\n", tmp.str().c_str()); |
Expr(condition->if_false(), kPrecedenceLowest, false); |
} else { |
Sequence(kSequenceStyleBracedBlock, |
@@ -484,6 +496,11 @@ void Printer::Sequence(SequenceStyle style, |
// No elements, and not forcing newlines, print nothing. |
} else if (list.size() == 1 && !force_multiline) { |
Print(" "); |
+if (style == kSequenceStyleBracedBlock) { |
+std::stringstream tmp; |
+list[0]->Print(tmp, 0); |
+fprintf(stderr, "stmt2: %s\n", tmp.str().c_str()); |
+} |
Expr(list[0], kPrecedenceLowest, false); |
CHECK(!list[0]->comments() || list[0]->comments()->after().empty()); |
Print(" "); |
@@ -491,6 +508,11 @@ void Printer::Sequence(SequenceStyle style, |
margin_ += kIndentSize; |
size_t i = 0; |
for (const auto& x : list) { |
+if (style == kSequenceStyleBracedBlock) { |
+std::stringstream tmp; |
+x->Print(tmp, 0); |
+fprintf(stderr, "stmt3: %s\n", tmp.str().c_str()); |
+} |
Newline(); |
// If: |
// - we're going to output some comments, and; |