+**NamespaceMacros** (``std::vector<std::string>``)
+ A vector of macros which are used to open namespace blocks.
+
+ These are expected to be macros of the form:
+
+ .. code-block:: c++
+
+ NAMESPACE(<namespace-name>, ...) {
+ <namespace-content>
+ }
+
+ For example: TESTSUITE
+
**ObjCBinPackProtocolList** (``BinPackStyle``)
Controls bin-packing Objective-C protocol conformance list
items into as few lines as possible when they go over ``ColumnLimit``.
/// For example: Q_UNUSED
std::vector<std::string> StatementMacros;
+ /// A vector of macros which are used to open namespace blocks.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// NAMESPACE(<namespace-name>, ...) {
+ /// <namespace-content>
+ /// }
+ /// \endcode
+ ///
+ /// For example: TESTSUITE
+ std::vector<std::string> NamespaceMacros;
+
tooling::IncludeStyle IncludeStyle;
/// Indent case labels one level from the switch statement.
MacroBlockEnd == R.MacroBlockEnd &&
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
NamespaceIndentation == R.NamespaceIndentation &&
+ NamespaceMacros == R.NamespaceMacros &&
ObjCBinPackProtocolList == R.ObjCBinPackProtocolList &&
ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
+ IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
TYPE(LineComment) \
TYPE(MacroBlockBegin) \
TYPE(MacroBlockEnd) \
+ TYPE(NamespaceMacro) \
TYPE(ObjCBlockLBrace) \
TYPE(ObjCBlockLParen) \
TYPE(ObjCDecl) \
// Detect "(inline|export)? namespace" in the beginning of a line.
if (NamespaceTok && NamespaceTok->isOneOf(tok::kw_inline, tok::kw_export))
NamespaceTok = NamespaceTok->getNextNonComment();
- return NamespaceTok && NamespaceTok->is(tok::kw_namespace) ? NamespaceTok
- : nullptr;
+ return NamespaceTok &&
+ NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro)
+ ? NamespaceTok
+ : nullptr;
}
private:
Macros.insert({&IdentTable.get(StatementMacro), TT_StatementMacro});
for (const std::string &TypenameMacro : Style.TypenameMacros)
Macros.insert({&IdentTable.get(TypenameMacro), TT_TypenameMacro});
+ for (const std::string &NamespaceMacro : Style.NamespaceMacros)
+ Macros.insert({&IdentTable.get(NamespaceMacro), TT_NamespaceMacro});
}
ArrayRef<FormatToken *> FormatTokenLexer::lex() {
// Computes the name of a namespace given the namespace token.
// Returns "" for anonymous namespace.
std::string computeName(const FormatToken *NamespaceTok) {
- assert(NamespaceTok && NamespaceTok->is(tok::kw_namespace) &&
+ assert(NamespaceTok &&
+ NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
"expecting a namespace token");
std::string name = "";
- // Collects all the non-comment tokens between 'namespace' and '{'.
const FormatToken *Tok = NamespaceTok->getNextNonComment();
- while (Tok && !Tok->is(tok::l_brace)) {
- name += Tok->TokenText;
+ if (NamespaceTok->is(TT_NamespaceMacro)) {
+ // Collects all the non-comment tokens between opening parenthesis
+ // and closing parenthesis or comma
+ assert(Tok && Tok->is(tok::l_paren) && "expected an opening parenthesis");
Tok = Tok->getNextNonComment();
+ while (Tok && !Tok->isOneOf(tok::r_paren, tok::comma)) {
+ name += Tok->TokenText;
+ Tok = Tok->getNextNonComment();
+ }
+ } else {
+ // Collects all the non-comment tokens between 'namespace' and '{'.
+ while (Tok && !Tok->is(tok::l_brace)) {
+ name += Tok->TokenText;
+ Tok = Tok->getNextNonComment();
+ }
}
return name;
}
-std::string computeEndCommentText(StringRef NamespaceName, bool AddNewline) {
- std::string text = "// namespace";
- if (!NamespaceName.empty()) {
+std::string computeEndCommentText(StringRef NamespaceName, bool AddNewline,
+ const FormatToken *NamespaceTok) {
+ std::string text = "// ";
+ text += NamespaceTok->TokenText;
+ if (NamespaceTok->is(TT_NamespaceMacro))
+ text += "(";
+ else if (!NamespaceName.empty())
text += ' ';
- text += NamespaceName;
- }
+ text += NamespaceName;
+ if (NamespaceTok->is(TT_NamespaceMacro))
+ text += ")";
if (AddNewline)
text += '\n';
return text;
return RBraceTok->Next && RBraceTok->Next->is(tok::comment);
}
-bool validEndComment(const FormatToken *RBraceTok, StringRef NamespaceName) {
+bool validEndComment(const FormatToken *RBraceTok, StringRef NamespaceName,
+ const FormatToken *NamespaceTok) {
assert(hasEndComment(RBraceTok));
const FormatToken *Comment = RBraceTok->Next;
new llvm::Regex("^/[/*] *(end (of )?)? *(anonymous|unnamed)? *"
"namespace( +([a-zA-Z0-9:_]+))?\\.? *(\\*/)?$",
llvm::Regex::IgnoreCase);
- SmallVector<StringRef, 7> Groups;
- if (NamespaceCommentPattern->match(Comment->TokenText, &Groups)) {
- StringRef NamespaceNameInComment = Groups.size() > 5 ? Groups[5] : "";
- // Anonymous namespace comments must not mention a namespace name.
- if (NamespaceName.empty() && !NamespaceNameInComment.empty())
- return false;
- StringRef AnonymousInComment = Groups.size() > 3 ? Groups[3] : "";
- // Named namespace comments must not mention anonymous namespace.
- if (!NamespaceName.empty() && !AnonymousInComment.empty())
+ static llvm::Regex *const NamespaceMacroCommentPattern =
+ new llvm::Regex("^/[/*] *(end (of )?)? *(anonymous|unnamed)? *"
+ "([a-zA-Z0-9_]+)\\(([a-zA-Z0-9:_]*)\\)\\.? *(\\*/)?$",
+ llvm::Regex::IgnoreCase);
+
+ SmallVector<StringRef, 8> Groups;
+ if (NamespaceTok->is(TT_NamespaceMacro) &&
+ NamespaceMacroCommentPattern->match(Comment->TokenText, &Groups)) {
+ StringRef NamespaceTokenText = Groups.size() > 4 ? Groups[4] : "";
+ // The name of the macro must be used.
+ if (NamespaceTokenText != NamespaceTok->TokenText)
return false;
- return NamespaceNameInComment == NamespaceName;
+ } else if (NamespaceTok->isNot(tok::kw_namespace) ||
+ !NamespaceCommentPattern->match(Comment->TokenText, &Groups)) {
+ // Comment does not match regex.
+ return false;
}
- return false;
+ StringRef NamespaceNameInComment = Groups.size() > 5 ? Groups[5] : "";
+ // Anonymous namespace comments must not mention a namespace name.
+ if (NamespaceName.empty() && !NamespaceNameInComment.empty())
+ return false;
+ StringRef AnonymousInComment = Groups.size() > 3 ? Groups[3] : "";
+ // Named namespace comments must not mention anonymous namespace.
+ if (!NamespaceName.empty() && !AnonymousInComment.empty())
+ return false;
+ return NamespaceNameInComment == NamespaceName;
}
void addEndComment(const FormatToken *RBraceTok, StringRef EndCommentText,
return NamespaceTok->getNamespaceToken();
}
+StringRef
+getNamespaceTokenText(const AnnotatedLine *Line,
+ const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
+ const FormatToken *NamespaceTok = getNamespaceToken(Line, AnnotatedLines);
+ return NamespaceTok ? NamespaceTok->TokenText : StringRef();
+}
+
NamespaceEndCommentsFixer::NamespaceEndCommentsFixer(const Environment &Env,
const FormatStyle &Style)
: TokenAnalyzer(Env, Style) {}
tooling::Replacements Fixes;
std::string AllNamespaceNames = "";
size_t StartLineIndex = SIZE_MAX;
+ StringRef NamespaceTokenText;
unsigned int CompactedNamespacesCount = 0;
for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
const AnnotatedLine *EndLine = AnnotatedLines[I];
StartLineIndex = EndLine->MatchingOpeningBlockLineIndex;
std::string NamespaceName = computeName(NamespaceTok);
if (Style.CompactNamespaces) {
+ if (CompactedNamespacesCount == 0)
+ NamespaceTokenText = NamespaceTok->TokenText;
if ((I + 1 < E) &&
- getNamespaceToken(AnnotatedLines[I + 1], AnnotatedLines) &&
+ NamespaceTokenText ==
+ getNamespaceTokenText(AnnotatedLines[I + 1], AnnotatedLines) &&
StartLineIndex - CompactedNamespacesCount - 1 ==
AnnotatedLines[I + 1]->MatchingOpeningBlockLineIndex &&
!AnnotatedLines[I + 1]->First->Finalized) {
EndCommentNextTok->NewlinesBefore == 0 &&
EndCommentNextTok->isNot(tok::eof);
const std::string EndCommentText =
- computeEndCommentText(NamespaceName, AddNewline);
+ computeEndCommentText(NamespaceName, AddNewline, NamespaceTok);
if (!hasEndComment(EndCommentPrevTok)) {
bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1;
if (!isShort)
addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
- } else if (!validEndComment(EndCommentPrevTok, NamespaceName)) {
+ } else if (!validEndComment(EndCommentPrevTok, NamespaceName,
+ NamespaceTok)) {
updateEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes);
}
StartLineIndex = SIZE_MAX;
// Reset token type in case we have already looked at it and then
// recovered from an error (e.g. failure to find the matching >).
- if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_LambdaLBrace,
- TT_ForEachMacro, TT_TypenameMacro,
- TT_FunctionLBrace, TT_ImplicitStringLiteral,
- TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
- TT_OverloadedOperator, TT_RegexLiteral,
- TT_TemplateString, TT_ObjCStringLiteral))
+ if (!CurrentToken->isOneOf(
+ TT_LambdaLSquare, TT_LambdaLBrace, TT_ForEachMacro,
+ TT_TypenameMacro, TT_FunctionLBrace, TT_ImplicitStringLiteral,
+ TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, TT_NamespaceMacro,
+ TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString,
+ TT_ObjCStringLiteral))
CurrentToken->Type = TT_Unknown;
CurrentToken->Role.reset();
CurrentToken->MatchingParen = nullptr;
/// \c true if this line starts a namespace definition.
bool startsWithNamespace() const {
return startsWith(tok::kw_namespace) ||
+ startsWith(TT_NamespaceMacro) ||
startsWith(tok::kw_inline, tok::kw_namespace) ||
startsWith(tok::kw_export, tok::kw_namespace);
}
unsigned Indent = 0;
};
-bool isNamespaceDeclaration(const AnnotatedLine *Line) {
- const FormatToken *NamespaceTok = Line->First;
- return NamespaceTok && NamespaceTok->getNamespaceToken();
-}
-
-bool isEndOfNamespace(const AnnotatedLine *Line,
- const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
+const FormatToken *getMatchingNamespaceToken(
+ const AnnotatedLine *Line,
+ const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
if (!Line->startsWith(tok::r_brace))
- return false;
+ return nullptr;
size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex;
if (StartLineIndex == UnwrappedLine::kInvalidIndex)
- return false;
+ return nullptr;
assert(StartLineIndex < AnnotatedLines.size());
- return isNamespaceDeclaration(AnnotatedLines[StartLineIndex]);
+ return AnnotatedLines[StartLineIndex]->First->getNamespaceToken();
+}
+
+StringRef getNamespaceTokenText(const AnnotatedLine *Line) {
+ const FormatToken *NamespaceToken = Line->First->getNamespaceToken();
+ return NamespaceToken ? NamespaceToken->TokenText : StringRef();
+}
+
+StringRef getMatchingNamespaceTokenText(
+ const AnnotatedLine *Line,
+ const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
+ const FormatToken *NamespaceToken =
+ getMatchingNamespaceToken(Line, AnnotatedLines);
+ return NamespaceToken ? NamespaceToken->TokenText : StringRef();
}
class LineJoiner {
TheLine->Level != 0);
if (Style.CompactNamespaces) {
- if (isNamespaceDeclaration(TheLine)) {
+ if (auto nsToken = TheLine->First->getNamespaceToken()) {
int i = 0;
unsigned closingLine = TheLine->MatchingClosingBlockLineIndex - 1;
- for (; I + 1 + i != E && isNamespaceDeclaration(I[i + 1]) &&
+ for (; I + 1 + i != E &&
+ nsToken->TokenText == getNamespaceTokenText(I[i + 1]) &&
closingLine == I[i + 1]->MatchingClosingBlockLineIndex &&
I[i + 1]->Last->TotalLength < Limit;
i++, closingLine--) {
return i;
}
- if (isEndOfNamespace(TheLine, AnnotatedLines)) {
+ if (auto nsToken = getMatchingNamespaceToken(TheLine, AnnotatedLines)) {
int i = 0;
unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1;
- for (; I + 1 + i != E && isEndOfNamespace(I[i + 1], AnnotatedLines) &&
+ for (; I + 1 + i != E &&
+ nsToken->TokenText ==
+ getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) &&
openingLine == I[i + 1]->MatchingOpeningBlockLineIndex;
i++, openingLine--) {
// No space between consecutive braces
static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
const FormatToken &InitialToken) {
- if (InitialToken.is(tok::kw_namespace))
+ if (InitialToken.isOneOf(tok::kw_namespace, TT_NamespaceMacro))
return Style.BraceWrapping.AfterNamespace;
if (InitialToken.is(tok::kw_class))
return Style.BraceWrapping.AfterClass;
parseStatementMacro();
return;
}
+ if (Style.isCpp() && FormatTok->is(TT_NamespaceMacro)) {
+ parseNamespace();
+ return;
+ }
// In all other cases, parse the declaration.
break;
default:
}
void UnwrappedLineParser::parseNamespace() {
- assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
+ assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
+ "'namespace' expected");
const FormatToken &InitialToken = *FormatTok;
nextToken();
- while (FormatTok->isOneOf(tok::identifier, tok::coloncolon))
- nextToken();
+ if (InitialToken.is(TT_NamespaceMacro)) {
+ parseParens();
+ } else {
+ while (FormatTok->isOneOf(tok::identifier, tok::coloncolon))
+ nextToken();
+ }
if (FormatTok->Tok.is(tok::l_brace)) {
if (ShouldBreakBeforeBrace(Style, InitialToken))
addUnwrappedLine();
Style));
}
+TEST_F(FormatTest, NamespaceMacros) {
+ FormatStyle Style = getLLVMStyle();
+ Style.NamespaceMacros.push_back("TESTSUITE");
+
+ verifyFormat("TESTSUITE(A) {\n"
+ "int foo();\n"
+ "} // TESTSUITE(A)",
+ Style);
+
+ verifyFormat("TESTSUITE(A, B) {\n"
+ "int foo();\n"
+ "} // TESTSUITE(A)",
+ Style);
+
+ // Properly indent according to NamespaceIndentation style
+ Style.NamespaceIndentation = FormatStyle::NI_All;
+ verifyFormat("TESTSUITE(A) {\n"
+ " int foo();\n"
+ "} // TESTSUITE(A)",
+ Style);
+ verifyFormat("TESTSUITE(A) {\n"
+ " namespace B {\n"
+ " int foo();\n"
+ " } // namespace B\n"
+ "} // TESTSUITE(A)",
+ Style);
+ verifyFormat("namespace A {\n"
+ " TESTSUITE(B) {\n"
+ " int foo();\n"
+ " } // TESTSUITE(B)\n"
+ "} // namespace A",
+ Style);
+
+ Style.NamespaceIndentation = FormatStyle::NI_Inner;
+ verifyFormat("TESTSUITE(A) {\n"
+ "TESTSUITE(B) {\n"
+ " int foo();\n"
+ "} // TESTSUITE(B)\n"
+ "} // TESTSUITE(A)",
+ Style);
+ verifyFormat("TESTSUITE(A) {\n"
+ "namespace B {\n"
+ " int foo();\n"
+ "} // namespace B\n"
+ "} // TESTSUITE(A)",
+ Style);
+ verifyFormat("namespace A {\n"
+ "TESTSUITE(B) {\n"
+ " int foo();\n"
+ "} // TESTSUITE(B)\n"
+ "} // namespace A",
+ Style);
+
+ // Properly merge namespace-macros blocks in CompactNamespaces mode
+ Style.NamespaceIndentation = FormatStyle::NI_None;
+ Style.CompactNamespaces = true;
+ verifyFormat("TESTSUITE(A) { TESTSUITE(B) {\n"
+ "}} // TESTSUITE(A::B)",
+ Style);
+
+ EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(out::in)",
+ format("TESTSUITE(out) {\n"
+ "TESTSUITE(in) {\n"
+ "} // TESTSUITE(in)\n"
+ "} // TESTSUITE(out)",
+ Style));
+
+ EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(out::in)",
+ format("TESTSUITE(out) {\n"
+ "TESTSUITE(in) {\n"
+ "} // TESTSUITE(in)\n"
+ "} // TESTSUITE(out)",
+ Style));
+
+ // Do not merge different namespaces/macros
+ EXPECT_EQ("namespace out {\n"
+ "TESTSUITE(in) {\n"
+ "} // TESTSUITE(in)\n"
+ "} // namespace out",
+ format("namespace out {\n"
+ "TESTSUITE(in) {\n"
+ "} // TESTSUITE(in)\n"
+ "} // namespace out",
+ Style));
+ EXPECT_EQ("TESTSUITE(out) {\n"
+ "namespace in {\n"
+ "} // namespace in\n"
+ "} // TESTSUITE(out)",
+ format("TESTSUITE(out) {\n"
+ "namespace in {\n"
+ "} // namespace in\n"
+ "} // TESTSUITE(out)",
+ Style));
+ Style.NamespaceMacros.push_back("FOOBAR");
+ EXPECT_EQ("TESTSUITE(out) {\n"
+ "FOOBAR(in) {\n"
+ "} // FOOBAR(in)\n"
+ "} // TESTSUITE(out)",
+ format("TESTSUITE(out) {\n"
+ "FOOBAR(in) {\n"
+ "} // FOOBAR(in)\n"
+ "} // TESTSUITE(out)",
+ Style));
+}
+
TEST_F(FormatTest, FormatsCompactNamespaces) {
FormatStyle Style = getLLVMStyle();
Style.CompactNamespaces = true;
+ Style.NamespaceMacros.push_back("TESTSUITE");
verifyFormat("namespace A { namespace B {\n"
"}} // namespace A::B",
CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros,
std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"}));
+ Style.NamespaceMacros.clear();
+ CHECK_PARSE("NamespaceMacros: [TESTSUITE]", NamespaceMacros,
+ std::vector<std::string>{"TESTSUITE"});
+ CHECK_PARSE("NamespaceMacros: [TESTSUITE, SUITE]", NamespaceMacros,
+ std::vector<std::string>({"TESTSUITE", "SUITE"}));
+
Style.IncludeStyle.IncludeCategories.clear();
std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = {
{"abc/.*", 2}, {".*", 1}};
"int i;\n"
"int j;\n"
"}"));
+
EXPECT_EQ("namespace {\n"
"int i;\n"
"int j;\n"
"// unrelated"));
}
+TEST_F(NamespaceEndCommentsFixerTest, AddsMacroEndComment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.NamespaceMacros.push_back("TESTSUITE");
+
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE()",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("inline TESTSUITE(A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(A)",
+ fixNamespaceEndComments("inline TESTSUITE(A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("TESTSUITE(::A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(::A)",
+ fixNamespaceEndComments("TESTSUITE(::A) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("TESTSUITE(::A::B) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(::A::B)",
+ fixNamespaceEndComments("TESTSUITE(::A::B) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("TESTSUITE(/**/::/**/A/**/::/**/B/**/) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(::A::B)",
+ fixNamespaceEndComments("TESTSUITE(/**/::/**/A/**/::/**/B/**/) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("TESTSUITE(A, B) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A, B) {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+ EXPECT_EQ("TESTSUITE(\"Test1\") {\n"
+ "int i;\n"
+ "int j;\n"
+ "}// TESTSUITE(\"Test1\")",
+ fixNamespaceEndComments("TESTSUITE(\"Test1\") {\n"
+ "int i;\n"
+ "int j;\n"
+ "}",
+ Style));
+}
+
TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
EXPECT_EQ("namespace A {\n"
"int i;\n"
"}; /* unnamed namespace */"));
}
+TEST_F(NamespaceEndCommentsFixerTest, KeepsValidMacroEndComment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.NamespaceMacros.push_back("TESTSUITE");
+
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "} // end anonymous TESTSUITE()",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "} // end anonymous TESTSUITE()",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /* end of TESTSUITE(A) */",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /* end of TESTSUITE(A) */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ Style));
+ EXPECT_EQ("TESTSUITE(A::B) {\n"
+ "int i;\n"
+ "} // end TESTSUITE(A::B)",
+ fixNamespaceEndComments("TESTSUITE(A::B) {\n"
+ "int i;\n"
+ "} // end TESTSUITE(A::B)",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // end TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // end TESTSUITE(A)",
+ Style));
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "}; /* unnamed TESTSUITE() */",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "}; /* unnamed TESTSUITE() */",
+ Style));
+}
+
TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
EXPECT_EQ("namespace {\n"
"int i;\n"
CompactNamespacesStyle));
}
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidMacroEndLineComment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.NamespaceMacros.push_back("TESTSUITE");
+
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "} // TESTSUITE()",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE()",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} //",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; //",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE A",
+ Style));
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "} // TESTSUITE()",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "} // TESTSUITE",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TOASTSUITE(A)",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // TOASTSUITE(A)",
+ Style));
+ // Updates invalid line comments even for short namespaces.
+ EXPECT_EQ("TESTSUITE(A) {} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {} // TESTSUITE()", Style));
+ EXPECT_EQ("TESTSUITE(A) {}; // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {}; // TESTSUITE()", Style));
+
+ // Update invalid comments for compacted namespaces.
+ FormatStyle CompactNamespacesStyle = getLLVMStyle();
+ CompactNamespacesStyle.CompactNamespaces = true;
+ CompactNamespacesStyle.NamespaceMacros.push_back("TESTSUITE");
+
+ EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(out::in)",
+ fixNamespaceEndComments("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(out)",
+ CompactNamespacesStyle));
+ EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(out::in)",
+ fixNamespaceEndComments("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}} // TESTSUITE(in)",
+ CompactNamespacesStyle));
+ EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}\n"
+ "} // TESTSUITE(out::in)",
+ fixNamespaceEndComments("TESTSUITE(out) { TESTSUITE(in) {\n"
+ "}// TAOSTSUITE(in)\n"
+ "} // TESTSUITE(out)",
+ CompactNamespacesStyle));
+}
+
TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
EXPECT_EQ("namespace {\n"
"int i;\n"
fixNamespaceEndComments("namespace A {}; /**/"));
}
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidMacroEndBlockComment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.NamespaceMacros.push_back("TESTSUITE");
+
+ EXPECT_EQ("TESTSUITE() {\n"
+ "int i;\n"
+ "} // TESTSUITE()",
+ fixNamespaceEndComments("TESTSUITE() {\n"
+ "int i;\n"
+ "} /* TESTSUITE(A) */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /* end TESTSUITE() */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /**/",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /* end unnamed TESTSUITE() */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "} /* TOASTSUITE(A) */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {\n"
+ "int i;\n"
+ "}; /* TAOSTSUITE(A) */",
+ Style));
+ EXPECT_EQ("TESTSUITE(A) {} // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {} /**/", Style));
+ EXPECT_EQ("TESTSUITE(A) {}; // TESTSUITE(A)",
+ fixNamespaceEndComments("TESTSUITE(A) {}; /**/", Style));
+}
+
TEST_F(NamespaceEndCommentsFixerTest,
DoesNotAddEndCommentForNamespacesControlledByMacros) {
EXPECT_EQ("#ifdef 1\n"