diff options
author | Jacek Olesiak <jolesiak@google.com> | 2018-05-24 10:50:36 +0000 |
---|---|---|
committer | Jacek Olesiak <jolesiak@google.com> | 2018-05-24 10:50:36 +0000 |
commit | 34391f097d9350d59d3050bf149c0f536dd460da (patch) | |
tree | 642760dfbe9429f661dcdd9d891837fc063d07b3 /clang/lib | |
parent | d0a8ad3ac047bc6badaaf8796eb6c8447c4dbaf9 (diff) | |
download | bcm5719-llvm-34391f097d9350d59d3050bf149c0f536dd460da.tar.gz bcm5719-llvm-34391f097d9350d59d3050bf149c0f536dd460da.zip |
[clang-format] Fix putting ObjC message arguments in one line for multiline receiver
Summary:
Reapply reverted changes from D46879.
Currently BreakBeforeParameter is set to true everytime message receiver spans multiple lines, e.g.:
```
[[object block:^{
return 42;
}] aa:42 bb:42];
```
will be formatted:
```
[[object block:^{
return 42;
}] aa:42
bb:42];
```
even though arguments could fit into one line. This change fixes this behavior.
Test Plan:
make -j12 FormatTests && tools/clang/unittests/Format/FormatTests
Reviewers: benhamilton, krasimir
Reviewed By: benhamilton, krasimir
Subscribers: djasper, klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D47195
llvm-svn: 333171
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Format/ContinuationIndenter.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index eacdfdc6e05..ac871471d9d 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1387,6 +1387,29 @@ void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) { (Current.is(tok::greater) && Current.is(TT_DictLiteral)))) State.Stack.pop_back(); + // Reevaluate whether ObjC message arguments fit into one line. + // If a receiver spans multiple lines, e.g.: + // [[object block:^{ + // return 42; + // }] a:42 b:42]; + // BreakBeforeParameter is calculated based on an incorrect assumption + // (it is checked whether the whole expression fits into one line without + // considering a line break inside a message receiver). + // We check whether arguements fit after receiver scope closer (into the same + // line). + if (Current.MatchingParen && Current.MatchingParen->Previous) { + const FormatToken &CurrentScopeOpener = *Current.MatchingParen->Previous; + if (CurrentScopeOpener.is(TT_ObjCMethodExpr) && + CurrentScopeOpener.MatchingParen) { + int NecessarySpaceInLine = + getLengthToMatchingParen(CurrentScopeOpener, State.Stack) + + CurrentScopeOpener.TotalLength - Current.TotalLength - 1; + if (State.Column + Current.ColumnWidth + NecessarySpaceInLine <= + Style.ColumnLimit) + State.Stack.back().BreakBeforeParameter = false; + } + } + if (Current.is(tok::r_square)) { // If this ends the array subscript expr, reset the corresponding value. const FormatToken *NextNonComment = Current.getNextNonComment(); |