r372497 - Clang-format: Add Whitesmiths indentation style
Paul Hoad via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 22 05:00:34 PDT 2019
Author: paulhoad
Date: Sun Sep 22 05:00:34 2019
New Revision: 372497
URL: http://llvm.org/viewvc/llvm-project?rev=372497&view=rev
Log:
Clang-format: Add Whitesmiths indentation style
Summary:
This patch adds support for the Whitesmiths indentation style to clang-format. It’s an update to a patch submitted in 2015 (D6833), but reworks it to use the newer API.
There are still some issues with this patch, primarily around `switch` and `case` support. The added unit test won’t currently pass because of the remaining issues.
Reviewers: mboehme, MyDeveloperDay, djasper
Reviewed By: MyDeveloperDay
Subscribers: krasimir, MyDeveloperDay, echristo, cfe-commits
Patch By: @timwoj (Tim Wojtulewicz)
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67627
Modified:
cfe/trunk/docs/ClangFormatStyleOptions.rst
cfe/trunk/include/clang/Format/Format.h
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/docs/ClangFormatStyleOptions.rst (original)
+++ cfe/trunk/docs/ClangFormatStyleOptions.rst Sun Sep 22 05:00:34 2019
@@ -1128,6 +1128,34 @@ the configuration (without a prefix: ``A
B
};
+ * ``BS_Whitesmiths`` (in configuration: ``Whitesmiths``)
+ Like ``Allman`` but always indent braces and line up code with braces.
+
+ .. code-block:: c++
+
+ try
+ {
+ foo();
+ }
+ catch ()
+ {
+ }
+ void foo() { bar(); }
+ class foo
+ {
+ };
+ if (foo())
+ {
+ }
+ else
+ {
+ }
+ enum X : int
+ {
+ A,
+ B
+ };
+
* ``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
Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Sun Sep 22 05:00:34 2019
@@ -733,6 +733,32 @@ struct FormatStyle {
/// B
/// };
/// \endcode
+ BS_Whitesmiths,
+ /// Like ``Allman`` but always indent braces and line up code with braces.
+ /// \code
+ /// try
+ /// {
+ /// foo();
+ /// }
+ /// catch ()
+ /// {
+ /// }
+ /// void foo() { bar(); }
+ /// class foo
+ /// {
+ /// };
+ /// if (foo())
+ /// {
+ /// }
+ /// else
+ /// {
+ /// }
+ /// enum X : int
+ /// {
+ /// A,
+ /// B
+ /// };
+ /// \endcode
BS_GNU,
/// Like ``Attach``, but break before functions.
/// \code
Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Sun Sep 22 05:00:34 2019
@@ -931,6 +931,11 @@ unsigned ContinuationIndenter::getNewLin
return std::max(State.Stack.back().LastSpace,
State.Stack.back().Indent + Style.ContinuationIndentWidth);
+ if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
+ State.Line->First->is(tok::kw_enum))
+ return (Style.IndentWidth * State.Line->First->IndentLevel) +
+ Style.IndentWidth;
+
if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block)
return Current.NestingLevel == 0 ? State.FirstIndent
: State.Stack.back().Indent;
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Sun Sep 22 05:00:34 2019
@@ -165,6 +165,7 @@ template <> struct ScalarEnumerationTrai
IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
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);
IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
@@ -656,6 +657,19 @@ static FormatStyle expandPresets(const F
Expanded.BraceWrapping.AfterExternBlock = true;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
+ break;
+ case FormatStyle::BS_Whitesmiths:
+ Expanded.BraceWrapping.AfterCaseLabel = true;
+ Expanded.BraceWrapping.AfterClass = true;
+ Expanded.BraceWrapping.AfterControlStatement = true;
+ Expanded.BraceWrapping.AfterEnum = true;
+ Expanded.BraceWrapping.AfterFunction = true;
+ Expanded.BraceWrapping.AfterNamespace = true;
+ Expanded.BraceWrapping.AfterObjCDeclaration = true;
+ Expanded.BraceWrapping.AfterStruct = true;
+ Expanded.BraceWrapping.AfterExternBlock = true;
+ Expanded.BraceWrapping.BeforeCatch = true;
+ Expanded.BraceWrapping.BeforeElse = true;
break;
case FormatStyle::BS_GNU:
Expanded.BraceWrapping = {true, true, true, true, true, true, true, true,
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Sun Sep 22 05:00:34 2019
@@ -1193,6 +1193,12 @@ void UnwrappedLineFormatter::formatFirst
if (Newlines)
Indent = NewlineIndent;
+ // If in Whitemsmiths mode, indent start and end of blocks
+ if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
+ if (RootToken.isOneOf(tok::l_brace, tok::r_brace, tok::kw_case))
+ Indent += Style.IndentWidth;
+ }
+
// Preprocessor directives get indented before the hash only if specified
if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
(Line.Type == LT_PreprocessorDirective ||
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=372497&r1=372496&r2=372497&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Sun Sep 22 05:00:34 2019
@@ -2401,6 +2401,16 @@ TEST_F(FormatTest, FormatTryCatchBraceSt
" // something\n"
"}",
Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
+ verifyFormat("try\n"
+ " {\n"
+ " // something white\n"
+ " }\n"
+ "catch (...)\n"
+ " {\n"
+ " // something white\n"
+ " }",
+ Style);
Style.BreakBeforeBraces = FormatStyle::BS_GNU;
verifyFormat("try\n"
" {\n"
@@ -4880,6 +4890,13 @@ TEST_F(FormatTest, BreaksFunctionDeclara
"}",
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"
@@ -11420,6 +11437,251 @@ TEST_F(FormatTest, AllmanBraceBreaking)
BreakBeforeBraceShortIfs);
}
+TEST_F(FormatTest, WhitesmithsBraceBreaking) {
+ FormatStyle WhitesmithsBraceStyle = getLLVMStyle();
+ WhitesmithsBraceStyle.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
+
+ // Make a few changes to the style for testing purposes
+ WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::SFS_Empty;
+ WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
+ WhitesmithsBraceStyle.ColumnLimit = 0;
+
+ // FIXME: this test case can't decide whether there should be a blank line
+ // after the ~D() line or not. It adds one if one doesn't exist in the test
+ // and it removes the line if one exists.
+ /*
+ 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"
+ " } // namespace B\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()\n"
+ " {\n"
+ " return;\n"
+ " }\n"
+ " };\n"
+ "struct B\n"
+ " {\n"
+ " int x;\n"
+ " };\n"
+ " } // namespace a",
+ 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"
+ " } while (false)\n"
+ " }\n",
+ WhitesmithsBraceStyle);
+
+ // FIXME: the block and the break under case 2 in this test don't get indented correctly
+ /*
+ verifyFormat("void switchTest1(int a)\n"
+ " {\n"
+ " switch (a)\n"
+ " {\n"
+ " case 2:\n"
+ " {\n"
+ " }\n"
+ " break;\n"
+ " }\n"
+ " }\n",
+ WhitesmithsBraceStyle);
+ */
+
+ // FIXME: the block and the break under case 2 in this test don't get indented correctly
+ /*
+ verifyFormat("void switchTest2(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, // testing\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()\n"
+ " {\n"
+ " int i = 5;\n"
+ " }\n"
+ "#ifdef _DEBUG\n"
+ "void bar()\n"
+ " {\n"
+ " }\n"
+ "#else\n"
+ "void bar()\n"
+ " {\n"
+ " foobar();\n"
+ " }\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);
+
+ FormatStyle BreakBeforeBraceShortIfs = WhitesmithsBraceStyle;
+ BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_Always;
+ 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;
@@ -12097,6 +12359,8 @@ TEST_F(FormatTest, ParsesConfiguration)
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);
CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces,
FormatStyle::BS_WebKit);
More information about the cfe-commits
mailing list