clang-format: Improve format of calls with several lambdas.

Before:
  SomeFunction([]() {
                 int i = 42;
                 return i;
               },
               []() {
    int j = 43;
    return j;
  });

After:
  SomeFunction([]() {
                 int i = 42;
                 return i;
               },
               []() {
                 int j = 43;
                 return j;
               });

llvm-svn: 205848
This commit is contained in:
Daniel Jasper 2014-04-09 12:08:39 +00:00
parent 6bd3229616
commit 3ae6f5a47b
3 changed files with 25 additions and 2 deletions

View File

@ -566,6 +566,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
Current.LastInChainOfCalls ? 0 : State.Column + Current.ColumnWidth;
if (Current.Type == TT_ObjCSelectorName)
State.Stack.back().ObjCSelectorNameFound = true;
if (Current.Type == TT_LambdaLSquare)
++State.Stack.back().LambdasFound;
if (Current.Type == TT_CtorInitializerColon) {
// Indent 2 from the column, so:
// SomeClass::SomeClass()
@ -654,7 +656,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
bool BreakBeforeParameter = false;
if (Current.is(tok::l_brace) ||
Current.Type == TT_ArrayInitializerLSquare) {
if (Current.MatchingParen && Current.BlockKind == BK_Block) {
if (Current.MatchingParen && Current.BlockKind == BK_Block &&
State.Stack.back().LambdasFound <= 1) {
// If this is an l_brace starting a nested block, we pretend (wrt. to
// indentation) that we already consumed the corresponding r_brace.
// Thus, we remove all ParenStates caused by fake parentheses that end
@ -670,6 +673,10 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
// SomeFunction(a, [] {
// f(); // break
// });
//
// If we have already found more than one lambda introducers on this
// level, we opt out of this because similarity between the lambdas is
// more important.
for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i) {
assert(State.Stack.size() > 1);
if (State.Stack.size() == 1) {

View File

@ -139,7 +139,7 @@ struct ParenState {
StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
ContainsUnwrappedBuilder(0), AlignColons(true),
ObjCSelectorNameFound(false) {}
ObjCSelectorNameFound(false), LambdasFound(0) {}
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
@ -230,6 +230,12 @@ struct ParenState {
/// the same token.
bool ObjCSelectorNameFound;
/// \brief Counts the number of lambda introducers found on this level.
///
/// Not considered for memoization as it will always have the same value at
/// the same token.
unsigned LambdasFound;
bool operator<(const ParenState &Other) const {
if (Indent != Other.Indent)
return Indent < Other.Indent;

View File

@ -8171,6 +8171,16 @@ TEST_F(FormatTest, FormatsLambdas) {
" return fffffffffffffffffffffffffffffffffffffff(i * j);\n"
"};");
// Multiple lambdas in the same parentheses change indentation rules.
verifyFormat("SomeFunction([]() {\n"
" int i = 42;\n"
" return i;\n"
" },\n"
" []() {\n"
" int j = 43;\n"
" return j;\n"
" });");
// Not lambdas.
verifyFormat("constexpr char hello[]{\"hello\"};");
verifyFormat("double &operator[](int i) { return 0; }\n"