[PATCH] clang-format: Adding two new format options.

Robin Sommer via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 16 17:44:00 PDT 2016


**SpacesAroundConditions** (``bool``)
  If ``true``, spaces will be inserted around if/for/while conditions.

**SpacesAfterNot** (``bool``)
  If ``true``, spaces will be inserted after ``!``.
---
 docs/ClangFormatStyleOptions.rst |  6 ++++++
 include/clang/Format/Format.h    |  8 ++++++++
 lib/Format/Format.cpp            |  6 ++++++
 lib/Format/TokenAnnotator.cpp    | 14 +++++++++++++-
 unittests/Format/FormatTest.cpp  | 20 ++++++++++++++++++++
 5 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index a548e83..fac5369 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -721,6 +721,12 @@ the configuration (without a prefix: ``Auto``).
 **SpacesInSquareBrackets** (``bool``)
   If ``true``, spaces will be inserted after ``[`` and before ``]``.
 
+**SpacesAroundConditions** (``bool``)
+  If ``true``, spaces will be inserted around if/for/while conditions.
+
+**SpacesAfterNot** (``bool``)
+  If ``true``, spaces will be inserted after ``!``.
+
 **Standard** (``LanguageStandard``)
   Format compatible with this standard, e.g. use ``A<A<int> >``
   instead of ``A<A<int>>`` for ``LS_Cpp03``.
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 1ff305d..72bff2a 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -597,6 +597,12 @@ struct FormatStyle {
   /// \brief If ``true``, spaces will be inserted after ``[`` and before ``]``.
   bool SpacesInSquareBrackets;
 
+  /// \brief If ``true``, spaces will be inserted around if/for/while conditions.
+  bool SpacesAroundConditions;
+
+  /// \brief If ``true``, spaces will be inserted after ``!``.
+  bool SpacesAfterNot;
+
   /// \brief Supported language standards.
   enum LanguageStandard {
     /// Use C++03-compatible syntax.
@@ -707,6 +713,8 @@ struct FormatStyle {
            SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
            SpacesInParentheses == R.SpacesInParentheses &&
            SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
+           SpacesAfterNot == R.SpacesAfterNot &&
+           SpacesAroundConditions == R.SpacesAroundConditions &&
            Standard == R.Standard && TabWidth == R.TabWidth &&
            UseTab == R.UseTab;
   }
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 32d6bb8..2e04e41 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -352,6 +352,10 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.SpacesInCStyleCastParentheses);
     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
+    IO.mapOptional("SpacesAfterNot",
+                   Style.SpacesAfterNot);
+    IO.mapOptional("SpacesAroundConditions",
+                   Style.SpacesAroundConditions);
     IO.mapOptional("Standard", Style.Standard);
     IO.mapOptional("TabWidth", Style.TabWidth);
     IO.mapOptional("UseTab", Style.UseTab);
@@ -556,6 +560,8 @@ FormatStyle getLLVMStyle() {
   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
   LLVMStyle.SpaceBeforeAssignmentOperators = true;
   LLVMStyle.SpacesInAngles = false;
+  LLVMStyle.SpacesAfterNot = false;
+  LLVMStyle.SpacesAroundConditions = false;
 
   LLVMStyle.PenaltyBreakComment = 300;
   LLVMStyle.PenaltyBreakFirstLessLess = 120;
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 4a90522..5861930 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -1976,6 +1976,16 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
     return Right.is(tok::hash);
   if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
     return Style.SpaceInEmptyParentheses;
+  if (Style.SpacesAroundConditions) {
+    if (Left.is(tok::l_paren) && Left.Previous &&
+      Left.Previous->isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
+                             tok::kw_switch, TT_ForEachMacro))
+        return true;
+    if (Right.is(tok::r_paren) && Right.MatchingParen && Right.MatchingParen->Previous &&
+      Right.MatchingParen->Previous->isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while,
+                                             tok::kw_switch, TT_ForEachMacro))
+        return true;
+  }
   if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
     return (Right.is(TT_CastRParen) ||
             (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
@@ -2196,6 +2206,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
       return Style.SpacesInContainerLiterals;
     return true;
   }
+ if (Style.SpacesAfterNot && Left.is(tok::exclaim))
+        return true;
   if (Left.is(TT_UnaryOperator))
     return Right.is(TT_BinaryOperator);
 
@@ -2214,7 +2226,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
   if (!Style.SpaceBeforeAssignmentOperators &&
       Right.getPrecedence() == prec::Assignment)
     return false;
-  if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment))
+  if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren))
     return (Left.is(TT_TemplateOpener) &&
             Style.Standard == FormatStyle::LS_Cpp03) ||
            !(Left.isOneOf(tok::identifier, tok::l_paren, tok::r_paren,
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 8d46ba6..3b86aac 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -10185,6 +10185,8 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
   CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses);
   CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
   CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
+  CHECK_PARSE_BOOL(SpacesAfterNot);
+  CHECK_PARSE_BOOL(SpacesAroundConditions);
 
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterControlStatement);
@@ -11483,6 +11485,24 @@ TEST_F(FormatTest, FormatsTableGenCode) {
   verifyFormat("include \"a.td\"\ninclude \"b.td\"", Style);
 }
 
+TEST_F(FormatTest, SpacesAfterNot) {
+  FormatStyle Spaces = getLLVMStyle();
+  Spaces.SpacesAfterNot = true;
+  verifyFormat("if (! a)\n  return;", Spaces);
+  verifyFormat("while (! (x || y))\n  return;", Spaces);
+  verifyFormat("do {\n} while (! foo);", Spaces);
+}
+
+TEST_F(FormatTest, SpacesAroundConditions) {
+  FormatStyle Spaces = getLLVMStyle();
+  Spaces.SpacesAroundConditions = true;
+  verifyFormat("if ( !a )\n  return;", Spaces);
+  verifyFormat("if ( a )\n  return;", Spaces);
+  verifyFormat("while ( a )\n  return;", Spaces);
+  verifyFormat("while ( (a && b) )\n  return;", Spaces);
+  verifyFormat("do {\n} while ( 1 != 0 );", Spaces);
+}
+
 // Since this test case uses UNIX-style file path. We disable it for MS
 // compiler.
 #if !defined(_MSC_VER) && !defined(__MINGW32__)

-- 
2.5.5



More information about the cfe-commits mailing list