[clang] 829ed96 - Reland [clang-format] Add the KeepEmptyLinesAtEOF option
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 13 10:02:36 PDT 2023
Author: Owen Pan
Date: 2023-06-13T10:02:10-07:00
New Revision: 829ed96b779c10cb023d7e3dbcfad22413979ec4
URL: https://github.com/llvm/llvm-project/commit/829ed96b779c10cb023d7e3dbcfad22413979ec4
DIFF: https://github.com/llvm/llvm-project/commit/829ed96b779c10cb023d7e3dbcfad22413979ec4.diff
LOG: Reland [clang-format] Add the KeepEmptyLinesAtEOF option
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/unittests/Format/ConfigParseTest.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 8f23a4aa27a92..fa552d65e208a 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3555,6 +3555,11 @@ the configuration (without a prefix: ``Auto``).
false:
import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
+.. _KeepEmptyLinesAtEOF:
+
+**KeepEmptyLinesAtEOF** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ <KeepEmptyLinesAtEOF>`
+ Keep empty lines (up to ``MaxEmptyLinesToKeep``) at end of file.
+
.. _KeepEmptyLinesAtTheStartOfBlocks:
**KeepEmptyLinesAtTheStartOfBlocks** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ <KeepEmptyLinesAtTheStartOfBlocks>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a6b4a79b00a19..6bfd77cc91028 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -719,6 +719,7 @@ clang-format
- Fix all known issues associated with ``LambdaBodyIndentation: OuterScope``.
- Add ``BracedInitializerIndentWidth`` which can be used to configure
the indentation level of the contents of braced init lists.
+- Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 6a9d435174cdd..74b3e15918184 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2675,6 +2675,10 @@ struct FormatStyle {
bool JavaScriptWrapImports;
// clang-format on
+ /// Keep empty lines (up to ``MaxEmptyLinesToKeep``) at end of file.
+ /// \version 17
+ bool KeepEmptyLinesAtEOF;
+
/// If true, the empty line at the start of blocks is kept.
/// \code
/// true: false:
@@ -4364,6 +4368,7 @@ struct FormatStyle {
JavaImportGroups == R.JavaImportGroups &&
JavaScriptQuotes == R.JavaScriptQuotes &&
JavaScriptWrapImports == R.JavaScriptWrapImports &&
+ KeepEmptyLinesAtEOF == R.KeepEmptyLinesAtEOF &&
KeepEmptyLinesAtTheStartOfBlocks ==
R.KeepEmptyLinesAtTheStartOfBlocks &&
Language == R.Language &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 6e2b6a662e7e1..5fee5e6c261a9 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -942,6 +942,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
Style.KeepEmptyLinesAtTheStartOfBlocks);
+ IO.mapOptional("KeepEmptyLinesAtEOF", Style.KeepEmptyLinesAtEOF);
IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation);
IO.mapOptional("LineEnding", Style.LineEnding);
IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
@@ -1410,6 +1411,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
/*Hex=*/0, /*HexMinDigits=*/0};
LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
LLVMStyle.JavaScriptWrapImports = true;
+ LLVMStyle.KeepEmptyLinesAtEOF = false;
LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature;
LLVMStyle.LineEnding = FormatStyle::LE_DeriveLF;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 33be74dfe1b9f..5172deb494b2e 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1425,7 +1425,9 @@ void UnwrappedLineFormatter::formatFirstToken(
unsigned NewlineIndent) {
FormatToken &RootToken = *Line.First;
if (RootToken.is(tok::eof)) {
- unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
+ unsigned Newlines =
+ std::min(RootToken.NewlinesBefore,
+ Style.KeepEmptyLinesAtEOF ? Style.MaxEmptyLinesToKeep + 1 : 1);
unsigned TokenIndent = Newlines ? NewlineIndent : 0;
Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent,
TokenIndent);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 169c93d1143eb..6c720ec22054c 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -167,6 +167,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
CHECK_PARSE_BOOL(InsertBraces);
CHECK_PARSE_BOOL(InsertNewlineAtEOF);
+ CHECK_PARSE_BOOL(KeepEmptyLinesAtEOF);
CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index fa53cbd262def..ee64b3a041c38 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -25728,6 +25728,15 @@ TEST_F(FormatTest, InsertNewlineAtEOF) {
verifyFormat("int i;\n", "int i;", Style);
}
+TEST_F(FormatTest, KeepEmptyLinesAtEOF) {
+ FormatStyle Style = getLLVMStyle();
+ Style.KeepEmptyLinesAtEOF = true;
+
+ const StringRef Code{"int i;\n\n"};
+ verifyFormat(Code, Code, Style);
+ verifyFormat(Code, "int i;\n\n\n", Style);
+}
+
TEST_F(FormatTest, SpaceAfterUDL) {
verifyFormat("auto c = (4s).count();");
verifyFormat("auto x = 5s .count() == 5;");
More information about the cfe-commits
mailing list