MyDeveloperDay created this revision.
MyDeveloperDay added reviewers: nikola, djasper, poiru, klimek.
MyDeveloperDay added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

Implementation of Jarkko Hietaniemi original AlwaysBreakBeforeElse to avoid 
cuddled braces on an "else" statement.

WebKit Style + Linux BreakBeforeBraces style gives cuddled else brackets, this 
patch adds an AlwaysBreakBeforeElse style to allow required brace style such 
that the else is placed on a newline after the closing brace of the if

Patch by: Jarkko Hietaniemi

http://reviews.llvm.org/D12492

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

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -9131,6 +9131,33 @@
                WebKitBraceStyle);
 }
 
+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);
+
+    verifyFormat("void foo() {\n"
+        "  if (a) {\n"
+        "    a();\n"
+        "  }\n"
+        "  else if (b) {\n"
+        "    b();\n"
+        "  }\n"
+        "  else {\n"
+        "    b();\n"
+        "  }\n"
+        "}\n",
+        BeforeElse);
+}
+
 TEST_F(FormatTest, CatchExceptionReferenceBinding) {
   verifyFormat("void f() {\n"
                "  try {\n"
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1272,8 +1272,11 @@
     --Line->Level;
   }
   if (FormatTok->Tok.is(tok::kw_else)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup)
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup ||
+        Style.AlwaysBreakBeforeElse) {
       addUnwrappedLine();
+    }
+
     nextToken();
     if (FormatTok->Tok.is(tok::l_brace)) {
       CompoundStatementIndenter Indenter(this, Style, Line->Level);
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -217,6 +217,8 @@
                    Style.AlwaysBreakAfterDefinitionReturnType);
     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
                    Style.AlwaysBreakBeforeMultilineStrings);
+    IO.mapOptional("AlwaysBreakBeforeElse",
+                   Style.AlwaysBreakBeforeElse);
     IO.mapOptional("AlwaysBreakTemplateDeclarations",
                    Style.AlwaysBreakTemplateDeclarations);
     IO.mapOptional("BinPackArguments", Style.BinPackArguments);
@@ -357,6 +359,7 @@
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
+  LLVMStyle.AlwaysBreakBeforeElse = false;
   LLVMStyle.AlwaysBreakTemplateDeclarations = false;
   LLVMStyle.BinPackParameters = true;
   LLVMStyle.BinPackArguments = true;
@@ -420,6 +423,7 @@
   GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
   GoogleStyle.AllowShortLoopsOnASingleLine = true;
   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
+  GoogleStyle.AlwaysBreakBeforeElse = false;
   GoogleStyle.AlwaysBreakTemplateDeclarations = true;
   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
   GoogleStyle.DerivePointerAlignment = true;
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -138,6 +138,9 @@
   /// template declaration.
   bool AlwaysBreakTemplateDeclarations;
 
+  /// \brief If \c true, always break before 'else'.
+  bool AlwaysBreakBeforeElse;
+
   /// \brief If \c false, a function call's arguments will either be all on the
   /// same line or will have one line each.
   bool BinPackArguments;
@@ -465,6 +468,8 @@
                R.AlwaysBreakBeforeMultilineStrings &&
            AlwaysBreakTemplateDeclarations ==
                R.AlwaysBreakTemplateDeclarations &&
+           AlwaysBreakBeforeElse ==
+               R.AlwaysBreakBeforeElse &&
            BinPackArguments == R.BinPackArguments &&
            BinPackParameters == R.BinPackParameters &&
            BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -244,6 +244,9 @@
   If ``true``, always break after the ``template<...>`` of a
   template declaration.
 
+**AlwaysBreakBeforeElse** (``bool``)
+  If ``true``, always break before ``else``.
+
 **BinPackArguments** (``bool``)
   If ``false``, a function call's arguments will either be all on the
   same line or will have one line each.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to