Typz created this revision.
Herald added a subscriber: klimek.
This option allows cleaning up namespace declaration, by removing the
extra semicolon after namespace closing brace.
https://reviews.llvm.org/D33314
Files:
include/clang/Format/Format.h
lib/Format/Format.cpp
lib/Format/NamespaceEndCommentsFixer.cpp
unittests/Format/FormatTest.cpp
unittests/Format/NamespaceEndCommentsFixerTest.cpp
Index: unittests/Format/NamespaceEndCommentsFixerTest.cpp
===================================================================
--- unittests/Format/NamespaceEndCommentsFixerTest.cpp
+++ unittests/Format/NamespaceEndCommentsFixerTest.cpp
@@ -214,6 +214,51 @@
"// unrelated"));
}
+TEST_F(NamespaceEndCommentsFixerTest, RemoveSemicolon) {
+ FormatStyle LLVMStyleWithoutSemicolon = getLLVMStyle();
+ LLVMStyleWithoutSemicolon.AllowSemicolonAfterNamespace = false;
+
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ " int j;\n"
+ "}// namespace",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ " int j;\n"
+ "};",
+ LLVMStyleWithoutSemicolon));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "};",
+ LLVMStyleWithoutSemicolon));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "}// namespace A\n"
+ "// unrelated",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "};\n"
+ "// unrelated",
+ LLVMStyleWithoutSemicolon));
+ // case without semicolon is not affected
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ " int j;\n"
+ "}",
+ LLVMStyleWithoutSemicolon));
+}
+
TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
EXPECT_EQ("namespace A {\n"
" int i;\n"
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -8670,6 +8670,7 @@
CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
+ CHECK_PARSE_BOOL(AllowSemicolonAfterNamespace);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
Index: lib/Format/NamespaceEndCommentsFixer.cpp
===================================================================
--- lib/Format/NamespaceEndCommentsFixer.cpp
+++ lib/Format/NamespaceEndCommentsFixer.cpp
@@ -107,6 +107,19 @@
<< llvm::toString(std::move(Err)) << "\n";
}
}
+
+void removeTrailingSemicolon(const FormatToken *SemiColonTok,
+ const SourceManager &SourceMgr,
+ tooling::Replacements *Fixes) {
+ assert(SemiColonTok->is(tok::semi));
+ auto Range = CharSourceRange::getCharRange(SemiColonTok->Tok.getLocation(),
+ SemiColonTok->Tok.getEndLoc());
+ auto Err = Fixes->add(tooling::Replacement(SourceMgr, Range, StringRef()));
+ if (Err) {
+ llvm::errs() << "Error while removing trailing semicolon at end of namespace: "
+ << llvm::toString(std::move(Err)) << "\n";
+ }
+}
} // namespace
NamespaceEndCommentsFixer::NamespaceEndCommentsFixer(const Environment &Env,
@@ -144,6 +157,8 @@
// comments to the semicolon tokens.
if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) {
EndCommentPrevTok = RBraceTok->Next;
+ if (!Style.AllowSemicolonAfterNamespace)
+ removeTrailingSemicolon(RBraceTok->Next, SourceMgr, &Fixes);
}
// The next token in the token stream after the place where the end comment
// token must be. This is either the next token on the current line or the
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -252,6 +252,7 @@
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
Style.AllowAllParametersOfDeclarationOnNextLine);
+ IO.mapOptional("AllowSemicolonAfterNamespace", Style.AllowSemicolonAfterNamespace);
IO.mapOptional("AllowShortBlocksOnASingleLine",
Style.AllowShortBlocksOnASingleLine);
IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
@@ -505,6 +506,7 @@
LLVMStyle.AlignConsecutiveAssignments = false;
LLVMStyle.AlignConsecutiveDeclarations = false;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
+ LLVMStyle.AllowSemicolonAfterNamespace = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
LLVMStyle.AllowShortBlocksOnASingleLine = false;
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -144,6 +144,14 @@
/// \endcode
bool AllowAllParametersOfDeclarationOnNextLine;
+ /// \brief If ``true``, clang-format removes semicolon at the end of namespace.
+ /// \code
+ /// true: false:
+ /// namespace a { vs. namespace a {
+ /// } };
+ /// \endcode
+ bool AllowSemicolonAfterNamespace;
+
/// \brief Allows contracting simple braced statements to a single line.
///
/// E.g., this allows ``if (a) { return; }`` to be put on a single line.
@@ -1352,6 +1360,7 @@
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
R.AllowAllParametersOfDeclarationOnNextLine &&
+ AllowSemicolonAfterNamespace == R.AllowSemicolonAfterNamespace &&
AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
AllowShortCaseLabelsOnASingleLine ==
R.AllowShortCaseLabelsOnASingleLine &&
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits