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; });
  }

llvm-svn: 190039
This commit is contained in:
Daniel Jasper 2013-09-05 10:04:31 +00:00
parent 9fe0e8dacd
commit 9a8d48b5e1
4 changed files with 37 additions and 29 deletions

View File

@ -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

View File

@ -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;

View File

@ -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<UnwrappedLineNode>::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<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
E = Line.Tokens.end();

View File

@ -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");
}