forked from OSchip/llvm-project
[clang-format] Change heuristic for locating lambda template arguments
Previously, the heuristic was simply to look for template argument- specific keywords, such as typename, class, template and auto that are preceded by a left angle bracket <. This changes the heuristic to instead look for a left angle bracket < preceded by a right square bracket ], since according to the C++ grammar, the template arguments must *directly* follow the introducer. (This sort of check might just end up being *too* aggressive) This patch also adds a bunch more token annotator tests for lambdas, specifically for some of the stranger forms of lambdas now allowed as of C++20 or soon-to-be-allowed as part of C++23. Fixes https://github.com/llvm/llvm-project/issues/57093 This does NOT resolve the FIXME regarding explicit template lists, but perhaps it gets closer Differential Revision: https://reviews.llvm.org/D132295
This commit is contained in:
parent
2adf241592
commit
247613548b
|
@ -2210,21 +2210,21 @@ bool UnwrappedLineParser::tryToParseLambda() {
|
|||
case tok::l_square:
|
||||
parseSquare();
|
||||
break;
|
||||
case tok::less:
|
||||
assert(FormatTok->Previous);
|
||||
if (FormatTok->Previous->is(tok::r_square))
|
||||
InTemplateParameterList = true;
|
||||
nextToken();
|
||||
break;
|
||||
case tok::kw_auto:
|
||||
case tok::kw_class:
|
||||
case tok::kw_template:
|
||||
case tok::kw_typename:
|
||||
assert(FormatTok->Previous);
|
||||
if (FormatTok->Previous->is(tok::less))
|
||||
InTemplateParameterList = true;
|
||||
nextToken();
|
||||
break;
|
||||
case tok::amp:
|
||||
case tok::star:
|
||||
case tok::kw_const:
|
||||
case tok::kw_constexpr:
|
||||
case tok::comma:
|
||||
case tok::less:
|
||||
case tok::greater:
|
||||
case tok::identifier:
|
||||
case tok::numeric_constant:
|
||||
|
|
|
@ -21730,6 +21730,18 @@ TEST_F(FormatTest, FormatsLambdas) {
|
|||
" g();\n"
|
||||
" }\n"
|
||||
"};\n");
|
||||
verifyFormat("auto L = []<int... T>(T...) {\n"
|
||||
" {\n"
|
||||
" f();\n"
|
||||
" g();\n"
|
||||
" }\n"
|
||||
"};");
|
||||
verifyFormat("auto L = []<Foo... T>(T...) {\n"
|
||||
" {\n"
|
||||
" f();\n"
|
||||
" g();\n"
|
||||
" }\n"
|
||||
"};");
|
||||
|
||||
// Multiple lambdas in the same parentheses change indentation rules. These
|
||||
// lambdas are forced to start on new lines.
|
||||
|
|
|
@ -809,18 +809,85 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
|
|||
|
||||
Tokens = annotate("[]() -> auto {}");
|
||||
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
|
||||
EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[]() -> auto & {}");
|
||||
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
|
||||
EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[]() -> auto * {}");
|
||||
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
|
||||
EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] {}");
|
||||
ASSERT_EQ(Tokens.size(), 5u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] noexcept {}");
|
||||
ASSERT_EQ(Tokens.size(), 6u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] -> auto {}");
|
||||
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow);
|
||||
EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <typename T> () {}");
|
||||
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <typename T> {}");
|
||||
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <typename... T> () {}");
|
||||
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <typename... T> {}");
|
||||
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <int... T> () {}");
|
||||
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <int... T> {}");
|
||||
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <Foo... T> () {}");
|
||||
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
|
||||
|
||||
Tokens = annotate("[] <Foo... T> {}");
|
||||
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
||||
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
|
||||
EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
|
||||
EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
|
||||
}
|
||||
|
||||
TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
|
||||
|
|
Loading…
Reference in New Issue