``ClassImpl.hpp`` would not have the main include file put on top
before any other include.
+**IndentCaseBlocks** (``bool``)
+ Indent case label blocks one level from the case label.
+
+ When ``false``, the block following the case label uses the same
+ indentation level as for the case label, treating the case label the same
+ as an if-statement.
+ When ``true``, the block gets indented as a scope block.
+
+ .. code-block:: c++
+
+ false: true:
+ switch (fool) { vs. switch (fool) {
+ case 1: { case 1:
+ bar(); {
+ } break; bar();
+ default: { }
+ plop(); break;
+ } default:
+ } {
+ plop();
+ }
+ }
+
**IndentCaseLabels** (``bool``)
Indent case labels one level from the switch statement.
When ``false``, use the same indentation level as for the switch
statement. Switch statement body is always indented one level more than
- case labels.
+ case labels (except the first block following the case label, which
+ itself indents the code - unless IndentCaseBlocks is enabled).
.. code-block:: c++
x = ( int32 )y vs. x = (int32)y
**SpacesInConditionalStatement** (``bool``)
- If ``true``, spaces will be inserted around if/for/while (and similar) conditions.
+ If ``true``, spaces will be inserted around if/for/switch/while
+ conditions.
+
+ .. code-block:: c++
+
+ true: false:
+ if ( a ) { ... } vs. if (a) { ... }
+ while ( i < 5 ) { ... } while (i < 5) { ... }
**SpacesInContainerLiterals** (``bool``)
If ``true``, spaces are inserted inside container literals (e.g.
------------
+- 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``).
+
+ .. code-block:: c++
+
+ switch (fool) { vs. switch (fool) {
+ case 1: case 1: {
+ { bar();
+ bar(); } break;
+ } default: {
+ break; plop();
+ default: }
+ { }
+ plop();
+ }
+ }
+
libclang
--------
///
/// When ``false``, use the same indentation level as for the switch
/// statement. Switch statement body is always indented one level more than
- /// case labels.
+ /// case labels (except the first block following the case label, which
+ /// itself indents the code - unless IndentCaseBlocks is enabled).
/// \code
/// false: true:
/// switch (fool) { vs. switch (fool) {
/// \endcode
bool IndentCaseLabels;
+ /// Indent case label blocks one level from the case label.
+ ///
+ /// When ``false``, the block following the case label uses the same
+ /// indentation level as for the case label, treating the case label the same
+ /// as an if-statement.
+ /// When ``true``, the block gets indented as a scope block.
+ /// \code
+ /// false: true:
+ /// switch (fool) { vs. switch (fool) {
+ /// case 1: { case 1:
+ /// bar(); {
+ /// } break; bar();
+ /// default: { }
+ /// plop(); break;
+ /// } default:
+ /// } {
+ /// plop();
+ /// }
+ /// }
+ /// \endcode
+ bool IndentCaseBlocks;
+
/// Indent goto labels.
///
/// When ``false``, goto labels are flushed left.
IncludeStyle.IncludeIsMainSourceRegex ==
R.IncludeStyle.IncludeIsMainSourceRegex &&
IndentCaseLabels == R.IndentCaseLabels &&
+ IndentCaseBlocks == R.IndentCaseBlocks &&
IndentGotoLabels == R.IndentGotoLabels &&
IndentPPDirectives == R.IndentPPDirectives &&
IndentWidth == R.IndentWidth && Language == R.Language &&
IO.mapOptional("IncludeIsMainSourceRegex",
Style.IncludeStyle.IncludeIsMainSourceRegex);
IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
+ IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
IO.mapOptional("IndentWidth", Style.IndentWidth);
LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
LLVMStyle.IndentCaseLabels = false;
+ LLVMStyle.IndentCaseBlocks = false;
LLVMStyle.IndentGotoLabels = true;
LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
LLVMStyle.IndentWrappedFunctionNames = false;
--Line->Level;
if (LeftAlignLabel)
Line->Level = 0;
- if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
+ if (!Style.IndentCaseBlocks && CommentsBeforeNextToken.empty() &&
+ FormatTok->Tok.is(tok::l_brace)) {
CompoundStatementIndenter Indenter(this, Line->Level,
Style.BraceWrapping.AfterCaseLabel,
Style.BraceWrapping.IndentBraces);
" }\n"
"}",
Style));
+ Style.IndentCaseLabels = false;
+ Style.IndentCaseBlocks = true;
+ EXPECT_EQ("switch (n)\n"
+ "{\n"
+ "case 0:\n"
+ " {\n"
+ " return false;\n"
+ " }\n"
+ "case 1:\n"
+ " break;\n"
+ "default:\n"
+ " {\n"
+ " return true;\n"
+ " }\n"
+ "}",
+ format("switch (n) {\n"
+ "case 0: {\n"
+ " return false;\n"
+ "}\n"
+ "case 1:\n"
+ " break;\n"
+ "default: {\n"
+ " return true;\n"
+ "}\n"
+ "}",
+ Style));
+ Style.IndentCaseLabels = true;
+ Style.IndentCaseBlocks = true;
+ EXPECT_EQ("switch (n)\n"
+ "{\n"
+ " case 0:\n"
+ " {\n"
+ " return false;\n"
+ " }\n"
+ " case 1:\n"
+ " break;\n"
+ " default:\n"
+ " {\n"
+ " return true;\n"
+ " }\n"
+ "}",
+ format("switch (n) {\n"
+ "case 0: {\n"
+ " return false;\n"
+ "}\n"
+ "case 1:\n"
+ " break;\n"
+ "default: {\n"
+ " return true;\n"
+ "}\n"
+ "}",
+ Style));
}
TEST_F(FormatTest, CaseRanges) {
CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
CHECK_PARSE_BOOL(DisableFormat);
CHECK_PARSE_BOOL(IndentCaseLabels);
+ CHECK_PARSE_BOOL(IndentCaseBlocks);
CHECK_PARSE_BOOL(IndentGotoLabels);
CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);