NOTE: This is an experimental flag, that might go away or be renamed. Do
not use this in config files, etc. Use at your own risk.
+**FixNamespaceComments** (``bool``)
+ If ``true``, clang-format adds missing namespace end comments and
+ fixes invalid existing ones.
+
**ForEachMacros** (``std::vector<std::string>``)
A vector of macros that should be interpreted as foreach loops
instead of as function calls.
+**JavaScriptWrapImports** (``bool``)
+ Whether to wrap JavaScript import/export statements.
+
**KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
If true, empty lines at the start of blocks are kept.
Do not use.
* ``LK_Cpp`` (in configuration: ``Cpp``)
- Should be used for C, C++, ObjectiveC, ObjectiveC++.
+ Should be used for C, C++.
* ``LK_Java`` (in configuration: ``Java``)
Should be used for Java.
* ``LK_JavaScript`` (in configuration: ``JavaScript``)
Should be used for JavaScript.
+ * ``LK_ObjC`` (in configuration: ``ObjC``)
+ Should be used for Objective-C, Objective-C++.
+
* ``LK_Proto`` (in configuration: ``Proto``)
Should be used for Protocol Buffers
(https://developers.google.com/protocol-buffers/).
* ``UT_ForIndentation`` (in configuration: ``ForIndentation``)
Use tabs only for indentation.
+ * ``UT_ForContinuationAndIndentation`` (in configuration: ``ForContinuationAndIndentation``)
+ Use tabs only for line continuation and indentation.
+
* ``UT_Always`` (in configuration: ``Always``)
Use tabs whenever we need to fill whitespace that spans at least from
one tab stop to the next one.
/// not use this in config files, etc. Use at your own risk.
bool ExperimentalAutoDetectBinPacking;
+ /// \brief If ``true``, clang-format adds missing namespace end comments and
+ /// fixes invalid existing ones.
+ bool FixNamespaceComments;
+
/// \brief A vector of macros that should be interpreted as foreach loops
/// instead of as function calls.
///
DisableFormat == R.DisableFormat &&
ExperimentalAutoDetectBinPacking ==
R.ExperimentalAutoDetectBinPacking &&
+ FixNamespaceComments == R.FixNamespaceComments &&
ForEachMacros == R.ForEachMacros &&
IncludeCategories == R.IncludeCategories &&
IndentCaseLabels == R.IndentCaseLabels &&
IO.mapOptional("DisableFormat", Style.DisableFormat);
IO.mapOptional("ExperimentalAutoDetectBinPacking",
Style.ExperimentalAutoDetectBinPacking);
+ IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
IO.mapOptional("ForEachMacros", Style.ForEachMacros);
IO.mapOptional("IncludeCategories", Style.IncludeCategories);
IO.mapOptional("IncludeIsMainRegex", Style.IncludeIsMainRegex);
LLVMStyle.Cpp11BracedListStyle = true;
LLVMStyle.DerivePointerAlignment = false;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
+ LLVMStyle.FixNamespaceComments = true;
LLVMStyle.ForEachMacros.push_back("foreach");
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
MozillaStyle.ConstructorInitializerIndentWidth = 2;
MozillaStyle.ContinuationIndentWidth = 2;
MozillaStyle.Cpp11BracedListStyle = false;
+ MozillaStyle.FixNamespaceComments = false;
MozillaStyle.IndentCaseLabels = true;
MozillaStyle.ObjCSpaceAfterProperty = true;
MozillaStyle.ObjCSpaceBeforeProtocolList = false;
Style.BreakConstructorInitializersBeforeComma = true;
Style.Cpp11BracedListStyle = false;
Style.ColumnLimit = 0;
+ Style.FixNamespaceComments = false;
Style.IndentWidth = 4;
Style.NamespaceIndentation = FormatStyle::NI_Inner;
Style.ObjCBlockIndentWidth = 4;
Style.BreakBeforeTernaryOperators = true;
Style.Cpp11BracedListStyle = false;
Style.ColumnLimit = 79;
+ Style.FixNamespaceComments = false;
Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
Style.Standard = FormatStyle::LS_Cpp03;
return Style;
return tooling::Replacements();
auto Env = Environment::CreateVirtualEnvironment(Code, FileName, Ranges);
- if (Style.Language == FormatStyle::LK_JavaScript &&
- Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
- JavaScriptRequoter Requoter(*Env, Expanded);
- tooling::Replacements Requotes = Requoter.process();
- if (!Requotes.empty()) {
- auto NewCode = applyAllReplacements(Code, Requotes);
+ auto reformatAfterApplying = [&] (TokenAnalyzer& Fixer) {
+ tooling::Replacements Fixes = Fixer.process();
+ if (!Fixes.empty()) {
+ auto NewCode = applyAllReplacements(Code, Fixes);
if (NewCode) {
auto NewEnv = Environment::CreateVirtualEnvironment(
*NewCode, FileName,
- tooling::calculateRangesAfterReplacements(Requotes, Ranges));
+ tooling::calculateRangesAfterReplacements(Fixes, Ranges));
Formatter Format(*NewEnv, Expanded, IncompleteFormat);
- return Requotes.merge(Format.process());
+ return Fixes.merge(Format.process());
}
}
+ Formatter Format(*Env, Expanded, IncompleteFormat);
+ return Format.process();
+ };
+
+ if (Style.Language == FormatStyle::LK_Cpp &&
+ Style.FixNamespaceComments) {
+ NamespaceEndCommentsFixer CommentsFixer(*Env, Expanded);
+ return reformatAfterApplying(CommentsFixer);
+ }
+
+ if (Style.Language == FormatStyle::LK_JavaScript &&
+ Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
+ JavaScriptRequoter Requoter(*Env, Expanded);
+ return reformatAfterApplying(Requoter);
}
Formatter Format(*Env, Expanded, IncompleteFormat);
unsigned Length = Declaration.size();
bool IncompleteFormat = false;
+ format::FormatStyle Style = format::getLLVMStyle();
+ Style.FixNamespaceComments = false;
tooling::Replacements Replaces =
- reformat(format::getLLVMStyle(), StringDecl,
- tooling::Range(Offset, Length), "xmldecl.xd", &IncompleteFormat);
+ reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd",
+ &IncompleteFormat);
auto FormattedStringDecl = applyAllReplacements(StringDecl, Replaces);
if (static_cast<bool>(FormattedStringDecl)) {
Declaration = *FormattedStringDecl;
EXPECT_EQ("namespace N {\n"
"\n"
"int i;\n"
- "}",
+ "} // namespace N",
format("namespace N {\n"
"\n"
"int i;\n"
"}"));
// FIXME: This is slightly inconsistent.
+ FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle();
+ LLVMWithNoNamespaceFix.FixNamespaceComments = false;
EXPECT_EQ("namespace {\n"
"int i;\n"
"}",
+ format("namespace {\n"
+ "int i;\n"
+ "\n"
+ "}", LLVMWithNoNamespaceFix));
+ EXPECT_EQ("namespace {\n"
+ "int i;\n"
+ "\n"
+ "} // namespace",
format("namespace {\n"
"int i;\n"
"\n"
}
TEST_F(FormatTest, FormatsNamespaces) {
+ FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle();
+ LLVMWithNoNamespaceFix.FixNamespaceComments = false;
+
verifyFormat("namespace some_namespace {\n"
"class A {};\n"
"void f() { f(); }\n"
- "}");
+ "}",
+ LLVMWithNoNamespaceFix);
verifyFormat("namespace {\n"
"class A {};\n"
"void f() { f(); }\n"
- "}");
+ "}",
+ LLVMWithNoNamespaceFix);
verifyFormat("inline namespace X {\n"
"class A {};\n"
"void f() { f(); }\n"
- "}");
+ "}",
+ LLVMWithNoNamespaceFix);
verifyFormat("using namespace some_namespace;\n"
"class A {};\n"
- "void f() { f(); }");
+ "void f() { f(); }",
+ LLVMWithNoNamespaceFix);
// This code is more common than we thought; if we
// layout this correctly the semicolon will go into
// its own line, which is undesirable.
- verifyFormat("namespace {};");
+ verifyFormat("namespace {};",
+ LLVMWithNoNamespaceFix);
verifyFormat("namespace {\n"
"class A {};\n"
- "};");
+ "};",
+ LLVMWithNoNamespaceFix);
verifyFormat("namespace {\n"
"int SomeVariable = 0; // comment\n"
- "} // namespace");
+ "} // namespace",
+ LLVMWithNoNamespaceFix);
EXPECT_EQ("#ifndef HEADER_GUARD\n"
"#define HEADER_GUARD\n"
"namespace my_namespace {\n"
" namespace my_namespace {\n"
"int i;\n"
"} // my_namespace\n"
- "#endif // HEADER_GUARD"));
+ "#endif // HEADER_GUARD",
+ LLVMWithNoNamespaceFix));
EXPECT_EQ("namespace A::B {\n"
"class C {};\n"
"}",
format("namespace A::B {\n"
"class C {};\n"
- "}"));
+ "}",
+ LLVMWithNoNamespaceFix));
FormatStyle Style = getLLVMStyle();
Style.NamespaceIndentation = FormatStyle::NI_All;
" int i;\n"
" namespace in {\n"
" int i;\n"
- " } // namespace\n"
- "} // namespace",
+ " } // namespace in\n"
+ "} // namespace out",
format("namespace out {\n"
"int i;\n"
"namespace in {\n"
"int i;\n"
- "} // namespace\n"
- "} // namespace",
+ "} // namespace in\n"
+ "} // namespace out",
Style));
Style.NamespaceIndentation = FormatStyle::NI_Inner;
"int i;\n"
"namespace in {\n"
" int i;\n"
- "} // namespace\n"
- "} // namespace",
+ "} // namespace in\n"
+ "} // namespace out",
format("namespace out {\n"
"int i;\n"
"namespace in {\n"
"int i;\n"
- "} // namespace\n"
- "} // namespace",
+ "} // namespace in\n"
+ "} // namespace out",
Style));
}
EXPECT_EQ("SOME_MACRO\n"
"namespace {\n"
"void f();\n"
- "}",
+ "} // namespace",
format("SOME_MACRO\n"
" namespace {\n"
"void f( );\n"
- "}"));
+ "} // namespace"));
// Only if the identifier contains at least 5 characters.
EXPECT_EQ("HTTP f();", format("HTTP\nf();"));
EXPECT_EQ("MACRO\nf();", format("MACRO\nf();"));
verifyIncompleteFormat("namespace {\n"
"class Foo { Foo (\n"
"};\n"
- "} // comment");
+ "} // namespace");
}
TEST_F(FormatTest, IncorrectCodeErrorDetection) {
TEST_F(FormatTest, MozillaBraceBreaking) {
FormatStyle MozillaBraceStyle = getLLVMStyle();
MozillaBraceStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
+ MozillaBraceStyle.FixNamespaceComments = false;
verifyFormat("namespace a {\n"
"class A\n"
"{\n"
TEST_F(FormatTest, WebKitBraceBreaking) {
FormatStyle WebKitBraceStyle = getLLVMStyle();
WebKitBraceStyle.BreakBeforeBraces = FormatStyle::BS_WebKit;
+ WebKitBraceStyle.FixNamespaceComments = false;
verifyFormat("namespace a {\n"
"class A {\n"
" void f()\n"