diff options
| author | Jacek Olesiak <jolesiak@google.com> | 2018-05-17 08:35:15 +0000 |
|---|---|---|
| committer | Jacek Olesiak <jolesiak@google.com> | 2018-05-17 08:35:15 +0000 |
| commit | b48d65ca757f8d7199b6a7825cb100b95c5d9781 (patch) | |
| tree | ff68e6bff0b21d5c5e178f41509da79dbaf96297 /clang/lib/Format | |
| parent | c10788728bb5f15bff2c080e75831e3d710aa8f9 (diff) | |
| download | bcm5719-llvm-b48d65ca757f8d7199b6a7825cb100b95c5d9781.tar.gz bcm5719-llvm-b48d65ca757f8d7199b6a7825cb100b95c5d9781.zip | |
[clang-format] Fix putting ObjC message arguments in one line for multiline receiver
Summary:
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, djasper
Reviewed By: benhamilton
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D46879
llvm-svn: 332582
Diffstat (limited to 'clang/lib/Format')
| -rw-r--r-- | clang/lib/Format/ContinuationIndenter.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 9a07c5ed591..fc4c9115e89 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1073,8 +1073,34 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, if (Current.isMemberAccess()) State.Stack.back().StartOfFunctionCall = !Current.NextOperator ? 0 : State.Column; - if (Current.is(TT_SelectorName)) + if (Current.is(TT_SelectorName) && + !State.Stack.back().ObjCSelectorNameFound) { State.Stack.back().ObjCSelectorNameFound = true; + + // 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). + if (Current.Previous && Current.Previous->closesScope() && + Current.Previous->MatchingParen && + Current.Previous->MatchingParen->Previous) { + const FormatToken &CurrentScopeOpener = + *Current.Previous->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(TT_CtorInitializerColon) && Style.BreakConstructorInitializers != FormatStyle::BCIS_AfterColon) { // Indent 2 from the column, so: |

