From: Daniel Jasper Date: Thu, 5 Sep 2013 10:04:31 +0000 (+0000) Subject: clang-format: Fix parsing and indenting lambdas. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ac2c974bc64d3767ad5e39451a874c50b3004b3a;p=clang clang-format: Fix parsing and indenting lambdas. Before: void f() { other(x.begin(), x.end(), // [&](int, int) { return 1; }); } After: void f() { other(x.begin(), x.end(), // [&](int, int) { return 1; }); } git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190039 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index f9219cbaf7..c47d799f44 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -267,7 +267,8 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, State.Column = State.Stack.back().Indent; State.Stack.back().ColonPos = State.Column + Current.CodePointCount; } - } else if (Current.is(tok::l_square) && Current.Type != TT_ObjCMethodExpr) { + } else if (Current.is(tok::l_square) && Current.Type != TT_ObjCMethodExpr && + Current.Type != TT_LambdaLSquare) { if (State.Stack.back().StartOfArraySubscripts != 0) State.Column = State.Stack.back().StartOfArraySubscripts; else diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 9e17ee9f6c..46baab4aab 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -201,7 +201,8 @@ private: while (CurrentToken != NULL) { if (CurrentToken->is(tok::r_square)) { - if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren)) { + if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) && + Left->Type == TT_ObjCMethodExpr) { // An ObjC method call is rarely followed by an open parenthesis. // FIXME: Do we incorrectly label ":" with this? StartsObjCMethodExpr = false; diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 4e70625f5b..13b9847527 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -676,27 +676,22 @@ void UnwrappedLineParser::parseStructuralElement() { void UnwrappedLineParser::tryToParseLambda() { assert(FormatTok->is(tok::l_square)); FormatToken &LSquare = *FormatTok; - if (!tryToParseLambdaIntroducer()) { + if (!tryToParseLambdaIntroducer()) return; - } - if (FormatTok->is(tok::l_paren)) { - parseParens(); - } while (FormatTok->isNot(tok::l_brace)) { switch (FormatTok->Tok.getKind()) { - case tok::l_brace: - break; - case tok::l_paren: - parseParens(); - break; - case tok::semi: - case tok::equal: - case tok::eof: - return; - default: - nextToken(); - break; + case tok::l_brace: + break; + case tok::l_paren: + parseParens(); + break; + case tok::identifier: + case tok::kw_mutable: + nextToken(); + break; + default: + return; } } LSquare.Type = TT_LambdaLSquare; @@ -707,23 +702,33 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() { nextToken(); if (FormatTok->is(tok::equal)) { nextToken(); - if (FormatTok->is(tok::r_square)) return true; - if (FormatTok->isNot(tok::comma)) return false; + if (FormatTok->is(tok::r_square)) { + nextToken(); + return true; + } + if (FormatTok->isNot(tok::comma)) + return false; nextToken(); } else if (FormatTok->is(tok::amp)) { nextToken(); - if (FormatTok->is(tok::r_square)) return true; + if (FormatTok->is(tok::r_square)) { + nextToken(); + return true; + } if (!FormatTok->isOneOf(tok::comma, tok::identifier)) { return false; } - if (FormatTok->is(tok::comma)) nextToken(); + if (FormatTok->is(tok::comma)) + nextToken(); } else if (FormatTok->is(tok::r_square)) { nextToken(); return true; } do { - if (FormatTok->is(tok::amp)) nextToken(); - if (!FormatTok->isOneOf(tok::identifier, tok::kw_this)) return false; + if (FormatTok->is(tok::amp)) + nextToken(); + if (!FormatTok->isOneOf(tok::identifier, tok::kw_this)) + return false; nextToken(); if (FormatTok->is(tok::comma)) { nextToken(); @@ -836,6 +841,9 @@ void UnwrappedLineParser::parseParens() { case tok::r_brace: // A "}" inside parenthesis is an error if there wasn't a matching "{". return; + case tok::l_square: + tryToParseLambda(); + break; case tok::l_brace: { if (!tryToParseBracedList()) { parseChildBlock(); @@ -1195,7 +1203,7 @@ static void printDebugInfo(const UnwrappedLine &Line, StringRef Prefix = "") { for (std::list::const_iterator I = Line.Tokens.begin(), E = Line.Tokens.end(); I != E; ++I) { - llvm::dbgs() << I->Tok->Tok.getName() << " "; + llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] "; } for (std::list::const_iterator I = Line.Tokens.begin(), E = Line.Tokens.end(); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 3dfcd7473d..5e5a579ddb 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -6295,12 +6295,10 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("void f() {\n" " other(x.begin(), x.end(), [&](int, int) { return 1; });\n" "}\n"); - // FIXME: The formatting is incorrect; this test currently checks that - // parsing of the unwrapped lines doesn't regress. verifyFormat("void f() {\n" " other(x.begin(), //\n" " x.end(), //\n" - " [&](int, int) { return 1; });\n" + " [&](int, int) { return 1; });\n" "}\n"); }