I've fixed the method to do the indentation, by adapting indent in 
ContinuationIndenter::getNewLineColumn()

As far as I understand it, the indent of the content of the enumeration is 
determined by the very last statement.
In a first attempt, I looked at the current token being an identifier; though 
it was not selective enough.
Now I look at the previous token, though this worked for the current tests, it 
gives incorrect indent for the second enum-value.

Further more this introduces an issue with the breaks, where:
switch (i)
..{
case A:
..{
..}
..break;
..}

​becomes:​

​switch (i)
..{
case A:
..{
..}
break;
..}

I'm really starting to get lost in this one function call :s


http://reviews.llvm.org/D6833

Files:
  docs/ClangFormatStyleOptions.rst
  include/clang/Format/Format.h
  lib/Format/ContinuationIndenter.cpp
  lib/Format/ContinuationIndenter.h
  lib/Format/Format.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  lib/Format/UnwrappedLineParser.cpp
  unittests/Format/FormatTest.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -256,6 +256,8 @@
     Like ``Attach``, but break before function definitions, and 'else'.
   * ``BS_Allman`` (in configuration: ``Allman``)
     Always break before braces.
+  * ``BS_Whitesmiths`` (in configuration: ``Whitesmiths``)
+    Like ``Allman``, with the braces intended too.
   * ``BS_GNU`` (in configuration: ``GNU``)
     Always break before braces and add an extra level of indentation to
     braces of control statements, not to those of class, function
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -319,6 +319,8 @@
     BS_Stroustrup,
     /// Always break before braces.
     BS_Allman,
+    /// Allman style with a level of indentation before the braces
+    BS_Whitesmiths,
     /// Always break before braces and add an extra level of indentation to
     /// braces of control statements, not to those of class, function
     /// or other definitions.
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -513,9 +513,19 @@
     return std::max(State.Stack.back().LastSpace,
                     State.Stack.back().Indent + Style.ContinuationIndentWidth);

-  if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block)
+  // Start of braced block
+  if (NextNonComment->is(tok::l_brace) &&
+      NextNonComment->BlockKind == BK_Block) {
+    // Whitesmiths indents the { and } too, compared to Allman,
+    // this also needs to happen for the special parsed blocks.
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths)
+      return (Current.NestingLevel == 0 ? State.FirstIndent
+                                        : State.Stack.back().Indent) +
+             Style.IndentWidth;
     return Current.NestingLevel == 0 ? State.FirstIndent
                                      : State.Stack.back().Indent;
+  }
+  // End of braced block (or ])
   if (Current.isOneOf(tok::r_brace, tok::r_square)) {
     if (Current.closesBlockTypeList(Style))
       return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
@@ -589,6 +599,15 @@
     // Ensure that we fall back to the continuation indent width instead of
     // just flushing continuations left.
     return State.Stack.back().Indent + Style.ContinuationIndentWidth;
+
+  // Whitesmiths indents the { and } too, compared to Allman,
+  // this also needs to happen for the special parsed blocks.
+  // The content between the braces needs to no extra indent
+  if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
+    if (PreviousNonComment && PreviousNonComment->is(tok::l_brace) &&
+        PreviousNonComment->BlockKind == BK_Block)
+      return State.Stack.back().Indent - Style.IndentWidth;
+  }
   return State.Stack.back().Indent;
 }

Index: lib/Format/ContinuationIndenter.h
===================================================================
--- lib/Format/ContinuationIndenter.h
+++ lib/Format/ContinuationIndenter.h
@@ -156,7 +156,8 @@
         NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
         ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
         AlignColons(true), ObjCSelectorNameFound(false),
-        HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
+        HasMultipleNestedBlocks(false), NestedBlockInlined(false),
+        BlockNoExtraIndent(false)	{}

   /// \brief The position to which a specific parenthesis level needs to be
   /// indented.
@@ -265,6 +266,9 @@
   // "function" in JavaScript) is not wrapped to a new line.
   bool NestedBlockInlined;

