Skip to content
Snippets Groups Projects
Commit 1f3085d3 authored by Krasimir Georgiev's avatar Krasimir Georgiev
Browse files

[clang-format] Support namespaces ending in semicolon

Summary:
This patch adds support for namespaces ending in semicolon to the namespace comment fixer.
source:
```
namespace A {
  int i;
  int j;
};
```
clang-format before:
```
namespace A {
  int i;
  int j;
} // namespace A;
```
clang-format after:
```
namespace A {
  int i;
  int j;
}; // namespace A
```

Reviewers: djasper

Reviewed By: djasper

Subscribers: cfe-commits, klimek

Differential Revision: https://reviews.llvm.org/D30688

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297140 91177308-0d34-0410-b5e6-96231b3b80d8
parent 0bfb9a5b
No related branches found
No related tags found
No related merge requests found
...@@ -139,20 +139,34 @@ tooling::Replacements NamespaceEndCommentsFixer::analyze( ...@@ -139,20 +139,34 @@ tooling::Replacements NamespaceEndCommentsFixer::analyze(
if (RBraceTok->Finalized) if (RBraceTok->Finalized)
continue; continue;
RBraceTok->Finalized = true; RBraceTok->Finalized = true;
const FormatToken *EndCommentPrevTok = RBraceTok;
// Namespaces often end with '};'. In that case, attach namespace end
// comments to the semicolon tokens.
if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) {
EndCommentPrevTok = RBraceTok->Next;
}
// 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
// first token on the next line.
const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next;
if (EndCommentNextTok && EndCommentNextTok->is(tok::comment))
EndCommentNextTok = EndCommentNextTok->Next;
if (!EndCommentNextTok && I + 1 < E)
EndCommentNextTok = AnnotatedLines[I + 1]->First;
bool AddNewline = EndCommentNextTok &&
EndCommentNextTok->NewlinesBefore == 0 &&
EndCommentNextTok->isNot(tok::eof);
const std::string NamespaceName = computeName(NamespaceTok); const std::string NamespaceName = computeName(NamespaceTok);
bool AddNewline = (I + 1 < E) &&
AnnotatedLines[I + 1]->First->NewlinesBefore == 0 &&
AnnotatedLines[I + 1]->First->isNot(tok::eof);
const std::string EndCommentText = const std::string EndCommentText =
computeEndCommentText(NamespaceName, AddNewline); computeEndCommentText(NamespaceName, AddNewline);
if (!hasEndComment(RBraceTok)) { if (!hasEndComment(EndCommentPrevTok)) {
bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1; bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1;
if (!isShort) if (!isShort)
addEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
continue; continue;
} }
if (!validEndComment(RBraceTok, NamespaceName)) if (!validEndComment(EndCommentPrevTok, NamespaceName))
updateEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); updateEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
} }
return Fixes; return Fixes;
} }
......
...@@ -184,6 +184,34 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) { ...@@ -184,6 +184,34 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
"}\n" "}\n"
"}\n" "}\n"
"}")); "}"));
// Adds an end comment after a semicolon.
EXPECT_EQ("namespace {\n"
" int i;\n"
" int j;\n"
"};// namespace",
fixNamespaceEndComments("namespace {\n"
" int i;\n"
" int j;\n"
"};"));
EXPECT_EQ("namespace A {\n"
" int i;\n"
" int j;\n"
"};// namespace A",
fixNamespaceEndComments("namespace A {\n"
" int i;\n"
" int j;\n"
"};"));
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"));
} }
TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) { TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
...@@ -220,6 +248,24 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) { ...@@ -220,6 +248,24 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
" int j;\n" " int j;\n"
" int k;\n" " int k;\n"
"}")); "}"));
EXPECT_EQ("namespace {\n"
" int i;\n"
" int j;\n"
"};// namespace\n"
"int k;",
fixNamespaceEndComments("namespace {\n"
" int i;\n"
" int j;\n"
"};int k;"));
EXPECT_EQ("namespace {\n"
" int i;\n"
" int j;\n"
"};// namespace\n"
";",
fixNamespaceEndComments("namespace {\n"
" int i;\n"
" int j;\n"
"};;"));
} }
TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) { TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) {
...@@ -227,6 +273,8 @@ TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) { ...@@ -227,6 +273,8 @@ TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) {
EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}")); EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}"));
EXPECT_EQ("namespace A { a }", EXPECT_EQ("namespace A { a }",
fixNamespaceEndComments("namespace A { a }")); fixNamespaceEndComments("namespace A { a }"));
EXPECT_EQ("namespace A { a };",
fixNamespaceEndComments("namespace A { a };"));
} }
TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) { TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) {
...@@ -238,6 +286,14 @@ TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) { ...@@ -238,6 +286,14 @@ TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) {
"}", "}",
// The range (16, 3) spans the 'int' above. // The range (16, 3) spans the 'int' above.
/*Ranges=*/{1, tooling::Range(16, 3)})); /*Ranges=*/{1, tooling::Range(16, 3)}));
EXPECT_EQ("namespace A {\n"
" int i;\n"
"};",
fixNamespaceEndComments("namespace A {\n"
" int i;\n"
"};",
// The range (16, 3) spans the 'int' above.
/*Ranges=*/{1, tooling::Range(16, 3)}));
} }
TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) { TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) {
...@@ -276,6 +332,18 @@ TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) { ...@@ -276,6 +332,18 @@ TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) {
fixNamespaceEndComments("namespace A::B {\n" fixNamespaceEndComments("namespace A::B {\n"
" int i;\n" " int i;\n"
"} // end namespace A::B")); "} // end namespace A::B"));
EXPECT_EQ("namespace A {\n"
" int i;\n"
"}; // end namespace A",
fixNamespaceEndComments("namespace A {\n"
" int i;\n"
"}; // end namespace A"));
EXPECT_EQ("namespace {\n"
" int i;\n"
"}; /* unnamed namespace */",
fixNamespaceEndComments("namespace {\n"
" int i;\n"
"}; /* unnamed namespace */"));
} }
TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) { TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
...@@ -309,10 +377,17 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) { ...@@ -309,10 +377,17 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
fixNamespaceEndComments("namespace A {\n" fixNamespaceEndComments("namespace A {\n"
" int i;\n" " int i;\n"
"} // banamespace A")); "} // banamespace A"));
EXPECT_EQ("namespace A {\n"
" int i;\n"
"}; // namespace A",
fixNamespaceEndComments("namespace A {\n"
" int i;\n"
"}; // banamespace A"));
// Updates invalid line comments even for short namespaces. // Updates invalid line comments even for short namespaces.
EXPECT_EQ("namespace A {} // namespace A", EXPECT_EQ("namespace A {} // namespace A",
fixNamespaceEndComments("namespace A {} // namespace")); fixNamespaceEndComments("namespace A {} // namespace"));
EXPECT_EQ("namespace A {}; // namespace A",
fixNamespaceEndComments("namespace A {}; // namespace"));
} }
TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) { TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
...@@ -346,8 +421,16 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) { ...@@ -346,8 +421,16 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
fixNamespaceEndComments("namespace A {\n" fixNamespaceEndComments("namespace A {\n"
" int i;\n" " int i;\n"
"} /* banamespace A */")); "} /* banamespace A */"));
EXPECT_EQ("namespace A {\n"
" int i;\n"
"}; // namespace A",
fixNamespaceEndComments("namespace A {\n"
" int i;\n"
"}; /* banamespace A */"));
EXPECT_EQ("namespace A {} // namespace A", EXPECT_EQ("namespace A {} // namespace A",
fixNamespaceEndComments("namespace A {} /**/")); fixNamespaceEndComments("namespace A {} /**/"));
EXPECT_EQ("namespace A {}; // namespace A",
fixNamespaceEndComments("namespace A {}; /**/"));
} }
TEST_F(NamespaceEndCommentsFixerTest, TEST_F(NamespaceEndCommentsFixerTest,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment