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

Side by Side Diff: tools/gn/line_breaker.h

Issue 742003002: gn format: penalty-based line breaking WIP XXX Base URL: https://chromium.googlesource.com/chromium/src.git@gn-more-disabled
Patch Set: futzing 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 unified diff | Download patch
« no previous file with comments | « tools/gn/gn.gyp ('k') | tools/gn/line_breaker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef TOOLS_GN_LINE_BREAKER_H_
6 #define TOOLS_GN_LINE_BREAKER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "tools/gn/token.h"
13
14 class ParseNode;
15
16 namespace commands {
17
18 enum { kIndentSize = 2 };
19 enum { kMaximumWidth = 2 };
20
21 enum Precedence {
22 kPrecedenceLowest,
23 kPrecedenceAssign,
24 kPrecedenceOr,
25 kPrecedenceAnd,
26 kPrecedenceCompare,
27 kPrecedenceAdd,
28 kPrecedenceSuffix,
29 kPrecedenceUnary,
30 };
31
32 // Gives the precedence for operators in a BinaryOpNode.
33 Precedence GetPrecedence(const base::StringPiece op);
34
35 class AnnotatedToken {
36 public:
37 enum Type {
38 UNDERLYING = Token::Type::NUM_TYPES, // Nothing additional on top of the
39 // basic Token::Type;
40 LEFT_PAREN_FUNCTION_CALL,
41 LEFT_PAREN_GROUPING,
42 LEFT_BRACKET_LIST_LITERAL,
43 LEFT_BRACKET_ACCESSOR,
44 };
45
46 AnnotatedToken(const Token& token, Type type);
47 ~AnnotatedToken();
48
49 const base::StringPiece value() const { return token_.value(); }
50 Type type() const {
51 return type_ == UNDERLYING ? static_cast<Type>(token_.type()) : type_;
52 }
53
54 private:
55 Token token_;
56 Type type_;
57 };
58
59 std::vector<AnnotatedToken> BuildAnnotatedTokenList(const ParseNode* statement);
60
61 // This takes a subset of the parse tree that is considered to be one
62 // "statement-like" thing, as well as the column offset at which it must start.
63 // This might be something like an assignment 'sources = ["x"]' or the condition
64 // in an 'if' statement.
65 //
66 // The chunk is a flat list of tokens with extra information about what kind
67 // they are (for example, distinguishing between the '(' to start a function
68 // call, vs. a '(' in a parenthesized expression). If any line break is
69 // necessary to fit, try a line break between each item, summing up a penalty
70 // value depending on where it's broken. The set of line breaks with the lowest
71 // penalty score is chosen.
72 //
73 // One wrinkle is that we can't just do an exhaustive search because there are
74 // commonly very long statements in .gn files. For 'sources = ["0", "1", "2",
75 // ... "999"]' there's ~2000 possible line breaks inside the list. Checking all
76 // possible line breaks would be 2^2000 permutations, and ain't nobody got time
77 // for that. However, the penalty for ([tokenN..end] laid out at column M) is a
78 // cacheable value, which makes the problem tractable.
79 class LineBreaker {
80 public:
81 LineBreaker(const std::vector<AnnotatedToken>& annotated_tokens,
82 int initial_column);
83 ~LineBreaker();
84
85 std::string GetBestLayout();
86
87 private:
88 struct LineState {
89 int column;
90 int next;
91 };
92 void Format(int index, int start_column);
93
94 int CalculatePenalty(LineState state, bool newline);
95 void AddTokenToState(bool newline, LineState* state);
96
97 struct CacheKey {
98 int token_index; // The penalty is calculated from this token to the end of
99 // the list.
100 int column;
101 };
102 typedef std::map<CacheKey, int> PenaltyCache;
103 PenaltyCache penalty_cache_;
104
105 const std::vector<AnnotatedToken>& annotated_tokens_;
106 int initial_column_;
107 int end_;
108
109 DISALLOW_COPY_AND_ASSIGN(LineBreaker);
110 };
111
112 } // namespace commands
113
114 #endif // TOOLS_GN_LINE_BREAKER_H_
OLDNEW
« no previous file with comments | « tools/gn/gn.gyp ('k') | tools/gn/line_breaker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698