[clang-format] Add new option BeforeLambdaBody in Allman style.

This option add a line break then a lambda is inside a function call.

Reviewers : djasper, klimek, krasimir, MyDeveloperDay

Reviewed By: MyDeveloperDay

Differential Revision: https://reviews.llvm.org/D44609
This commit is contained in:
Wawha 2020-02-13 20:25:34 +01:00
parent ef7488ef20
commit fa0118e6e5
7 changed files with 680 additions and 287 deletions

View File

@ -968,6 +968,24 @@ the configuration (without a prefix: ``Auto``).
} else {
}
* ``bool BeforeLambdaBody`` Wrap lambda block.
.. code-block:: c++
true:
connect(
[]()
{
foo();
bar();
});
false:
connect([]() {
foo();
bar();
});
* ``bool IndentBraces`` Indent the wrapped braces themselves.
* ``bool SplitEmptyFunction`` If ``false``, empty function body can be put on a single line.

View File

@ -1,272 +1,291 @@
========================================
Clang 11.0.0 (In-Progress) Release Notes
========================================
.. contents::
:local:
:depth: 2
Written by the `LLVM Team <https://llvm.org/>`_
.. warning::
These are in-progress notes for the upcoming Clang 11 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
frontend, part of the LLVM Compiler Infrastructure, release 11.0.0. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
general LLVM release notes, see `the LLVM
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
releases may be downloaded from the `LLVM releases web
site <https://llvm.org/releases/>`_.
For more information about Clang or LLVM, including information about the
latest release, please see the `Clang Web Site <https://clang.llvm.org>`_ or the
`LLVM Web Site <https://llvm.org>`_.
Note that if you are reading this file from a Git checkout or the
main Clang web page, this document applies to the *next* release, not
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.
What's New in Clang 11.0.0?
===========================
Some of the major new features and improvements to Clang are listed
here. Generic improvements to Clang as a whole or to its underlying
infrastructure are described first, followed by language-specific
sections with improvements to Clang's support for those languages.
Major New Features
------------------
- ...
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ...
Non-comprehensive list of changes in this release
-------------------------------------------------
New Compiler Flags
------------------
- -fstack-clash-protection will provide a protection against the stack clash
attack for x86 architecture through automatic probing of each page of
allocated stack.
Deprecated Compiler Flags
-------------------------
The following options are deprecated and ignored. They will be removed in
future versions of Clang.
- ...
Modified Compiler Flags
-----------------------
New Pragmas in Clang
--------------------
- ...
Attribute Changes in Clang
--------------------------
- ...
Windows Support
---------------
C Language Changes in Clang
---------------------------
- ...
C11 Feature Support
^^^^^^^^^^^^^^^^^^^
...
C++ Language Changes in Clang
-----------------------------
- Clang now implements a restriction on giving non-C-compatible anonymous
structs a typedef name for linkage purposes, as described in C++ committee
paper `P1766R1 <http://wg21.link/p1766r1>`. This paper was adopted by the
C++ committee as a Defect Report resolution, so it is applied retroactively
to all C++ standard versions. This affects code such as:
.. code-block:: c++
typedef struct {
int f() { return 0; }
} S;
Previous versions of Clang rejected some constructs of this form
(specifically, where the linkage of the type happened to be computed
before the parser reached the typedef name); those cases are still rejected
in Clang 11. In addition, cases that previous versions of Clang did not
reject now produce an extension warning. This warning can be disabled with
the warning flag ``-Wno-non-c-typedef-for-linkage``.
Affected code should be updated to provide a tag name for the anonymous
struct:
.. code-block:: c++
struct S {
int f() { return 0; }
};
If the code is shared with a C compilation (for example, if the parts that
are not C-compatible are guarded with ``#ifdef __cplusplus``), the typedef
declaration should be retained, but a tag name should still be provided:
.. code-block:: c++
typedef struct S {
int f() { return 0; }
} S;
C++1z Feature Support
^^^^^^^^^^^^^^^^^^^^^
...
Objective-C Language Changes in Clang
-------------------------------------
OpenCL C Language Changes in Clang
----------------------------------
...
ABI Changes in Clang
--------------------
OpenMP Support in Clang
-----------------------
- ...
CUDA Support in Clang
---------------------
- ...
Internal API Changes
--------------------
These are major API changes that have happened since the 10.0.0 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
Build System Changes
--------------------
These are major changes to the build system that have happened since the 10.0.0
release of Clang. Users of the build system should adjust accordingly.
- ...
AST Matchers
------------
- ...
clang-format
------------
- Option ``IndentCaseBlocks`` has been added to support treating the block
following a switch case label as a scope block which gets indented itself.
It helps avoid having the closing bracket align with the switch statement's
closing bracket (when ``IndentCaseLabels`` is ``false``).
- Option ``ObjCBreakBeforeNestedBlockParam`` has been added to optionally apply
linebreaks for function arguments declarations before nested blocks.
.. code-block:: c++
switch (fool) { vs. switch (fool) {
case 1: case 1: {
{ bar();
bar(); } break;
} default: {
break; plop();
default: }
{ }
plop();
}
}
- Option ``InsertTrailingCommas`` can be set to ``TCS_Wrapped`` to insert
trailing commas in container literals (arrays and objects) that wrap across
multiple lines. It is currently only available for JavaScript and disabled by
default (``TCS_None``).
libclang
--------
- ...
Static Analyzer
---------------
- ...
.. _release-notes-ubsan:
Undefined Behavior Sanitizer (UBSan)
------------------------------------
Core Analysis Improvements
==========================
- ...
New Issues Found
================
- ...
Python Binding Changes
----------------------
The following methods have been added:
- ...
Significant Known Problems
==========================
Additional Information
======================
A wide variety of additional information is available on the `Clang web
page <https://clang.llvm.org/>`_. The web page contains versions of the
API documentation which are up-to-date with the Subversion version of
the source code. You can access versions of these documents specific to
this release by going into the "``clang/docs/``" directory in the Clang
tree.
If you have any questions or comments about Clang, please feel free to
contact us via the `mailing
list <https://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
========================================
Clang 11.0.0 (In-Progress) Release Notes
========================================
.. contents::
:local:
:depth: 2
Written by the `LLVM Team <https://llvm.org/>`_
.. warning::
These are in-progress notes for the upcoming Clang 11 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
frontend, part of the LLVM Compiler Infrastructure, release 11.0.0. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
general LLVM release notes, see `the LLVM
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
releases may be downloaded from the `LLVM releases web
site <https://llvm.org/releases/>`_.
For more information about Clang or LLVM, including information about the
latest release, please see the `Clang Web Site <https://clang.llvm.org>`_ or the
`LLVM Web Site <https://llvm.org>`_.
Note that if you are reading this file from a Git checkout or the
main Clang web page, this document applies to the *next* release, not
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.
What's New in Clang 11.0.0?
===========================
Some of the major new features and improvements to Clang are listed
here. Generic improvements to Clang as a whole or to its underlying
infrastructure are described first, followed by language-specific
sections with improvements to Clang's support for those languages.
Major New Features
------------------
- ...
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ...
Non-comprehensive list of changes in this release
-------------------------------------------------
New Compiler Flags
------------------
- -fstack-clash-protection will provide a protection against the stack clash
attack for x86 architecture through automatic probing of each page of
allocated stack.
Deprecated Compiler Flags
-------------------------
The following options are deprecated and ignored. They will be removed in
future versions of Clang.
- ...
Modified Compiler Flags
-----------------------
New Pragmas in Clang
--------------------
- ...
Attribute Changes in Clang
--------------------------
- ...
Windows Support
---------------
C Language Changes in Clang
---------------------------
- ...
C11 Feature Support
^^^^^^^^^^^^^^^^^^^
...
C++ Language Changes in Clang
-----------------------------
- Clang now implements a restriction on giving non-C-compatible anonymous
structs a typedef name for linkage purposes, as described in C++ committee
paper `P1766R1 <http://wg21.link/p1766r1>`. This paper was adopted by the
C++ committee as a Defect Report resolution, so it is applied retroactively
to all C++ standard versions. This affects code such as:
.. code-block:: c++
typedef struct {
int f() { return 0; }
} S;
Previous versions of Clang rejected some constructs of this form
(specifically, where the linkage of the type happened to be computed
before the parser reached the typedef name); those cases are still rejected
in Clang 11. In addition, cases that previous versions of Clang did not
reject now produce an extension warning. This warning can be disabled with
the warning flag ``-Wno-non-c-typedef-for-linkage``.
Affected code should be updated to provide a tag name for the anonymous
struct:
.. code-block:: c++
struct S {
int f() { return 0; }
};
If the code is shared with a C compilation (for example, if the parts that
are not C-compatible are guarded with ``#ifdef __cplusplus``), the typedef
declaration should be retained, but a tag name should still be provided:
.. code-block:: c++
typedef struct S {
int f() { return 0; }
} S;
C++1z Feature Support
^^^^^^^^^^^^^^^^^^^^^
...
Objective-C Language Changes in Clang
-------------------------------------
OpenCL C Language Changes in Clang
----------------------------------
...
ABI Changes in Clang
--------------------
OpenMP Support in Clang
-----------------------
- ...
CUDA Support in Clang
---------------------
- ...
Internal API Changes
--------------------
These are major API changes that have happened since the 10.0.0 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
Build System Changes
--------------------
These are major changes to the build system that have happened since the 10.0.0
release of Clang. Users of the build system should adjust accordingly.
- ...
AST Matchers
------------
- ...
clang-format
------------
- Option ``IndentCaseBlocks`` has been added to support treating the block
following a switch case label as a scope block which gets indented itself.
It helps avoid having the closing bracket align with the switch statement's
closing bracket (when ``IndentCaseLabels`` is ``false``).
- Option ``ObjCBreakBeforeNestedBlockParam`` has been added to optionally apply
linebreaks for function arguments declarations before nested blocks.
.. code-block:: c++
switch (fool) { vs. switch (fool) {
case 1: case 1: {
{ bar();
bar(); } break;
} default: {
break; plop();
default: }
{ }
plop();
}
}
- Option ``InsertTrailingCommas`` can be set to ``TCS_Wrapped`` to insert
trailing commas in container literals (arrays and objects) that wrap across
multiple lines. It is currently only available for JavaScript and disabled by
default (``TCS_None``).
- Option ``BraceWrapping.BeforeLambdaBody`` has been added to manage lambda
line break inside function parameter call in Allman style.
.. code-block:: c++
true:
connect(
[]()
{
foo();
bar();
});
false:
connect([]() {
foo();
bar();
});
libclang
--------
- ...
Static Analyzer
---------------
- ...
.. _release-notes-ubsan:
Undefined Behavior Sanitizer (UBSan)
------------------------------------
Core Analysis Improvements
==========================
- ...
New Issues Found
================
- ...
Python Binding Changes
----------------------
The following methods have been added:
- ...
Significant Known Problems
==========================
Additional Information
======================
A wide variety of additional information is available on the `Clang web
page <https://clang.llvm.org/>`_. The web page contains versions of the
API documentation which are up-to-date with the Subversion version of
the source code. You can access versions of these documents specific to
this release by going into the "``clang/docs/``" directory in the Clang
tree.
If you have any questions or comments about Clang, please feel free to
contact us via the `mailing
list <https://lists.llvm.org/mailman/listinfo/cfe-dev>`_.

View File

@ -992,6 +992,23 @@ struct FormatStyle {
/// }
/// \endcode
bool BeforeElse;
/// Wrap lambda block.
/// \code
/// true:
/// connect(
/// []()
/// {
/// foo();
/// bar();
/// });
///
/// false:
/// connect([]() {
/// foo();
/// bar();
/// });
/// \endcode
bool BeforeLambdaBody;
/// Indent the wrapped braces themselves.
bool IndentBraces;
/// If ``false``, empty function body can be put on a single line.

View File

@ -329,6 +329,11 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
bool ContinuationIndenter::mustBreak(const LineState &State) {
const FormatToken &Current = *State.NextToken;
const FormatToken &Previous = *Current.Previous;
if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore &&
Current.is(TT_LambdaLBrace)) {
auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack);
return (LambdaBodyLength > getColumnLimit(State));
}
if (Current.MustBreakBefore || Current.is(TT_InlineASMColon))
return true;
if (State.Stack.back().BreakBeforeClosingBrace &&
@ -1081,6 +1086,18 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
return State.Stack.back().Indent;
}
static bool hasNestedBlockInlined(const FormatToken *Previous,
const FormatToken &Current,
const FormatStyle &Style) {
if (Previous->isNot(tok::l_paren))
return true;
if (Previous->ParameterCount > 1)
return true;
// Also a nested block if contains a lambda inside function with 1 parameter
return (Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare));
}
unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
bool DryRun, bool Newline) {
assert(State.Stack.size());
@ -1183,8 +1200,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) &&
!Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
State.Stack.back().NestedBlockInlined =
!Newline &&
(Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1);
!Newline && hasNestedBlockInlined(Previous, Current, Style);
}
moveStatePastFakeLParens(State, Newline);
@ -1421,7 +1437,21 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
State.Stack.back().HasMultipleNestedBlocks = (Current.BlockParameterCount > 1);
if (Style.BraceWrapping.BeforeLambdaBody &&
Current.Next != nullptr && Current.Tok.is(tok::l_paren)) {
// Search for any parameter that is a lambda
FormatToken const *next = Current.Next;
while (next != nullptr) {
if (next->is(TT_LambdaLSquare)) {
State.Stack.back().HasMultipleNestedBlocks = true;
break;
}
next = next->Next;
}
}
State.Stack.back().IsInsideObjCArrayLiteral =
Current.is(TT_ArrayInitializerLSquare) && Current.Previous &&
Current.Previous->is(tok::at);

