forked from OSchip/llvm-project
clang-format: better handle namespace macros
Summary: Other macros are used to declare namespaces, and should thus be handled similarly. This is the case for crpcut's TESTSUITE macro, or for unittest-cpp's SUITE macro: TESTSUITE(Foo) { TEST(MyFirstTest) { assert(0); } } // TESTSUITE(Foo) This patch deals with this cases by introducing a new option to specify lists of namespace macros. Internally, it re-uses the system already in place for foreach and statement macros, to ensure there is no impact on performance. Reviewers: krasimir, djasper, klimek Reviewed By: klimek Subscribers: acoomans, cfe-commits, klimek Tags: #clang Differential Revision: https://reviews.llvm.org/D37813 llvm-svn: 362740
This commit is contained in:
parent
f1d9b3180e
commit
e8a301f87f
|
@ -1782,6 +1782,19 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
|
||||
|
||||
**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``.
|
||||
|
|
|
@ -1195,6 +1195,18 @@ struct FormatStyle {
|
|||
/// 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.
|
||||
|
@ -1942,6 +1954,7 @@ struct FormatStyle {
|
|||
MacroBlockEnd == R.MacroBlockEnd &&
|
||||
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
|
||||
NamespaceIndentation == R.NamespaceIndentation &&
|
||||
NamespaceMacros == R.NamespaceMacros &&
|
||||
ObjCBinPackProtocolList == R.ObjCBinPackProtocolList &&
|
||||
ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
|
||||
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
|
||||
|
|
|
@ -455,6 +455,7 @@ template <> struct MappingTraits<FormatStyle> {
|
|||
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);
|
||||
|
|
|
@ -71,6 +71,7 @@ namespace format {
|
|||
TYPE(LineComment) \
|
||||
TYPE(MacroBlockBegin) \
|
||||
TYPE(MacroBlockEnd) \
|
||||
TYPE(NamespaceMacro) \
|
||||
TYPE(ObjCBlockLBrace) \
|
||||
TYPE(ObjCBlockLParen) \
|
||||
TYPE(ObjCDecl) \
|
||||
|
@ -531,8 +532,10 @@ struct FormatToken {
|
|||
// 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:
|
||||
|
|
|
@ -41,6 +41,8 @@ FormatTokenLexer::FormatTokenLexer(const SourceManager &SourceMgr, FileID ID,
|
|||
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() {
|
||||
|
|
|
@ -29,24 +29,41 @@ static const int kShortNamespaceMaxLines = 1;
|
|||
// 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;
|
||||
|
@ -56,7 +73,8 @@ bool hasEndComment(const FormatToken *RBraceTok) {
|
|||
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;
|
||||
|
||||
|
@ -66,19 +84,32 @@ bool validEndComment(const FormatToken *RBraceTok, StringRef NamespaceName) {
|
|||
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())
|
||||
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;
|
||||
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;
|
||||
} 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,
|
||||
|
@ -127,6 +158,13 @@ getNamespaceToken(const AnnotatedLine *Line,
|
|||
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) {}
|
||||
|
@ -139,6 +177,7 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze(
|
|||
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];
|
||||
|
@ -160,8 +199,11 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze(
|
|||
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) {
|
||||
|
@ -189,12 +231,13 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze(
|
|||
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;
|
||||
|
|
|
@ -1194,12 +1194,12 @@ private:
|
|||
|
||||
// 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;
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
/// \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);
|
||||
}
|
||||
|
|
|
@ -134,20 +134,29 @@ private:
|
|||
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 {
|
||||
|
@ -249,10 +258,11 @@ private:
|
|||
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--) {
|
||||
|
@ -264,10 +274,12 @@ private:
|
|||
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
|
||||
|
|
|
@ -630,7 +630,7 @@ static bool isIIFE(const UnwrappedLine &Line,
|
|||
|
||||
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;
|
||||
|
@ -1122,6 +1122,10 @@ void UnwrappedLineParser::parseStructuralElement() {
|
|||
parseStatementMacro();
|
||||
return;
|
||||
}
|
||||
if (Style.isCpp() && FormatTok->is(TT_NamespaceMacro)) {
|
||||
parseNamespace();
|
||||
return;
|
||||
}
|
||||
// In all other cases, parse the declaration.
|
||||
break;
|
||||
default:
|
||||
|
@ -1860,12 +1864,17 @@ void UnwrappedLineParser::parseTryCatch() {
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
|
@ -1870,9 +1870,117 @@ TEST_F(FormatTest, FormatsNamespaces) {
|
|||
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",
|
||||
|
@ -11700,6 +11808,12 @@ TEST_F(FormatTest, ParsesConfiguration) {
|
|||
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}};
|
||||
|
|
|
@ -52,6 +52,7 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
|
|||
"int i;\n"
|
||||
"int j;\n"
|
||||
"}"));
|
||||
|
||||
EXPECT_EQ("namespace {\n"
|
||||
"int i;\n"
|
||||
"int j;\n"
|
||||
|
@ -248,6 +249,85 @@ TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
|
|||
"// 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"
|
||||
|
@ -380,6 +460,54 @@ TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) {
|
|||
"}; /* 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"
|
||||
|
@ -446,6 +574,96 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
|
|||
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"
|
||||
|
@ -489,6 +707,58 @@ TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
|
|||
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"
|
||||
|
|
Loading…
Reference in New Issue