diff options
author | Daniel Jasper <djasper@google.com> | 2013-01-16 14:59:02 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-01-16 14:59:02 +0000 |
commit | 0df6acdf4f6faf7579775a739e1c09448c076c0f (patch) | |
tree | f91f004a8f568b32b857f5a0d23a54626901d42b /lib/Format/Format.cpp | |
parent | ca547dbbb1e10c801158f2eecaf3d49e1071b0e3 (diff) |
Add option to avoid "bin-packing" of parameters.
"Bin-packing" here means allowing multiple parameters on one line, if a
function call/declaration is spread over multiple lines.
This is required by the Chromium style guide and probably desired for
the Google style guide. Not making changes to LLVM style as I don't have
enough data.
With this enabled, we format stuff like:
aaaaaaaaaaaaaaa(aaaaaaaaaa,
aaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaa).aaaaaaaaaaaaaaaaaa();
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172617 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/Format.cpp')
-rw-r--r-- | lib/Format/Format.cpp | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index ee9b463e90..f4fa6fc35f 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -73,7 +73,7 @@ public: AnnotatedToken(const FormatToken &FormatTok) : FormatTok(FormatTok), Type(TT_Unknown), SpaceRequiredBefore(false), CanBreakBefore(false), MustBreakBefore(false), - ClosesTemplateDeclaration(false), Parent(NULL) {} + ClosesTemplateDeclaration(false), MatchingParen(NULL), Parent(NULL) {} bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); } bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); } @@ -92,6 +92,8 @@ public: bool ClosesTemplateDeclaration; + AnnotatedToken *MatchingParen; + /// \brief The total length of the line up to and including this token. unsigned TotalLength; @@ -146,6 +148,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.SplitTemplateClosingGreater = true; LLVMStyle.IndentCaseLabels = false; LLVMStyle.SpacesBeforeTrailingComments = 1; + LLVMStyle.BinPackParameters = true; LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; @@ -162,6 +165,7 @@ FormatStyle getGoogleStyle() { GoogleStyle.SplitTemplateClosingGreater = false; GoogleStyle.IndentCaseLabels = true; GoogleStyle.SpacesBeforeTrailingComments = 2; + GoogleStyle.BinPackParameters = false; GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; GoogleStyle.AllowShortIfStatementsOnASingleLine = true; GoogleStyle.ObjCSpaceBeforeProtocolList = false; @@ -318,7 +322,8 @@ private: struct ParenState { ParenState(unsigned Indent, unsigned LastSpace) : Indent(Indent), LastSpace(LastSpace), FirstLessLess(0), - BreakBeforeClosingBrace(false), BreakAfterComma(false) {} + BreakBeforeClosingBrace(false), BreakAfterComma(false), + HasMultiParameterLine(false) {} /// \brief The position to which a specific parenthesis level needs to be /// indented. @@ -345,6 +350,7 @@ private: bool BreakBeforeClosingBrace; bool BreakAfterComma; + bool HasMultiParameterLine; bool operator<(const ParenState &Other) const { if (Indent != Other.Indent) @@ -357,6 +363,8 @@ private: return BreakBeforeClosingBrace; if (BreakAfterComma != Other.BreakAfterComma) return BreakAfterComma; + if (HasMultiParameterLine != Other.HasMultiParameterLine) + return HasMultiParameterLine; return false; } }; @@ -484,6 +492,9 @@ private: if (Previous.is(tok::l_paren) || Previous.is(tok::l_brace) || State.NextToken->Parent->Type == TT_TemplateOpener) State.Stack[ParenLevel].Indent = State.Column + Spaces; + if (Previous.is(tok::comma)) + State.Stack[ParenLevel].HasMultiParameterLine = true; + // Top-level spaces that are not part of assignments are exempt as that // mostly leads to better results. @@ -492,9 +503,18 @@ private: (ParenLevel != 0 || getPrecedence(Previous) == prec::Assignment)) State.Stack[ParenLevel].LastSpace = State.Column; } - if (Newline && Previous.is(tok::l_brace)) { + + // If we break after an {, we should also break before the corresponding }. + if (Newline && Previous.is(tok::l_brace)) State.Stack.back().BreakBeforeClosingBrace = true; - } + + // If we are breaking after '(', '{', '<' or ',', we need to break after + // future commas as well to avoid bin packing. + if (!Style.BinPackParameters && Newline && + (Previous.is(tok::comma) || Previous.is(tok::l_paren) || + Previous.is(tok::l_brace) || Previous.Type == TT_TemplateOpener)) + State.Stack.back().BreakAfterComma = true; + moveStateToNextToken(State); } @@ -523,6 +543,17 @@ private: } State.Stack.push_back( ParenState(NewIndent, State.Stack.back().LastSpace)); + + // If the entire set of parameters will not fit on the current line, we + // will need to break after commas on this level to avoid bin-packing. + if (!Style.BinPackParameters && Current.MatchingParen != NULL && + !Current.Children.empty()) { + if (getColumnLimit() < State.Column + Current.FormatTok.TokenLength + + Current.MatchingParen->TotalLength - + Current.Children[0].TotalLength) { + State.Stack.back().BreakAfterComma = true; + } + } } // If we encounter a closing ), ], } or >, we can remove a level from our @@ -623,6 +654,11 @@ private: State.NextToken->Type != TT_LineComment && State.Stack.back().BreakAfterComma) return UINT_MAX; + // Trying to insert a parameter on a new line if there are already more than + // one parameter on the current line is bin packing. + if (NewLine && State.NextToken->Parent->is(tok::comma) && + State.Stack.back().HasMultiParameterLine && !Style.BinPackParameters) + return UINT_MAX; if (!NewLine && State.NextToken->Type == TT_CtorInitializerColon) return UINT_MAX; @@ -631,7 +667,8 @@ private: CurrentPenalty += Parameters.PenaltyIndentLevel * State.Stack.size() + splitPenalty(*State.NextToken->Parent); } else { - if (State.Stack.size() < State.StartOfLineLevel) + if (State.Stack.size() < State.StartOfLineLevel && + State.NextToken->is(tok::identifier)) CurrentPenalty += Parameters.PenaltyLevelDecrease * (State.StartOfLineLevel - State.Stack.size()); } @@ -706,8 +743,13 @@ public: ColonIsObjCMethodExpr(false) {} bool parseAngle() { + if (CurrentToken == NULL) + return false; + AnnotatedToken *Left = CurrentToken->Parent; while (CurrentToken != NULL) { if (CurrentToken->is(tok::greater)) { + Left->MatchingParen = CurrentToken; + CurrentToken->MatchingParen = Left; CurrentToken->Type = TT_TemplateCloser; next(); return true; @@ -725,10 +767,15 @@ public: } bool parseParens() { - if (CurrentToken != NULL && CurrentToken->is(tok::caret)) - CurrentToken->Parent->Type = TT_ObjCBlockLParen; + if (CurrentToken == NULL) + return false; + AnnotatedToken *Left = CurrentToken->Parent; + if (CurrentToken->is(tok::caret)) + Left->Type = TT_ObjCBlockLParen; while (CurrentToken != NULL) { if (CurrentToken->is(tok::r_paren)) { + Left->MatchingParen = CurrentToken; + CurrentToken->MatchingParen = Left; next(); return true; } @@ -781,8 +828,14 @@ public: } bool parseBrace() { + // Lines are fine to end with '{'. + if (CurrentToken == NULL) + return true; + AnnotatedToken *Left = CurrentToken->Parent; while (CurrentToken != NULL) { if (CurrentToken->is(tok::r_brace)) { + Left->MatchingParen = CurrentToken; + CurrentToken->MatchingParen = Left; next(); return true; } @@ -791,7 +844,6 @@ public: if (!consumeToken()) return false; } - // Lines can currently end with '{'. return true; } |