View File

@ -581,6 +581,7 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
@ -668,8 +669,8 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
false, false, false,
false, false, false,
false, false, false,
false, true, true,
true};
false, false, true,
true, true};
switch (Style.BreakBeforeBraces) {
case FormatStyle::BS_Linux:
Expanded.BraceWrapping.AfterClass = true;
@ -717,14 +718,15 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.AfterExternBlock = true;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
Expanded.BraceWrapping.BeforeLambdaBody = true;
break;
case FormatStyle::BS_GNU:
Expanded.BraceWrapping = {true, true, FormatStyle::BWACS_Always,
true, true, true,
true, true, true,
true, true, true,
true, true, true,
true};
Expanded.BraceWrapping = {true, true, FormatStyle::BWACS_Always,
true, true, true,
true, true, true,
true, true, true,
false, true, true,
true, true};
break;
case FormatStyle::BS_WebKit:
Expanded.BraceWrapping.AfterFunction = true;
@ -768,8 +770,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
false, false, false,
false, false, false,
false, false, false,
false, true, true,
true};
false, false, true,
true, true};
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;

View File

@ -3122,6 +3122,56 @@ static bool isAllmanBrace(const FormatToken &Tok) {
!Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
}
// Returns 'true' if 'Tok' is an function argument.
static bool IsFunctionArgument(const FormatToken &Tok) {
return Tok.MatchingParen && Tok.MatchingParen->Next &&
Tok.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren);
}
static bool
isItAnEmptyLambdaAllowed(const FormatToken &Tok,
FormatStyle::ShortLambdaStyle ShortLambdaOption) {
return Tok.Children.empty() && ShortLambdaOption != FormatStyle::SLS_None;
}
static bool
isItAInlineLambdaAllowed(const FormatToken &Tok,
FormatStyle::ShortLambdaStyle ShortLambdaOption) {
return (ShortLambdaOption == FormatStyle::SLS_Inline &&
IsFunctionArgument(Tok)) ||
(ShortLambdaOption == FormatStyle::SLS_All);
}
static bool isOneChildWithoutMustBreakBefore(const FormatToken &Tok) {
if (Tok.Children.size() != 1)
return false;
FormatToken *curElt = Tok.Children[0]->First;
while (curElt) {
if (curElt->MustBreakBefore)
return false;
curElt = curElt->Next;
}
return true;
}
static bool
isAllmanLambdaBrace(const FormatToken &Tok) {
return (Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
!Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral));
}
static bool
isAllmanBraceIncludedBreakableLambda(const FormatToken &Tok,
FormatStyle::ShortLambdaStyle ShortLambdaOption) {
if (!isAllmanLambdaBrace(Tok))
return false;
if (isItAnEmptyLambdaAllowed(Tok, ShortLambdaOption))
return false;
return !isItAInlineLambdaAllowed(Tok, ShortLambdaOption) ||
!isOneChildWithoutMustBreakBefore(Tok);
}
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
const FormatToken &Right) {
const FormatToken &Left = *Right.Previous;
@ -3257,6 +3307,14 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
}
if (Right.is(TT_InlineASMBrace))
return Right.HasUnescapedNewline;
auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
if (Style.BraceWrapping.BeforeLambdaBody &&
(isAllmanBraceIncludedBreakableLambda(Left, ShortLambdaOption) ||
isAllmanBraceIncludedBreakableLambda(Right, ShortLambdaOption))) {
return true;
}
if (isAllmanBrace(Left) || isAllmanBrace(Right))
return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
(Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
@ -3268,8 +3326,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
if (Left.is(TT_LambdaLBrace)) {
if (Left.MatchingParen && Left.MatchingParen->Next &&
Left.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren) &&
if (IsFunctionArgument(Left) &&
Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline)
return false;
@ -3667,11 +3724,21 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
(Left.is(tok::r_square) && Right.is(TT_AttributeSquare)))
return false;
auto ShortLambdaOption = Style.AllowShortLambdasOnASingleLine;
if (Style.BraceWrapping.BeforeLambdaBody) {
if (isAllmanLambdaBrace(Left))
return !isItAnEmptyLambdaAllowed(Left, ShortLambdaOption);
if (isAllmanLambdaBrace(Right))
return !isItAnEmptyLambdaAllowed(Right, ShortLambdaOption);
}
return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
tok::kw_class, tok::kw_struct, tok::comment) ||
Right.isMemberAccess() ||
Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
tok::colon, tok::l_square, tok::at) ||
(Style.BraceWrapping.BeforeLambdaBody && Right.is(tok::l_brace)) ||
(Left.is(tok::r_paren) &&
Right.isOneOf(tok::identifier, tok::kw_const)) ||
(Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||

View File

@ -12673,6 +12673,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
@ -13962,6 +13963,245 @@ TEST_F(FormatTest, FormatsLambdas) {
"function([]() { return b; }, a)", MergeInline);
verifyFormat("function(a, []() { return b; })",
"function(a, []() { return b; })", MergeInline);
// Check option "BraceWrapping.BeforeLambdaBody" and different state of
// AllowShortLambdasOnASingleLine
FormatStyle LLVMWithBeforeLambdaBody = getLLVMStyle();
LLVMWithBeforeLambdaBody.BreakBeforeBraces = FormatStyle::BS_Custom;
LLVMWithBeforeLambdaBody.BraceWrapping.BeforeLambdaBody = true;
LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine =
FormatStyle::ShortLambdaStyle::SLS_None;
verifyFormat("FctWithOneNestedLambdaInline_SLS_None(\n"
" []()\n"
" {\n"
" return 17;\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdaEmpty_SLS_None(\n"
" []()\n"
" {\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("auto fct_SLS_None = []()\n"
"{\n"
" return 17;\n"
"};",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_None(\n"
" []()\n"
" {\n"
" return Call(\n"
" []()\n"
" {\n"
" return 17;\n"
" });\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("void Fct()\n"
"{\n"
" return {[]()\n"
" {\n"
" return 17;\n"
" }};\n"
"}",
LLVMWithBeforeLambdaBody);
LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine =
FormatStyle::ShortLambdaStyle::SLS_Empty;
verifyFormat("FctWithOneNestedLambdaInline_SLS_Empty(\n"
" []()\n"
" {\n"
" return 17;\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdaEmpty_SLS_Empty([]() {});",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdaEmptyInsideAVeryVeryVeryVeryVeryVeryVeryL"
"ongFunctionName_SLS_Empty(\n"
" []() {});",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithMultipleParams_SLS_Empty(A, B,\n"
" []()\n"
" {\n"
" return 17;\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("auto fct_SLS_Empty = []()\n"
"{\n"
" return 17;\n"
"};",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_Empty(\n"
" []()\n"
" {\n"
" return Call([]() {});\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_Empty(A,\n"
" []()\n"
" {\n"
" return Call([]() {});\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_Empty(\n"
" []()\n"
" {\n"
" return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n"
" AndShouldNotBeConsiderAsInline,\n"
" LambdaBodyMustBeBreak);\n"
" });",
LLVMWithBeforeLambdaBody);
LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine =
FormatStyle::ShortLambdaStyle::SLS_Inline;
verifyFormat("FctWithOneNestedLambdaInline_SLS_Inline([]() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdaEmpty_SLS_Inline([]() {});",
LLVMWithBeforeLambdaBody);
verifyFormat("auto fct_SLS_Inline = []()\n"
"{\n"
" return 17;\n"
"};",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_Inline([]() { return Call([]() { return "
"17; }); });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_Inline(\n"
" []()\n"
" {\n"
" return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n"
" AndShouldNotBeConsiderAsInline,\n"
" LambdaBodyMustBeBreak);\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithMultipleParams_SLS_Inline("
"VeryLongParameterThatShouldAskToBeOnMultiLine,\n"
" []() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithMultipleParams_SLS_Inline(FirstParam, []() { return 17; });",
LLVMWithBeforeLambdaBody);
LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine =
FormatStyle::ShortLambdaStyle::SLS_All;
verifyFormat("FctWithOneNestedLambdaInline_SLS_All([]() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdaEmpty_SLS_All([]() {});",
LLVMWithBeforeLambdaBody);
verifyFormat("auto fct_SLS_All = []() { return 17; };",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneParam_SLS_All(\n"
" []()\n"
" {\n"
" // A cool function...\n"
" return 43;\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithMultipleParams_SLS_All("
"VeryLongParameterThatShouldAskToBeOnMultiLine,\n"
" []() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithMultipleParams_SLS_All(A, []() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithMultipleParams_SLS_All(A, B, []() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_All(\n"
" []()\n"
" {\n"
" return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n"
" AndShouldNotBeConsiderAsInline,\n"
" LambdaBodyMustBeBreak);\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"auto fct_SLS_All = []()\n"
"{\n"
" return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n"
" AndShouldNotBeConsiderAsInline,\n"
" LambdaBodyMustBeBreak);\n"
"};",
LLVMWithBeforeLambdaBody);
LLVMWithBeforeLambdaBody.BinPackParameters = false;
verifyFormat("FctAllOnSameLine_SLS_All([]() { return S; }, Fst, Second);",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_All([]() { return SomeValueNotSoLong; },\n"
" FirstParam,\n"
" SecondParam,\n"
" ThirdParam,\n"
" FourthParam);",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithLongLineInLambda_SLS_All(\n"
" []() { return "
"SomeValueVeryVeryVeryVeryVeryVeryVeryVeryVeryLong; },\n"
" FirstParam,\n"
" SecondParam,\n"
" ThirdParam,\n"
" FourthParam);",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_All(FirstParam,\n"
" SecondParam,\n"
" ThirdParam,\n"
" FourthParam,\n"
" []() { return SomeValueNotSoLong; });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithLongLineInLambda_SLS_All(\n"
" []()\n"
" {\n"
" return "
"HereAVeryLongLineThatWillBeFormattedOnMultipleLineAndShouldNotB"
"eConsiderAsInline;\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"FctWithLongLineInLambda_SLS_All(\n"
" []()\n"
" {\n"
" return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n"
" AndShouldNotBeConsiderAsInline,\n"
" LambdaBodyMustBeBreak);\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithTwoParams_SLS_All(\n"
" []()\n"
" {\n"
" // A cool function...\n"
" return 43;\n"
" },\n"
" 87);",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithTwoParams_SLS_All([]() { return 43; }, 87);",
LLVMWithBeforeLambdaBody);
verifyFormat("FctWithOneNestedLambdas_SLS_All([]() { return 17; });",
LLVMWithBeforeLambdaBody);
verifyFormat(
"TwoNestedLambdas_SLS_All([]() { return Call([]() { return 17; }); });",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_All([]() { return Call([]() { return 17; "
"}); }, x);",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_All(\n"
" []()\n"
" {\n"
" // A cool function...\n"
" return Call([]() { return 17; });\n"
" });",
LLVMWithBeforeLambdaBody);
verifyFormat("TwoNestedLambdas_SLS_All(\n"
" []()\n"
" {\n"
" return Call(\n"
" []()\n"
" {\n"
" // A cool function...\n"
" return 17;\n"
" });\n"
" });",
LLVMWithBeforeLambdaBody);
}
TEST_F(FormatTest, EmptyLinesInLambdas) {