jp4a50 updated this revision to Diff 505264.
jp4a50 added a comment.
Add new code sample to demonstrate behaviour of "LambdaBodyIndentation:
OuterScope"
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146042/new/
https://reviews.llvm.org/D146042
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21914,60 +21914,61 @@
LLVMWithBeforeLambdaBody);
// Lambdas with different indentation styles.
- Style = getLLVMStyleWithColumns(100);
- EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then(\n"
- " [this, &someVariable, someObject = "
- "std::mv(s)](std::vector<int> evaluated) mutable {\n"
- " return someObject.startAsyncAction().then(\n"
- " [this, &someVariable](AsyncActionResult result) "
- "mutable { result.processMore(); });\n"
- " });\n"
- "}\n",
- format("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then([this, &someVariable, someObject = "
- "std::mv(s)](std::vector<int> evaluated) mutable {\n"
- " return someObject.startAsyncAction().then([this, "
- "&someVariable](AsyncActionResult result) mutable {\n"
- " result.processMore();\n"
- " });\n"
- " });\n"
- "}\n",
- Style));
+ Style = getLLVMStyleWithColumns(60);
+ verifyFormat("Result doSomething(Promise promise) {\n"
+ " return promise.then(\n"
+ " [this, obj = std::move(s)](int evaluated) mutable {\n"
+ " return someObject.startAsyncAction().then(\n"
+ " [this, &obj](Result result) mutable {\n"
+ " result.processMore();\n"
+ " });\n"
+ " });\n"
+ "}\n",
+ Style);
Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope;
- verifyFormat("test() {\n"
- " ([]() -> {\n"
+ verifyFormat("Result doSomething(Promise promise) {\n"
+ " return promise.then(\n"
+ " [this, obj = std::move(s)](int bar) mutable {\n"
+ " return obj.startAsyncAction().then(\n"
+ " [this, &obj](Result result) mutable {\n"
+ " result.processMore();\n"
+ " });\n"
+ " });\n"
+ "}\n",
+ Style);
+ verifyFormat("void test() {\n"
+ " ([]() -> auto {\n"
" int b = 32;\n"
" return 3;\n"
" }).foo();\n"
"}",
Style);
- verifyFormat("test() {\n"
- " []() -> {\n"
+ verifyFormat("void test() {\n"
+ " []() -> auto {\n"
" int b = 32;\n"
" return 3;\n"
" }\n"
"}",
Style);
- verifyFormat("std::sort(v.begin(), v.end(),\n"
- " [](const auto &someLongArgumentName, const auto "
- "&someOtherLongArgumentName) {\n"
- " return someLongArgumentName.someMemberVariable < "
- "someOtherLongArgumentName.someMemberVariable;\n"
- "});",
+ verifyFormat("void test() {\n"
+ " std::sort(v.begin(), v.end(),\n"
+ " [](const auto &foo, const auto &bar) {\n"
+ " return foo.baz < bar.baz;\n"
+ " });\n"
+ "}\n",
Style);
- verifyFormat("test() {\n"
+ verifyFormat("void test() {\n"
" (\n"
- " []() -> {\n"
- " int b = 32;\n"
- " return 3;\n"
- " },\n"
+ " []() -> auto {\n"
+ " int b = 32;\n"
+ " return 3;\n"
+ " },\n"
" foo, bar)\n"
" .foo();\n"
"}",
Style);
- verifyFormat("test() {\n"
- " ([]() -> {\n"
+ verifyFormat("void test() {\n"
+ " ([]() -> auto {\n"
" int b = 32;\n"
" return 3;\n"
" })\n"
@@ -21975,54 +21976,82 @@
" .bar();\n"
"}",
Style);
- EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then(\n"
- " [this, &someVariable, someObject = "
- "std::mv(s)](std::vector<int> evaluated) mutable {\n"
- " return someObject.startAsyncAction().then(\n"
- " [this, &someVariable](AsyncActionResult result) mutable { "
- "result.processMore(); });\n"
- " });\n"
- "}\n",
- format("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then([this, &someVariable, someObject = "
- "std::mv(s)](std::vector<int> evaluated) mutable {\n"
- " return someObject.startAsyncAction().then([this, "
- "&someVariable](AsyncActionResult result) mutable {\n"
- " result.processMore();\n"
- " });\n"
- " });\n"
- "}\n",
- Style));
- EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then([this, &someVariable] {\n"
- " return someObject.startAsyncAction().then(\n"
- " [this, &someVariable](AsyncActionResult result) mutable { "
- "result.processMore(); });\n"
- " });\n"
- "}\n",
- format("SomeResult doSomething(SomeObject promise) {\n"
- " return promise.then([this, &someVariable] {\n"
- " return someObject.startAsyncAction().then([this, "
- "&someVariable](AsyncActionResult result) mutable {\n"
- " result.processMore();\n"
- " });\n"
- " });\n"
- "}\n",
- Style));
- Style = getGoogleStyle();
- Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope;
- EXPECT_EQ("#define A \\\n"
- " [] { \\\n"
- " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n"
- " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n"
- " }",
- format("#define A [] { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n"
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); }",
- Style));
- // TODO: The current formatting has a minor issue that's not worth fixing
- // right now whereby the closing brace is indented relative to the signature
- // instead of being aligned. This only happens with macros.
+ verifyFormat("void foo() {\n"
+ " aFunction(1, b(c(foo, bar, baz, [](d) {\n"
+ " auto f = e(d);\n"
+ " return f;\n"
+ " })));\n"
+ "}\n",
+ Style);
+ Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
+ verifyFormat("void foo() {\n"
+ " aFunction(\n"
+ " 1, b(c(\n"
+ " [](d) -> Foo {\n"
+ " auto f = e(d);\n"
+ " return f;\n"
+ " },\n"
+ " foo, Bar{},\n"
+ " [] {\n"
+ " auto g = h();\n"
+ " return g;\n"
+ " },\n"
+ " baz)));\n"
+ "}\n",
+ Style);
+ verifyFormat("void foo() {\n"
+ " aFunction(1, b(c(foo, Bar{}, baz, [](d) -> Foo {\n"
+ " auto f = e(\n"
+ " foo,\n"
+ " [&] {\n"
+ " auto g = h();\n"
+ " return g;\n"
+ " },\n"
+ " qux,\n"
+ " [&] -> Bar {\n"
+ " auto i = j();\n"
+ " return i;\n"
+ " });\n"
+ " return f;\n"
+ " })));\n"
+ "}\n",
+ Style);
+ verifyFormat("#define A \\\n"
+ " [] { \\\n"
+ " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n"
+ " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n"
+ " }",
+ Style);
+ verifyFormat("Namespace::Foo::Foo(\n"
+ " LongClassName bar, AnotherLongClassName baz)\n"
+ " : baz{baz}, func{[&] {\n"
+ " auto qux = bar;\n"
+ " return aFunkyFunctionCall(qux);\n"
+ " }} {}\n",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.BeforeLambdaBody = true;
+ verifyFormat("void foo() {\n"
+ " aFunction(\n"
+ " 1, b(c(foo, Bar{}, baz,\n"
+ " [](d) -> Foo\n"
+ " {\n"
+ " auto f = e(\n"
+ " [&]\n"
+ " {\n"
+ " auto g = h();\n"
+ " return g;\n"
+ " },\n"
+ " qux,\n"
+ " [&] -> Bar\n"
+ " {\n"
+ " auto i = j();\n"
+ " return i;\n"
+ " });\n"
+ " return f;\n"
+ " })));\n"
+ "}\n",
+ Style);
}
TEST_F(FormatTest, LambdaWithLineComments) {
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -511,9 +511,10 @@
ShouldMerge = !Style.BraceWrapping.AfterClass ||
(NextLine.First->is(tok::r_brace) &&
!Style.BraceWrapping.SplitEmptyRecord);
- } if(TheLine->InPPDirective ||
- !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
- tok::kw_struct)) {
+ }
+ if (TheLine->InPPDirective ||
+ !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
+ tok::kw_struct)) {
// Try to merge a block with left brace unwrapped that wasn't yet
// covered.
ShouldMerge = !Style.BraceWrapping.AfterFunction ||
@@ -1002,17 +1003,6 @@
int AdditionalIndent =
P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
-
- if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
- P.NestedBlockIndent == P.LastSpace) {
- if (State.NextToken->MatchingParen &&
- State.NextToken->MatchingParen->is(TT_LambdaLBrace)) {
- State.Stack.pop_back();
- }
- if (LBrace->is(TT_LambdaLBrace))
- AdditionalIndent = 0;
- }
-
Penalty +=
BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
/*FixBadIndentation=*/true);
Index: clang/lib/Format/ContinuationIndenter.cpp
===================================================================
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1125,8 +1125,15 @@
Style.IndentWidth;
}
- if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block))
- return Current.NestingLevel == 0 ? State.FirstIndent : CurrentState.Indent;
+ if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) {
+ if (Current.NestingLevel == 0 ||
+ (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
+ State.NextToken->is(TT_LambdaLBrace) && State.Line &&
+ State.Line->Level != 0)) {
+ return State.FirstIndent;
+ }
+ return CurrentState.Indent;
+ }
if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
(Current.is(tok::greater) &&
(Style.Language == FormatStyle::LK_Proto ||
@@ -1830,6 +1837,11 @@
}
void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
+ if (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
+ State.NextToken->is(TT_LambdaLBrace) && State.Line &&
+ State.Line->Level != 0) {
+ State.Stack.back().NestedBlockIndent = State.FirstIndent;
+ }
unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent;
// ObjC block sometimes follow special indentation rules.
unsigned NewIndent =
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -3537,6 +3537,11 @@
return;
});
+ someMethod(someOtherMethod(
+ [](SomeReallyLongLambdaSignatureArgument foo) {
+ return;
+ }));
+
.. _Language:
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits