[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