curdeius created this revision.
curdeius added reviewers: MyDeveloperDay, HazardyKnusperkeks, owenpan.
curdeius requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Fixes https://github.com/llvm/llvm-project/issues/53430.
Initially, I had a quick and dirty approach, but it led to a myriad of special
cases handling comments (that may add unwrapped lines).
So I added TT_RecordLBrace type annotations and it seems like a much nicer
solution.
I think that in the future it will allow us to clean up some convoluted code
that detects records.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D118337
Files:
clang/lib/Format/FormatToken.h
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -67,6 +67,30 @@
EXPECT_TOKEN(Tokens[11], tok::star, TT_PointerOrReference);
}
+TEST_F(TokenAnnotatorTest, UnderstandsClasses) {
+ auto Tokens = annotate("class C {};");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_RecordLBrace);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsStructs) {
+ auto Tokens = annotate("struct S {};");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_RecordLBrace);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsUnions) {
+ auto Tokens = annotate("union U {};");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_RecordLBrace);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsEnums) {
+ auto Tokens = annotate("enum E {};");
+ EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_RecordLBrace);
+}
+
} // namespace
} // namespace format
} // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -12316,6 +12316,48 @@
" int f() {}\n"
"};",
MergeInlineOnly);
+
+ MergeInlineOnly.BraceWrapping.AfterClass = true;
+ MergeInlineOnly.BraceWrapping.AfterStruct = true;
+ verifyFormat("class C\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("struct C\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f()\n"
+ "{\n"
+ " return 42;\n"
+ "}",
+ MergeInlineOnly);
+ verifyFormat("int f() {}", MergeInlineOnly);
+ verifyFormat("class C\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("struct C\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("struct C\n"
+ "// comment\n"
+ "/* comment */\n"
+ "// comment\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("/* comment */ struct C\n"
+ "{\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
}
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2482,7 +2482,8 @@
parseParens();
} else {
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
- tok::l_square, tok::period)) {
+ tok::l_square, tok::period) ||
+ (Style.isCSharp() && FormatTok->is(tok::kw_union))) {
if (FormatTok->is(tok::l_square))
parseSquare();
else
@@ -2868,6 +2869,7 @@
// Just a declaration or something is wrong.
if (FormatTok->isNot(tok::l_brace))
return true;
+ FormatTok->setType(TT_RecordLBrace);
FormatTok->setBlockKind(BK_Block);
if (Style.Language == FormatStyle::LK_Java) {
@@ -3108,6 +3110,7 @@
}
}
if (FormatTok->Tok.is(tok::l_brace)) {
+ FormatTok->setType(TT_RecordLBrace);
if (ParseAsExpr) {
parseChildBlock();
} else {
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -276,6 +276,9 @@
FormatStyle::SFS_InlineOnly) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
+ if (Style.isJavaScript() && (*I)->Last->is(TT_FunctionLBrace))
+ return true;
+
if ((*I)->Level != 0) {
if (I == B)
return false;
@@ -288,23 +291,10 @@
break;
// Check if the found line starts a record.
- auto *RecordTok = (*J)->First;
- while (RecordTok) {
- // TODO: Refactor to isRecord(RecordTok).
- if (RecordTok->isOneOf(tok::kw_class, tok::kw_struct))
- return true;
- if (Style.isCpp() && RecordTok->is(tok::kw_union))
- return true;
- if (Style.isCSharp() && RecordTok->is(Keywords.kw_interface))
- return true;
- if (Style.Language == FormatStyle::LK_Java &&
- RecordTok->is(tok::kw_enum))
- return true;
- if (Style.isJavaScript() && RecordTok->is(Keywords.kw_function))
- return true;
-
- RecordTok = RecordTok->Next;
- }
+ for (const FormatToken *RecordTok = (*J)->Last; RecordTok;
+ RecordTok = RecordTok->Previous)
+ if (RecordTok->is(tok::l_brace))
+ return RecordTok->is(TT_RecordLBrace);
return false;
}
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1423,7 +1423,8 @@
TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
TT_UntouchableMacroFunc, TT_ConstraintJunctions,
- TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro))
+ TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro,
+ TT_RecordLBrace))
CurrentToken->setType(TT_Unknown);
CurrentToken->Role.reset();
CurrentToken->MatchingParen = nullptr;
Index: clang/lib/Format/FormatToken.h
===================================================================
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -96,6 +96,7 @@
TYPE(PointerOrReference) \
TYPE(PureVirtualSpecifier) \
TYPE(RangeBasedForLoopColon) \
+ TYPE(RecordLBrace) \
TYPE(RegexLiteral) \
TYPE(SelectorName) \
TYPE(StartOfName) \
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits