[PATCH] clang-format: "break before else" behavior
Jarkko Hietaniemi
jhi at iki.fi
Fri May 9 05:20:49 PDT 2014
I wanted cuddled braces for 'if' and 'else' (just like the default style
gives) *except* that I wanted my 'else' keywords themselves "uncuddled",
that is, inserting a break before the 'else':
if (a) {
a();
}
else {
b();
}
This style makes the 'else' stand out better, instead of being hidden in
} else {
while still giving the relatively tighter vertical packing of lines.
This looks to be part of the "Stroustrup" style.
However, I'm a little dubious about changing this because so far it
hasn't been part of the Stroustrup behavior... that is, existing users
of BS_Stroustrup will have their code look different when they re-format.
But http://www.stroustrup.com/Programming/PPP-style-rev3.pdf very
clearly "uncuddles" the 'else', while the braces of both 'else' and 'if'
are "cuddled", as a proper K&R descendant should.
In case changing the behavior of BS_Stroustrup is deemed too big a
change, I'm also including an alternate version of the change which adds
a new top-level option for this, AlwaysBreakBeforeElse.
Patches attached.
-------------- next part --------------
Index: tools/clang/include/clang/Format/Format.h
===================================================================
--- tools/clang/include/clang/Format/Format.h (revision 208145)
+++ tools/clang/include/clang/Format/Format.h (working copy)
@@ -240,7 +240,7 @@
/// Like \c Attach, but break before braces on function, namespace and
/// class definitions.
BS_Linux,
- /// Like \c Attach, but break before function definitions.
+ /// Like \c Attach, but break before function definitions, and 'else'.
BS_Stroustrup,
/// Always break before braces.
BS_Allman,
Index: tools/clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- tools/clang/lib/Format/UnwrappedLineParser.cpp (revision 208145)
+++ tools/clang/lib/Format/UnwrappedLineParser.cpp (working copy)
@@ -1035,6 +1035,8 @@
--Line->Level;
}
if (FormatTok->Tok.is(tok::kw_else)) {
+ if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
+ addUnwrappedLine();
nextToken();
if (FormatTok->Tok.is(tok::l_brace)) {
CompoundStatementIndenter Indenter(this, Style, Line->Level);
Index: tools/clang/unittests/Format/FormatTest.cpp
===================================================================
--- tools/clang/unittests/Format/FormatTest.cpp (revision 208145)
+++ tools/clang/unittests/Format/FormatTest.cpp (working copy)
@@ -7377,6 +7377,17 @@
"}",
BreakBeforeBrace);
+ verifyFormat("void foo()\n"
+ "{\n"
+ " if (a) {\n"
+ " a();\n"
+ " }\n"
+ " else {\n"
+ " b();\n"
+ " }\n"
+ "}\n",
+ BreakBeforeBrace);
+
verifyFormat("#ifdef _DEBUG\n"
"int foo(int i = 0)\n"
"#else\n"
-------------- next part --------------
Index: tools/clang/include/clang/Format/Format.h
===================================================================
--- tools/clang/include/clang/Format/Format.h (revision 208145)
+++ tools/clang/include/clang/Format/Format.h (working copy)
@@ -213,6 +213,9 @@
/// \brief If \c true, always break before multiline string literals.
bool AlwaysBreakBeforeMultilineStrings;
+ /// \brief If \c true, always break before 'else'.
+ bool AlwaysBreakBeforeElse;
+
/// \brief Different ways to use tab in formatting.
enum UseTabStyle {
/// Never use tab.
@@ -349,6 +352,7 @@
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
+ AlwaysBreakBeforeElse == R.AlwaysBreakBeforeElse &&
BreakConstructorInitializersBeforeComma ==
R.BreakConstructorInitializersBeforeComma &&
ColumnLimit == R.ColumnLimit &&
Index: tools/clang/lib/Format/Format.cpp
===================================================================
--- tools/clang/lib/Format/Format.cpp (revision 208145)
+++ tools/clang/lib/Format/Format.cpp (working copy)
@@ -160,6 +160,7 @@
Style.AlwaysBreakTemplateDeclarations);
IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
Style.AlwaysBreakBeforeMultilineStrings);
+ IO.mapOptional("AlwaysBreakBeforeElse", Style.AlwaysBreakBeforeElse);
IO.mapOptional("BreakBeforeBinaryOperators",
Style.BreakBeforeBinaryOperators);
IO.mapOptional("BreakBeforeTernaryOperators",
@@ -265,6 +266,7 @@
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
+ LLVMStyle.AlwaysBreakBeforeElse = false;
LLVMStyle.AlwaysBreakTemplateDeclarations = false;
LLVMStyle.BinPackParameters = true;
LLVMStyle.BreakBeforeBinaryOperators = false;
Index: tools/clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- tools/clang/lib/Format/UnwrappedLineParser.cpp (revision 208145)
+++ tools/clang/lib/Format/UnwrappedLineParser.cpp (working copy)
@@ -1035,6 +1035,8 @@
--Line->Level;
}
if (FormatTok->Tok.is(tok::kw_else)) {
+ if (Style.AlwaysBreakBeforeElse)
+ addUnwrappedLine();
nextToken();
if (FormatTok->Tok.is(tok::l_brace)) {
CompoundStatementIndenter Indenter(this, Style, Line->Level);
Index: tools/clang/unittests/Format/FormatTest.cpp
===================================================================
--- tools/clang/unittests/Format/FormatTest.cpp (revision 208145)
+++ tools/clang/unittests/Format/FormatTest.cpp (working copy)
@@ -8769,5 +8769,19 @@
"int i;\n"));
}
+TEST_F(FormatTest, AlwaysBreakBeforeElse) {
+ FormatStyle BeforeElse = getLLVMStyle();
+ BeforeElse.AlwaysBreakBeforeElse = true;
+ verifyFormat("void foo() {\n"
+ " if (a) {\n"
+ " a();\n"
+ " }\n"
+ " else {\n"
+ " b();\n"
+ " }\n"
+ "}\n",
+ BeforeElse);
+}
+
} // end namespace tooling
} // end namespace clang
More information about the cfe-commits
mailing list