Skip to content

Commit 2c6ecc9

Browse files
committed
[clang-format] Add an option to insert a newline at EOF if missing
Closes #38042. Differential Revision: https://reviews.llvm.org/D141035
1 parent 755e776 commit 2c6ecc9

File tree

7 files changed

+24
-0
lines changed

7 files changed

+24
-0
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,6 +3162,9 @@ the configuration (without a prefix: ``Auto``).
31623162
--i; --i;
31633163
while (i); } while (i);
31643164

3165+
**InsertNewlineAtEOF** (``Boolean``) :versionbadge:`clang-format 16`
3166+
Insert a newline at end of file if missing.
3167+
31653168
**InsertTrailingCommas** (``TrailingCommaStyle``) :versionbadge:`clang-format 11`
31663169
If set to ``TCS_Wrapped`` will insert trailing commas in container
31673170
literals (arrays and objects) that wrap across multiple lines.

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ clang-format
876876
in C++, C#, Java, and JavaScript.
877877
- Add ``BreakAfterAttributes`` option for breaking after a group of C++11
878878
attributes before a function declaration/definition name.
879+
- Add ``InsertNewlineAtEOF`` option for inserting a newline at EOF if missing.
879880

880881
clang-extdef-mapping
881882
--------------------

clang/include/clang/Format/Format.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,6 +2450,10 @@ struct FormatStyle {
24502450
/// \version 15
24512451
bool InsertBraces;
24522452

2453+
/// Insert a newline at end of file if missing.
2454+
/// \version 16
2455+
bool InsertNewlineAtEOF;
2456+
24532457
/// The style of inserting trailing commas into container literals.
24542458
enum TrailingCommaStyle : int8_t {
24552459
/// Do not insert trailing commas.
@@ -4151,6 +4155,7 @@ struct FormatStyle {
41514155
IndentWidth == R.IndentWidth &&
41524156
IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
41534157
InsertBraces == R.InsertBraces &&
4158+
InsertNewlineAtEOF == R.InsertNewlineAtEOF &&
41544159
IntegerLiteralSeparator.Binary == R.IntegerLiteralSeparator.Binary &&
41554160
IntegerLiteralSeparator.Decimal ==
41564161
R.IntegerLiteralSeparator.Decimal &&

clang/lib/Format/Format.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,7 @@ template <> struct MappingTraits<FormatStyle> {
899899
IO.mapOptional("IndentWrappedFunctionNames",
900900
Style.IndentWrappedFunctionNames);
901901
IO.mapOptional("InsertBraces", Style.InsertBraces);
902+
IO.mapOptional("InsertNewlineAtEOF", Style.InsertNewlineAtEOF);
902903
IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
903904
IO.mapOptional("IntegerLiteralSeparator", Style.IntegerLiteralSeparator);
904905
IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
@@ -1355,6 +1356,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
13551356
LLVMStyle.IndentWidth = 2;
13561357
LLVMStyle.IndentWrappedFunctionNames = false;
13571358
LLVMStyle.InsertBraces = false;
1359+
LLVMStyle.InsertNewlineAtEOF = false;
13581360
LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
13591361
LLVMStyle.IntegerLiteralSeparator = {/*Binary=*/0, /*Decimal=*/0, /*Hex=*/0};
13601362
LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,10 @@ class AnnotatingParser {
12891289
Tok->setType(TT_TrailingReturnArrow);
12901290
}
12911291
break;
1292+
case tok::eof:
1293+
if (Style.InsertNewlineAtEOF && Tok->NewlinesBefore == 0)
1294+
Tok->NewlinesBefore = 1;
1295+
break;
12921296
default:
12931297
break;
12941298
}

clang/unittests/Format/ConfigParseTest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
167167
CHECK_PARSE_BOOL(IndentRequiresClause);
168168
CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
169169
CHECK_PARSE_BOOL(InsertBraces);
170+
CHECK_PARSE_BOOL(InsertNewlineAtEOF);
170171
CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
171172
CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
172173
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);

clang/unittests/Format/FormatTest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25171,6 +25171,14 @@ TEST_F(FormatTest, BreakAfterAttributes) {
2517125171
EXPECT_EQ(Code, format(Code, Style));
2517225172
}
2517325173

25174+
TEST_F(FormatTest, InsertNewlineAtEOF) {
25175+
FormatStyle Style = getLLVMStyle();
25176+
Style.InsertNewlineAtEOF = true;
25177+
25178+
verifyFormat("int i;\n", Style);
25179+
verifyFormat("int i;\n", "int i;", Style);
25180+
}
25181+
2517425182
} // namespace
2517525183
} // namespace format
2517625184
} // namespace clang

0 commit comments

Comments
 (0)