[clang-format] Fix brace wrapping for Java records (#164711)
The brace wrapping for Java records should now behave similar to
classes. Before, opening braces for Java records were always placed in
the same line as the record definition.
GitOrigin-RevId: 6c4f9688082361a5c5d57aa1e6d368dfc4aeea75
diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp
index ac9c81d..d31d656 100644
--- a/lib/Format/UnwrappedLineFormatter.cpp
+++ b/lib/Format/UnwrappedLineFormatter.cpp
@@ -285,7 +285,8 @@
if (Tok && Tok->is(tok::kw_typedef))
Tok = Tok->getNextNonComment();
if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
- tok::kw_extern, Keywords.kw_interface)) {
+ tok::kw_extern, Keywords.kw_interface,
+ Keywords.kw_record)) {
return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
? tryMergeSimpleBlock(I, E, Limit)
: 0;
@@ -498,7 +499,8 @@
ShouldMerge = Style.AllowShortEnumsOnASingleLine;
} else if (TheLine->Last->is(TT_CompoundRequirementLBrace)) {
ShouldMerge = Style.AllowShortCompoundRequirementOnASingleLine;
- } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace)) {
+ } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace,
+ TT_RecordLBrace)) {
// NOTE: We use AfterClass (whereas AfterStruct exists) for both classes
// and structs, but it seems that wrapping is still handled correctly
// elsewhere.
@@ -507,7 +509,7 @@
!Style.BraceWrapping.SplitEmptyRecord);
} else if (TheLine->InPPDirective ||
TheLine->First->isNoneOf(tok::kw_class, tok::kw_enum,
- tok::kw_struct)) {
+ tok::kw_struct, Keywords.kw_record)) {
// Try to merge a block with left brace unwrapped that wasn't yet
// covered.
ShouldMerge = !Style.BraceWrapping.AfterFunction ||
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 5e2584e..8b7dd02 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -948,7 +948,11 @@
}
static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
- const FormatToken &InitialToken) {
+ const FormatToken &InitialToken,
+ const bool IsJavaRecord) {
+ if (IsJavaRecord)
+ return Style.BraceWrapping.AfterClass;
+
tok::TokenKind Kind = InitialToken.Tok.getKind();
if (InitialToken.is(TT_NamespaceMacro))
Kind = tok::kw_namespace;
@@ -3200,7 +3204,7 @@
if (FormatTok->is(tok::l_brace)) {
FormatTok->setFinalizedType(TT_NamespaceLBrace);
- if (ShouldBreakBeforeBrace(Style, InitialToken))
+ if (ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false))
addUnwrappedLine();
unsigned AddLevels =
@@ -3865,7 +3869,7 @@
}
if (!Style.AllowShortEnumsOnASingleLine &&
- ShouldBreakBeforeBrace(Style, InitialToken)) {
+ ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false)) {
addUnwrappedLine();
}
// Parse enum body.
@@ -4160,7 +4164,7 @@
if (ParseAsExpr) {
parseChildBlock();
} else {
- if (ShouldBreakBeforeBrace(Style, InitialToken))
+ if (ShouldBreakBeforeBrace(Style, InitialToken, IsJavaRecord))
addUnwrappedLine();
unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp
index 1416614..3cc97e2 100644
--- a/unittests/Format/FormatTestJava.cpp
+++ b/unittests/Format/FormatTestJava.cpp
@@ -848,6 +848,19 @@
" Pat Q. Smith");
}
+TEST_F(FormatTestJava, BreakAfterRecord) {
+ auto Style = getLLVMStyle(FormatStyle::LK_Java);
+ Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ Style.BraceWrapping.SplitEmptyRecord = true;
+
+ verifyFormat("public record Foo(int i)\n"
+ "{\n"
+ "}",
+ "public record Foo(int i) {}", Style);
+}
+
} // namespace
} // namespace test
} // namespace format