From 94096ad523611aa4c139c88ac5ec8985b46d6b1b Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 9 Apr 2014 12:08:39 +0000 Subject: [PATCH] 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; }); git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205848 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/ContinuationIndenter.cpp | 9 ++++++++- lib/Format/ContinuationIndenter.h | 8 +++++++- unittests/Format/FormatTest.cpp | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 5317fb33ff..d25ab68e39 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -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) { diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h index 9a3c118561..04e31e68b1 100644 --- a/lib/Format/ContinuationIndenter.h +++ b/lib/Format/ContinuationIndenter.h @@ -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; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index b9310abbbe..b932b274d7 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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" -- 2.40.0