diff options
author | Daniel Jasper <djasper@google.com> | 2015-04-23 09:23:17 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2015-04-23 09:23:17 +0000 |
commit | 289afc071ed0b1aa39b4021c5dc032163be5ce7e (patch) | |
tree | 47be356e566fe68ad208ea12e7cf22f4d4f017da /clang/lib/Format | |
parent | 5fd24c673e679557c3fcc16a6686c5f4af4944b9 (diff) | |
download | bcm5719-llvm-289afc071ed0b1aa39b4021c5dc032163be5ce7e.tar.gz bcm5719-llvm-289afc071ed0b1aa39b4021c5dc032163be5ce7e.zip |
clang-format: Support nested block formatting with ColumnLimit=0.
llvm-svn: 235580
Diffstat (limited to 'clang/lib/Format')
-rw-r--r-- | clang/lib/Format/ContinuationIndenter.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.h | 47 |
3 files changed, 50 insertions, 31 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index a2a68bd6d48..b03a99a248b 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -839,12 +839,26 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, (Current.PackingKind == PPK_OnePerLine || (!BinPackInconclusiveFunctions && Current.PackingKind == PPK_Inconclusive))); - // If this '[' opens an ObjC call, determine whether all parameters fit - // into one line and put one per line if they don't. - if (Current.is(TT_ObjCMethodExpr) && Style.ColumnLimit != 0 && - getLengthToMatchingParen(Current) + State.Column > + if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen) { + if (Style.ColumnLimit) { + // If this '[' opens an ObjC call, determine whether all parameters fit + // into one line and put one per line if they don't. + if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit(State)) - BreakBeforeParameter = true; + BreakBeforeParameter = true; + } else { + // For ColumnLimit = 0, we have to figure out whether there is or has to + // be a line break within this call. + for (const FormatToken *Tok = &Current; + Tok && Tok != Current.MatchingParen; Tok = Tok->Next) { + if (Tok->MustBreakBefore || + (Tok->CanBreakBefore && Tok->NewlinesBefore > 0)) { + BreakBeforeParameter = true; + break; + } + } + } + } } bool NoLineBreak = State.Stack.back().NoLineBreak || (Current.is(TT_TemplateOpener) && diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 6c92d79d139..f5120b9f2f3 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -303,7 +303,9 @@ private: class NoColumnLimitFormatter { public: - NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {} + NoColumnLimitFormatter(ContinuationIndenter *Indenter, + UnwrappedLineFormatter *Formatter) + : Indenter(Indenter), Formatter(Formatter) {} /// \brief Formats the line starting at \p State, simply keeping all of the /// input's line breaking decisions. @@ -314,12 +316,15 @@ public: bool Newline = Indenter->mustBreak(State) || (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); + unsigned Penalty = 0; + Formatter->formatChildren(State, Newline, /*DryRun=*/false, Penalty); Indenter->addTokenToState(State, Newline, /*DryRun=*/false); } } private: ContinuationIndenter *Indenter; + UnwrappedLineFormatter *Formatter; }; @@ -426,8 +431,7 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines, Indenter->addTokenToState(State, /*Newline=*/false, DryRun); } } else if (Style.ColumnLimit == 0) { - // FIXME: Implement nested blocks for ColumnLimit = 0. - NoColumnLimitFormatter Formatter(Indenter); + NoColumnLimitFormatter Formatter(Indenter, this); if (!DryRun) Formatter.format(Indent, &TheLine); } else { diff --git a/clang/lib/Format/UnwrappedLineFormatter.h b/clang/lib/Format/UnwrappedLineFormatter.h index 7d5b01148b0..35626338e38 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.h +++ b/clang/lib/Format/UnwrappedLineFormatter.h @@ -40,6 +40,30 @@ public: unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, int AdditionalIndent = 0, bool FixBadIndentation = false); + + /// \brief If the \p State's next token is an r_brace closing a nested block, + /// format the nested block before it. + /// + /// Returns \c true if all children could be placed successfully and adapts + /// \p Penalty as well as \p State. If \p DryRun is false, also directly + /// creates changes using \c Whitespaces. + /// + /// The crucial idea here is that children always get formatted upon + /// encountering the closing brace right after the nested block. Now, if we + /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is + /// \c false), the entire block has to be kept on the same line (which is only + /// possible if it fits on the line, only contains a single statement, etc. + /// + /// If \p NewLine is true, we format the nested block on separate lines, i.e. + /// break after the "{", format all lines with correct indentation and the put + /// the closing "}" on yet another new line. + /// + /// This enables us to keep the simple structure of the + /// \c UnwrappedLineFormatter, where we only have two options for each token: + /// break or don't break. + bool formatChildren(LineState &State, bool NewLine, bool DryRun, + unsigned &Penalty); + private: /// \brief Formats an \c AnnotatedLine and returns the penalty. /// @@ -131,29 +155,6 @@ private: void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode, bool NewLine, unsigned *Count, QueueType *Queue); - /// \brief If the \p State's next token is an r_brace closing a nested block, - /// format the nested block before it. - /// - /// Returns \c true if all children could be placed successfully and adapts - /// \p Penalty as well as \p State. If \p DryRun is false, also directly - /// creates changes using \c Whitespaces. - /// - /// The crucial idea here is that children always get formatted upon - /// encountering the closing brace right after the nested block. Now, if we - /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is - /// \c false), the entire block has to be kept on the same line (which is only - /// possible if it fits on the line, only contains a single statement, etc. - /// - /// If \p NewLine is true, we format the nested block on separate lines, i.e. - /// break after the "{", format all lines with correct indentation and the put - /// the closing "}" on yet another new line. - /// - /// This enables us to keep the simple structure of the - /// \c UnwrappedLineFormatter, where we only have two options for each token: - /// break or don't break. - bool formatChildren(LineState &State, bool NewLine, bool DryRun, - unsigned &Penalty); - ContinuationIndenter *Indenter; WhitespaceManager *Whitespaces; FormatStyle Style; |