+  //
+  bool BlockNoExtraIndent;
+
   bool operator<(const ParenState &Other) const {
     if (Indent != Other.Indent)
       return Indent < Other.Indent;
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -95,6 +95,7 @@
     IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
     IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
     IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
+    IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
     IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
   }
 };
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1888,6 +1888,7 @@
             Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline);
   if (isAllmanBrace(Left) || isAllmanBrace(Right))
     return Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+           Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
            Style.BreakBeforeBraces == FormatStyle::BS_GNU;
   if (Style.Language == FormatStyle::LK_Proto && Left.isNot(tok::l_brace) &&
       Right.is(TT_SelectorName))
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -135,6 +135,7 @@
     if (Limit == 0)
       return 0;
     if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+         Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
          Style.BreakBeforeBraces == FormatStyle::BS_GNU) &&
         (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine))
       return 0;
@@ -499,6 +500,13 @@
   if (PreviousLine && PreviousLine->First->isAccessSpecifier())
     Newlines = std::min(1u, Newlines);

+  if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
+    // Setting the indent level for Whitesmiths is implemented similar to
+    // Allman. e.g. Getting the indentation correct except for the { and }
+    // tokens. The correction of those tokens is done here.
+    if (RootToken.isOneOf(tok::l_brace, tok::r_brace))
+      Indent += Style.IndentWidth;
+  }
   Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent,
                                  Indent, InPPDirective &&
                                              !RootToken.HasUnescapedNewline);
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -156,7 +156,8 @@
   CompoundStatementIndenter(UnwrappedLineParser *Parser,
                             const FormatStyle &Style, unsigned &LineLevel)
       : LineLevel(LineLevel), OldLineLevel(LineLevel) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) {
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
       Parser->addUnwrappedLine();
     } else if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
       Parser->addUnwrappedLine();
@@ -441,6 +442,7 @@
   case FormatStyle::BS_Linux:
     return InitialToken.isOneOf(tok::kw_namespace, tok::kw_class);
   case FormatStyle::BS_Allman:
+  case FormatStyle::BS_Whitesmiths:
   case FormatStyle::BS_GNU:
     return true;
   default:
@@ -1115,6 +1117,7 @@
     CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
         Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
       addUnwrappedLine();
     } else {
@@ -1168,6 +1171,7 @@
     CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
         Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
         Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
       addUnwrappedLine();
@@ -1202,6 +1206,7 @@
     CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
         Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
         Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
       addUnwrappedLine();
@@ -1263,7 +1268,8 @@
   if (FormatTok->Tok.is(tok::l_brace)) {
     CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
-    if (Style.BreakBeforeBraces == FormatStyle::BS_GNU)
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU)
       addUnwrappedLine();
   } else {
     addUnwrappedLine();
@@ -1293,6 +1299,7 @@
     if (FormatTok->Tok.is(tok::kw_break)) {
       // "break;" after "}" on its own line only for BS_Allman and BS_GNU
       if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+          Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
           Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
         addUnwrappedLine();
       }
@@ -1545,6 +1552,7 @@

   if (FormatTok->Tok.is(tok::l_brace)) {
     if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths ||
         Style.BreakBeforeBraces == FormatStyle::BS_GNU)
       addUnwrappedLine();
     parseBlock(/*MustBeDeclaration=*/true);
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -2270,6 +2270,16 @@
                "  // something\n"
                "}",
                Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
+  verifyFormat("try\n"
+               "  {\n"
+               "  // something\n"
+               "  }\n"
+               "catch (...)\n"
+               "  {\n"
+               "  // something\n"
+               "  }",
+               Style);
   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
   verifyFormat("try\n"
                "  {\n"
@@ -3672,6 +3682,7 @@
   // they are not function-like.
   FormatStyle Style = getGoogleStyle();
   Style.ColumnLimit = 47;
+
   verifyFormat("void someLongFunction(\n"
                "    int someLoooooooooooooongParameter) const {\n}",
                getLLVMStyleWithColumns(47));
@@ -3723,6 +3734,13 @@
                "}",
                Style);

+  Style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) const\n"
+               "  {\n"
+               "  }",
+               Style);
+
   // Unless these are unknown annotations.
   verifyFormat("void SomeFunction(aaaaaaaaaa aaaaaaaaaaaaaaa,\n"
                "                  aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
@@ -8154,6 +8172,10 @@
                LinuxBraceStyle);
   verifyFormat("enum X {\n"
                "  Y = 0,\n"
+               "};\n",
+               LinuxBraceStyle);
+  verifyFormat("enum X {\n"
+               "  Y = 0,\n"
                "}\n",
                LinuxBraceStyle);
   verifyFormat("struct S {\n"
@@ -8320,6 +8342,11 @@
                "  Y = 0\n"
                "}\n",
                AllmanBraceStyle);
