]> granicus.if.org Git - clang/commitdiff
clang-format: Add option to allow short case labels on a single line.
authorDaniel Jasper <djasper@google.com>
Wed, 10 Sep 2014 13:11:45 +0000 (13:11 +0000)
committerDaniel Jasper <djasper@google.com>
Wed, 10 Sep 2014 13:11:45 +0000 (13:11 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217501 91177308-0d34-0410-b5e6-96231b3b80d8

docs/ClangFormatStyleOptions.rst
include/clang/Format/Format.h
lib/Format/Format.cpp
unittests/Format/FormatTest.cpp

index 332fe3becdafdb4c9f832c7375110494c5bd30a7..c7981cfcdf1fb4f7211174248d6a28223055964c 100644 (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
index a6d17542e4cef4a961b8733ba1d2e8dfd2fec08c..abf505922eed07cd5334c34f8ef5420e3ad60be0 100644 (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 {
index 7e243b6e0ed605d39700120462aa8456633075cf..5b2f222bfc5679481fd4600bdf3f21eaf2be6472 100644 (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,
index 6f00acf38f383ab68382451d3548f10becb7a122..8b8aaf1b4a619cdea8d0dcbacb609e15bca25ddd 100644 (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);