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