+  verifyFormat("enum X\n"
+               "{\n"
+               "  Y = 0\n"
+               "};\n",
+               AllmanBraceStyle);

   verifyFormat("@interface BSApplicationController ()\n"
                "{\n"
@@ -8418,6 +8445,230 @@
                BreakBeforeBraceShortIfs);
 }

+TEST_F(FormatTest, WhitesmithsBraceBreaking) {
+  FormatStyle WhitesmithsBraceStyle = getLLVMStyle();
+  WhitesmithsBraceStyle.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
+
+  verifyFormat("class A;\n"
+               "namespace B\n"
+               "  {\n"
+               "class C;\n"
+               "// Comment\n"
+               "class D\n"
+               "  {\n"
+               "public:\n"
+               "  D();\n"
+               "  ~D() {}\n"
+               "private:\n"
+               "  enum E\n"
+               "    {\n"
+               "    F\n"
+               "    }\n"
+               "  };\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("namespace a\n"
+               "  {\n"
+               "class A\n"
+               "  {\n"
+               "  void f()\n"
+               "    {\n"
+               "    if (true)\n"
+               "      {\n"
+               "      a();\n"
+               "      b();\n"
+               "      }\n"
+               "    }\n"
+               "  void g() { return; }\n"
+               "  };\n"
+               "struct B\n"
+               "  {\n"
+               "  int x;\n"
+               "  };\n"
+               "  }",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void f()\n"
+               "  {\n"
+               "  if (true)\n"
+               "    {\n"
+               "    a();\n"
+               "    }\n"
+               "  else if (false)\n"
+               "    {\n"
+               "    b();\n"
+               "    }\n"
+               "  else\n"
+               "    {\n"
+               "    c();\n"
+               "    }\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void f()\n"
+               "  {\n"
+               "  for (int i = 0; i < 10; ++i)\n"
+               "    {\n"
+               "    a();\n"
+               "    }\n"
+               "  while (false)\n"
+               "    {\n"
+               "    b();\n"
+               "    }\n"
+               "  do\n"
+               "    {\n"
+               "    c();\n"
+               "    }\n"
+               "  while (false)\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void f(int a)\n"
+               "  {\n"
+               "  switch (a)\n"
+               "    {\n"
+               "  case 0:\n"
+               "    break;\n"
+               "  case 1:\n"
+               "    {\n"
+               "    break;\n"
+               "    }\n"
+               "  case 2:\n"
+               "    {\n"
+               "    }\n"
+               "    break;\n"
+               "  default:\n"
+               "    break;\n"
+               "    }\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("enum X\n"
+               "  {\n"
+               "  Y = 0,\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+  verifyFormat("enum X\n"
+               "  {\n"
+               "  Y = 0\n"
+               "  }\n",
+               WhitesmithsBraceStyle);
+  verifyFormat("enum X\n"
+               "  {\n"
+               "  Y = 0,\n"
+               "  Z = 1\n"
+               "  };\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("@interface BSApplicationController ()\n"
+               "  {\n"
+               "@private\n"
+               "  id _extraIvar;\n"
+               "  }\n"
+               "@end\n",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("#ifdef _DEBUG\n"
+               "int foo(int i = 0)\n"
+               "#else\n"
+               "int foo(int i = 5)\n"
+               "#endif\n"
+               "  {\n"
+               "  return i;\n"
+               "  }",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void foo() {}\n"
+               "void bar()\n"
+               "#ifdef _DEBUG\n"
+               "  {\n"
+               "  foo();\n"
+               "  }\n"
+               "#else\n"
+               "  {\n"
+               "  }\n"
+               "#endif",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void foobar() { int i = 5; }\n"
+               "#ifdef _DEBUG\n"
+               "void bar() {}\n"
+               "#else\n"
+               "void bar() { foobar(); }\n"
+               "#endif",
+               WhitesmithsBraceStyle);
+
+  // This shouldn't affect ObjC blocks..
+  verifyFormat("[self doSomeThingWithACompletionHandler:^{\n"
+               "  // ...\n"
+               "  int i;\n"
+               "}];",
+               WhitesmithsBraceStyle);
+  verifyFormat("void (^block)(void) = ^{\n"
+               "  // ...\n"
+               "  int i;\n"
+               "};",
+               WhitesmithsBraceStyle);
+  // .. or dict literals.
+  verifyFormat("void f()\n"
+               "  {\n"
+               "  [object someMethod:@{ @\"a\" : @\"b\" }];\n"
+               "  }",
+               WhitesmithsBraceStyle);
+  verifyFormat("int f()\n"
+               "  { // comment\n"
+               "  return 42;\n"
+               "  }",
+               WhitesmithsBraceStyle);
+
+  verifyFormat("void f(Attribute Attribute)\n"
+               "  {\n"
+               "  auto ItFind = std::find_if(randomcontainerlongname.cbegin(),\n"
+               "                             randomcontainerlongname.cend(),\n"
+               "                             [&Attribute](const Attribute &Element) -> bool\n"
+			   "                               {\n"
+			   "                               return true;\n"
+			   "                               });\n"
+               "  }",
+               WhitesmithsBraceStyle);
+
+  WhitesmithsBraceStyle.ColumnLimit = 19;
+  verifyFormat("void f() { int i; }", WhitesmithsBraceStyle);
+  WhitesmithsBraceStyle.ColumnLimit = 18;
+  verifyFormat("void f()\n"
+               "  {\n"
+               "  int i;\n"
+               "  }",
+               WhitesmithsBraceStyle);
+  WhitesmithsBraceStyle.ColumnLimit = 80;
+
+  FormatStyle BreakBeforeBraceShortIfs = WhitesmithsBraceStyle;
+  BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = true;
+  BreakBeforeBraceShortIfs.AllowShortLoopsOnASingleLine = true;
+  verifyFormat("void f(bool b)\n"
+               "  {\n"
+               "  if (b)\n"
+               "    {\n"
+               "    return;\n"
+               "    }\n"
+               "  }\n",
+               BreakBeforeBraceShortIfs);
+  verifyFormat("void f(bool b)\n"
+               "  {\n"
+               "  if (b) return;\n"
+               "  }\n",
+               BreakBeforeBraceShortIfs);
+  verifyFormat("void f(bool b)\n"
+               "  {\n"
+               "  while (b)\n"
+               "    {\n"
+               "    return;\n"
+               "    }\n"
+               "  }\n",
+               BreakBeforeBraceShortIfs);
+}
+
 TEST_F(FormatTest, GNUBraceBreaking) {
   FormatStyle GNUBraceStyle = getLLVMStyle();
   GNUBraceStyle.BreakBeforeBraces = FormatStyle::BS_GNU;
@@ -8502,6 +8753,11 @@
                "  Y = 0,\n"
                "}\n",
                GNUBraceStyle);
+  verifyFormat("enum X\n"
+               "{\n"
+               "  Y = 0\n"
+               "};\n",
+               GNUBraceStyle);

   verifyFormat("@interface BSApplicationController ()\n"
                "{\n"
@@ -8806,6 +9062,8 @@
               FormatStyle::BS_Stroustrup);
   CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
               FormatStyle::BS_Allman);
+  CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces,
+              FormatStyle::BS_Whitesmiths);
   CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);

   Style.NamespaceIndentation = FormatStyle::NI_All;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to