clang-format: Add option to allow short case labels on a single line.

On a single line:
  switch (a) {
  case 1: x = 1; return;
  case 2: x = 2; return;
  default: break;
  }

Not on a single line:
  switch (a) {
  case 1:
    x = 1;
    return;
  case 2:
    x = 2;
    return;
  default:
    break;
  }

This partly addresses llvm.org/PR16535. In the long run, we probably want to
lay these out in columns.

llvm-svn: 217501
This commit is contained in:
Daniel Jasper 2014-09-10 13:11:45 +00:00
parent e7b92f0e81
commit b87899b567
4 changed files with 85 additions and 6 deletions

View File

@ -148,6 +148,9 @@ the configuration (without a prefix: ``Auto``).
E.g., this allows ``if (a) { return; }`` to be put on a single line.
**AllowShortCaseLabelsOnASingleLine** (``bool``)
If ``true``, short case labels will be contracted to a single line.
**AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``)
Dependent on the value, ``int f() { return 0; }`` can be put
on a single line.
@ -257,7 +260,7 @@ the configuration (without a prefix: ``Auto``).
**DerivePointerAlignment** (``bool``)
If ``true``, analyze the formatted file for the most common
alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback.
alignment of & and *. ``PointerAlignment`` is then used only as fallback.
**DisableFormat** (``bool``)
Disables formatting at all.
@ -374,6 +377,9 @@ the configuration (without a prefix: ``Auto``).
Align pointer in the middle.
**SpaceAfterCStyleCast** (``bool``)
If ``true``, a space may be inserted after C style casts.
**SpaceBeforeAssignmentOperators** (``bool``)
If ``false``, spaces will be removed before assignment operators.
@ -411,9 +417,6 @@ the configuration (without a prefix: ``Auto``).
**SpacesInCStyleCastParentheses** (``bool``)
If ``true``, spaces may be inserted into C style casts.
**SpaceAfterCStyleCast** (``bool``)
If ``true``, a space may be inserted after C style casts.
**SpacesInContainerLiterals** (``bool``)
If ``true``, spaces are inserted inside container literals (e.g.
ObjC and Javascript array and dict literals).
@ -422,8 +425,7 @@ the configuration (without a prefix: ``Auto``).
If ``true``, spaces will be inserted after '(' and before ')'.
**SpacesInSquareBrackets** (``bool``)
If ``true``, spaces will be inserted after '[' and before ']' in array
declarations and element access expressions, but not in lambdas.
If ``true``, spaces will be inserted after '[' and before ']'.
**Standard** (``LanguageStandard``)
Format compatible with this standard, e.g. use

View File

@ -195,6 +195,9 @@ struct FormatStyle {
/// single line.
bool AllowShortLoopsOnASingleLine;
/// \brief If \c true, short case labels will be contracted to a single line.
bool AllowShortCaseLabelsOnASingleLine;
/// \brief Different styles for merging short functions containing at most one
/// statement.
enum ShortFunctionStyle {

View File

@ -167,6 +167,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowAllParametersOfDeclarationOnNextLine);
IO.mapOptional("AllowShortBlocksOnASingleLine",
Style.AllowShortBlocksOnASingleLine);
IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
Style.AllowShortCaseLabelsOnASingleLine);
IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
@ -313,6 +315,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
LLVMStyle.AllowShortBlocksOnASingleLine = false;
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = false;
@ -642,6 +645,11 @@ public:
? tryMergeSimpleControlStatement(I, E, Limit)
: 0;
}
if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {
return Style.AllowShortCaseLabelsOnASingleLine
? tryMergeShortCaseLabels(I, E, Limit)
: 0;
}
if (TheLine->InPPDirective &&
(TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
return tryMergeSimplePPDirective(I, E, Limit);
@ -694,6 +702,30 @@ private:
return 1;
}
unsigned tryMergeShortCaseLabels(
SmallVectorImpl<AnnotatedLine *>::const_iterator I,
SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
if (Limit == 0 || I + 1 == E ||
I[1]->First->isOneOf(tok::kw_case, tok::kw_default))
return 0;
unsigned NumStmts = 0;
unsigned Length = 0;
for (; NumStmts < 3; ++NumStmts) {
if (I + 1 + NumStmts == E)
break;
const AnnotatedLine *Line = I[1 + NumStmts];
if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
break;
if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
tok::kw_while))
return 0;
Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
}
if (NumStmts == 0 || NumStmts == 3 || Length > Limit)
return 0;
return NumStmts;
}
unsigned
tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
SmallVectorImpl<AnnotatedLine *>::const_iterator E,

View File

@ -700,6 +700,47 @@ TEST_F(FormatTest, CaseRanges) {
"}");
}
TEST_F(FormatTest, ShortCaseLabels) {
FormatStyle Style = getLLVMStyle();
Style.AllowShortCaseLabelsOnASingleLine = true;
verifyFormat("switch (a) {\n"
"case 1: x = 1; break;\n"
"case 2: return;\n"
"case 3:\n"
"case 4:\n"
"case 5: return;\n"
"default: y = 1; break;\n"
"}",
Style);
verifyFormat("switch (a) {\n"
"case 1: {\n"
"}\n"
"case 2: {\n"
" return;\n"
"}\n"
"case 3: {\n"
" x = 1;\n"
" return;\n"
"}\n"
"case 4:\n"
" if (x)\n"
" return;\n"
"}",
Style);
Style.ColumnLimit = 21;
verifyFormat("switch (a) {\n"
"case 1: x = 1; break;\n"
"case 2: return;\n"
"case 3:\n"
"case 4:\n"
"case 5: return;\n"
"default:\n"
" y = 1;\n"
" break;\n"
"}",
Style);
}
TEST_F(FormatTest, FormatsLabels) {
verifyFormat("void f() {\n"
" some_code();\n"
@ -8316,6 +8357,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
CHECK_PARSE_BOOL(AlwaysBreakAfterDefinitionReturnType);