[llvm-branch-commits] [clang] 07ef031 - Work on EmptyLineAfterFunctionDefinition

Konrad Kleine via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Nov 22 10:43:22 PST 2021


Author: Konrad Kleine
Date: 2021-11-22T16:18:04Z
New Revision: 07ef031d4abb6d1a277abf7549329ca9be7cf8c6

URL: https://github.com/llvm/llvm-project/commit/07ef031d4abb6d1a277abf7549329ca9be7cf8c6
DIFF: https://github.com/llvm/llvm-project/commit/07ef031d4abb6d1a277abf7549329ca9be7cf8c6.diff

LOG: Work on EmptyLineAfterFunctionDefinition

Added: 
    

Modified: 
    clang/include/clang/Format/Format.h
    clang/lib/Format/Format.cpp
    clang/lib/Format/UnwrappedLineFormatter.cpp
    clang/unittests/Format/FormatTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index d38bc6e3f0e68..13d2e17380394 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2168,6 +2168,27 @@ struct FormatStyle {
   /// \version 13
   EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier;
 
+  /// Different styles for empty line after function definitions.
+  enum EmptyLineAfterFunctionDefinitionStyle : unsigned char {
+    /// Keep existing empty lines after function definition.
+    /// MaxEmptyLinesToKeep is applied instead.
+    ELAFDS_Leave,
+    /// Always add empty line after function modifiers if there are none.
+    /// MaxEmptyLinesToKeep is applied also.
+    /// \code
+    ///   void one() {}
+    ///
+    ///   void two() {}
+    ///
+    ///   void three() {}
+    /// \endcode
+    ELAFDS_Always,
+  };
+
+  /// Defines when to put an empty line after a function definition.
+  /// \version 14
+  EmptyLineAfterFunctionDefinitionStyle EmptyLineAfterFunctionDefinition;
+
   /// If ``true``, clang-format detects whether function calls and
   /// definitions are formatted with one parameter per line.
   ///
@@ -3738,6 +3759,7 @@ struct FormatStyle {
            DisableFormat == R.DisableFormat &&
            EmptyLineAfterAccessModifier == R.EmptyLineAfterAccessModifier &&
            EmptyLineBeforeAccessModifier == R.EmptyLineBeforeAccessModifier &&
+           EmptyLineAfterFunctionDefinition == R.EmptyLineAfterFunctionDefinition &&
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
            PackConstructorInitializers == R.PackConstructorInitializers &&

diff  --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 1d60f2b3a321b..dc46531a9bc2b 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -308,6 +308,17 @@ struct ScalarEnumerationTraits<
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<
+    FormatStyle::EmptyLineAfterFunctionDefinitionStyle> {
+  static void
+  enumeration(IO &IO, 
+              FormatStyle::EmptyLineAfterFunctionDefinitionStyle &Value) {
+    IO.enumCase(Value, "Leave", FormatStyle::ELAFDS_Leave);
+    IO.enumCase(Value, "Always", FormatStyle::ELAFDS_Always);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
   static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
@@ -675,6 +686,8 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.EmptyLineAfterAccessModifier);
     IO.mapOptional("EmptyLineBeforeAccessModifier",
                    Style.EmptyLineBeforeAccessModifier);
+    IO.mapOptional("EmptyLineAfterFunctionDefinition",
+                   Style.EmptyLineAfterFunctionDefinition);
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
 
@@ -1156,6 +1169,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.DerivePointerAlignment = false;
   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
+  LLVMStyle.EmptyLineAfterFunctionDefinition = FormatStyle::ELAFDS_Leave;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
   LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
   LLVMStyle.FixNamespaceComments = true;

diff  --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 299536cd806eb..1f7384c7dd847 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1333,6 +1333,18 @@ void UnwrappedLineFormatter::formatFirstToken(
     }
   }
 
+  if (PreviousLine && PreviousLine->mightBeFunctionDefinition() &&
+      (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) {
+     switch (Style.EmptyLineAfterFunctionDefinition) {
+      case FormatStyle::ELAFDS_Leave:
+        Newlines = std::max(Newlines, 1u);
+        break;
+      case FormatStyle::ELAFDS_Always:
+        Newlines = std::max(Newlines, 2u);
+        break;
+      }
+  }
+
   if (Newlines)
     Indent = NewlineIndent;
 

diff  --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 6507cbefc5a90..4a9a71393b4ff 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11083,6 +11083,308 @@ TEST_F(FormatTest, FormatsAfterAndBeforeAccessModifiersInteraction) {
                Style);
 }
 
+TEST_F(FormatTest, FormatsEmptyLineAfterFunctionDefinition) {
+
+  FormatStyle Style = getLLVMStyle();
+  EXPECT_EQ(Style.EmptyLineAfterFunctionDefinition, FormatStyle::ELAFDS_Leave);
+  // verifyFormat("void one() {}\n"
+  //              "\n"
+  //              "void two() {}\n"
+  //              "void three() {}\n",
+  //              Style);
+
+  // // Check if lines are removed.
+  // verifyFormat("void one() {}\n"
+  //              "void two() {}\n"
+  //              "void three() {}\n",
+  //              "void one() {}\n"
+  //              "\n"
+  //              "void two() {}\n"
+  //              "void three() {}\n",
+  //              Style);
+
+  Style.EmptyLineAfterFunctionDefinition = FormatStyle::ELAFDS_Always;
+  verifyFormat("void one() {}\n"
+               "\n"
+               "void two() {}\n"
+               "\n"
+               "void three() {}\n"
+               "\n",
+               Style);
+
+  // Check if lines are added.
+  verifyFormat("void one() {}\n"
+               "\n"
+               "void two() {}\n"
+               "\n"
+               "void three() {}\n"
+               "\n",
+               "void one() {}\n"
+               "void two() {}\n"
+               "void three() {}\n",
+               Style);
+
+  // // Leave tests rely on the code layout, test::messUp can not be used.
+  // Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave;
+  // Style.MaxEmptyLinesToKeep = 0u;
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private:\n"
+  //              "  int i;\n"
+  //              "\n"
+  //              "protected:\n"
+  //              "  int j;\n"
+  //              "};\n",
+  //              Style);
+
+  // // Check if MaxEmptyLinesToKeep is respected.
+  // EXPECT_EQ("struct foo {\n"
+  //           "private:\n"
+  //           "  void f() {}\n"
+  //           "\n"
+  //           "private:\n"
+  //           "  int i;\n"
+  //           "\n"
+  //           "protected:\n"
+  //           "  int j;\n"
+  //           "};\n",
+  //           format("struct foo {\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  void f() {}\n"
+  //                  "\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  int i;\n"
+  //                  "\n"
+  //                  "protected:\n"
+  //                  "\n\n\n"
+  //                  "  int j;\n"
+  //                  "};\n",
+  //                  Style));
+
+  // Style.MaxEmptyLinesToKeep = 1u;
+  // EXPECT_EQ("struct foo {\n"
+  //           "private:\n"
+  //           "\n"
+  //           "  void f() {}\n"
+  //           "\n"
+  //           "private:\n"
+  //           "\n"
+  //           "  int i;\n"
+  //           "\n"
+  //           "protected:\n"
+  //           "\n"
+  //           "  int j;\n"
+  //           "};\n",
+  //           format("struct foo {\n"
+  //                  "private:\n"
+  //                  "\n"
+  //                  "  void f() {}\n"
+  //                  "\n"
+  //                  "private:\n"
+  //                  "\n"
+  //                  "  int i;\n"
+  //                  "\n"
+  //                  "protected:\n"
+  //                  "\n"
+  //                  "  int j;\n"
+  //                  "};\n",
+  //                  Style));
+  // // Check if no lines are kept.
+  // EXPECT_EQ("struct foo {\n"
+  //           "private:\n"
+  //           "  void f() {}\n"
+  //           "\n"
+  //           "private:\n"
+  //           "  int i;\n"
+  //           "\n"
+  //           "protected:\n"
+  //           "  int j;\n"
+  //           "};\n",
+  //           format("struct foo {\n"
+  //                  "private:\n"
+  //                  "  void f() {}\n"
+  //                  "\n"
+  //                  "private:\n"
+  //                  "  int i;\n"
+  //                  "\n"
+  //                  "protected:\n"
+  //                  "  int j;\n"
+  //                  "};\n",
+  //                  Style));
+  // // Check if MaxEmptyLinesToKeep is respected.
+  // EXPECT_EQ("struct foo {\n"
+  //           "private:\n"
+  //           "\n"
+  //           "  void f() {}\n"
+  //           "\n"
+  //           "private:\n"
+  //           "\n"
+  //           "  int i;\n"
+  //           "\n"
+  //           "protected:\n"
+  //           "\n"
+  //           "  int j;\n"
+  //           "};\n",
+  //           format("struct foo {\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  void f() {}\n"
+  //                  "\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  int i;\n"
+  //                  "\n"
+  //                  "protected:\n"
+  //                  "\n\n\n"
+  //                  "  int j;\n"
+  //                  "};\n",
+  //                  Style));
+
+  // Style.MaxEmptyLinesToKeep = 10u;
+  // EXPECT_EQ("struct foo {\n"
+  //           "private:\n"
+  //           "\n\n\n"
+  //           "  void f() {}\n"
+  //           "\n"
+  //           "private:\n"
+  //           "\n\n\n"
+  //           "  int i;\n"
+  //           "\n"
+  //           "protected:\n"
+  //           "\n\n\n"
+  //           "  int j;\n"
+  //           "};\n",
+  //           format("struct foo {\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  void f() {}\n"
+  //                  "\n"
+  //                  "private:\n"
+  //                  "\n\n\n"
+  //                  "  int i;\n"
+  //                  "\n"
+  //                  "protected:\n"
+  //                  "\n\n\n"
+  //                  "  int j;\n"
+  //                  "};\n",
+  //                  Style));
+
+  // // Test with comments.
+  // Style = getLLVMStyle();
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              Style);
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              "struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              Style);
+
+  // Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always;
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              "struct foo {\n"
+  //              "private:\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              Style);
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "  // comment\n"
+  //              "  void f() {}\n"
+  //              "\n"
+  //              "private: /* comment */\n"
+  //              "\n"
+  //              "  int i;\n"
+  //              "};\n",
+  //              Style);
+
+  // // Test with preprocessor defines.
+  // Style = getLLVMStyle();
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              Style);
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              "struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              Style);
+
+  // Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always;
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              "struct foo {\n"
+  //              "private:\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              Style);
+  // verifyFormat("struct foo {\n"
+  //              "private:\n"
+  //              "\n"
+  //              "#ifdef FOO\n"
+  //              "#endif\n"
+  //              "  void f() {}\n"
+  //              "};\n",
+  //              Style);
+}
+
 TEST_F(FormatTest, FormatsArrays) {
   verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"
                "                         [bbbbbbbbbbbbbbbbbbbbbbbbb] = c;");


        


More information about the llvm-branch-commits mailing list