Skip to content

Commit 598aad0

Browse files
committed
[clang-format] Add a SortUsingDeclaration option and enable it by default
Summary: This patch adds a `SortUsingDeclaration` style option and enables it for llvm style. Reviewers: klimek Reviewed By: klimek Subscribers: klimek Differential Revision: https://reviews.llvm.org/D34453 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306094 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4c8bc86 commit 598aad0

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

docs/ClangFormatStyleOptions.rst

+9
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,15 @@ the configuration (without a prefix: ``Auto``).
14751475
#include "b.h" vs. #include "a.h"
14761476
#include "a.h" #include "b.h"
14771477

1478+
**SortUsingDeclarations** (``bool``)
1479+
If ``true``, clang-format will sort using declarations.
1480+
1481+
.. code-block:: c++
1482+
1483+
false: true:
1484+
using std::cout; vs. using std::cin;
1485+
using std::cin; using std::cout;
1486+
14781487
**SpaceAfterCStyleCast** (``bool``)
14791488
If ``true``, a space is inserted after C style casts.
14801489

include/clang/Format/Format.h

+8
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,14 @@ struct FormatStyle {
12701270
/// \endcode
12711271
bool SortIncludes;
12721272

1273+
/// \brief If ``true``, clang-format will sort using declarations.
1274+
/// \code
1275+
/// false: true:
1276+
/// using std::cout; vs. using std::cin;
1277+
/// using std::cin; using std::cout;
1278+
/// \endcode
1279+
bool SortUsingDeclarations;
1280+
12731281
/// \brief If ``true``, a space is inserted after C style casts.
12741282
/// \code
12751283
/// true: false:

lib/Format/Format.cpp

+44-26
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ template <> struct MappingTraits<FormatStyle> {
379379
IO.mapOptional("PointerAlignment", Style.PointerAlignment);
380380
IO.mapOptional("ReflowComments", Style.ReflowComments);
381381
IO.mapOptional("SortIncludes", Style.SortIncludes);
382+
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
382383
IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
383384
IO.mapOptional("SpaceAfterTemplateKeyword", Style.SpaceAfterTemplateKeyword);
384385
IO.mapOptional("SpaceBeforeAssignmentOperators",
@@ -619,6 +620,7 @@ FormatStyle getLLVMStyle() {
619620

620621
LLVMStyle.DisableFormat = false;
621622
LLVMStyle.SortIncludes = true;
623+
LLVMStyle.SortUsingDeclarations = true;
622624

623625
return LLVMStyle;
624626
}
@@ -773,6 +775,7 @@ FormatStyle getNoStyle() {
773775
FormatStyle NoStyle = getLLVMStyle();
774776
NoStyle.DisableFormat = true;
775777
NoStyle.SortIncludes = false;
778+
NoStyle.SortUsingDeclarations = false;
776779
return NoStyle;
777780
}
778781

@@ -1879,38 +1882,53 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
18791882
return tooling::Replacements();
18801883
if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
18811884
return tooling::Replacements();
1882-
auto Env = Environment::CreateVirtualEnvironment(Code, FileName, Ranges);
1883-
1884-
auto reformatAfterApplying = [&] (TokenAnalyzer& Fixer) {
1885-
tooling::Replacements Fixes = Fixer.process();
1886-
if (!Fixes.empty()) {
1887-
auto NewCode = applyAllReplacements(Code, Fixes);
1888-
if (NewCode) {
1889-
auto NewEnv = Environment::CreateVirtualEnvironment(
1890-
*NewCode, FileName,
1891-
tooling::calculateRangesAfterReplacements(Fixes, Ranges));
1892-
Formatter Format(*NewEnv, Expanded, Status);
1893-
return Fixes.merge(Format.process());
1894-
}
1895-
}
1896-
Formatter Format(*Env, Expanded, Status);
1897-
return Format.process();
1898-
};
18991885

1900-
if (Style.Language == FormatStyle::LK_Cpp &&
1901-
Style.FixNamespaceComments) {
1902-
NamespaceEndCommentsFixer CommentsFixer(*Env, Expanded);
1903-
return reformatAfterApplying(CommentsFixer);
1886+
typedef std::function<tooling::Replacements(const Environment &)>
1887+
AnalyzerPass;
1888+
SmallVector<AnalyzerPass, 4> Passes;
1889+
1890+
if (Style.Language == FormatStyle::LK_Cpp) {
1891+
if (Style.FixNamespaceComments)
1892+
Passes.emplace_back([&](const Environment &Env) {
1893+
return NamespaceEndCommentsFixer(Env, Expanded).process();
1894+
});
1895+
1896+
if (Style.SortUsingDeclarations)
1897+
Passes.emplace_back([&](const Environment &Env) {
1898+
return UsingDeclarationsSorter(Env, Expanded).process();
1899+
});
19041900
}
19051901

19061902
if (Style.Language == FormatStyle::LK_JavaScript &&
1907-
Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) {
1908-
JavaScriptRequoter Requoter(*Env, Expanded);
1909-
return reformatAfterApplying(Requoter);
1903+
Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
1904+
Passes.emplace_back([&](const Environment &Env) {
1905+
return JavaScriptRequoter(Env, Expanded).process();
1906+
});
1907+
1908+
Passes.emplace_back([&](const Environment &Env) {
1909+
return Formatter(Env, Expanded, Status).process();
1910+
});
1911+
1912+
std::unique_ptr<Environment> Env =
1913+
Environment::CreateVirtualEnvironment(Code, FileName, Ranges);
1914+
llvm::Optional<std::string> CurrentCode = None;
1915+
tooling::Replacements Fixes;
1916+
for (size_t I = 0, E = Passes.size(); I < E; ++I) {
1917+
tooling::Replacements PassFixes = Passes[I](*Env);
1918+
auto NewCode = applyAllReplacements(
1919+
CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes);
1920+
if (NewCode) {
1921+
Fixes = Fixes.merge(PassFixes);
1922+
if (I + 1 < E) {
1923+
CurrentCode = std::move(*NewCode);
1924+
Env = Environment::CreateVirtualEnvironment(
1925+
*CurrentCode, FileName,
1926+
tooling::calculateRangesAfterReplacements(Fixes, Ranges));
1927+
}
1928+
}
19101929
}
19111930

1912-
Formatter Format(*Env, Expanded, Status);
1913-
return Format.process();
1931+
return Fixes;
19141932
}
19151933

19161934
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,

unittests/Format/FormatTest.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -9333,6 +9333,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
93339333
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
93349334
CHECK_PARSE_BOOL(ReflowComments);
93359335
CHECK_PARSE_BOOL(SortIncludes);
9336+
CHECK_PARSE_BOOL(SortUsingDeclarations);
93369337
CHECK_PARSE_BOOL(SpacesInParentheses);
93379338
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
93389339
CHECK_PARSE_BOOL(SpacesInAngles);
@@ -10874,6 +10875,13 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) {
1087410875
EXPECT_EQ(Expected, *Result);
1087510876
}
1087610877

10878+
TEST_F(FormatTest, FormatSortsUsingDeclarations) {
10879+
EXPECT_EQ("using std::cin;\n"
10880+
"using std::cout;",
10881+
format("using std::cout;\n"
10882+
"using std::cin;", getGoogleStyle()));
10883+
}
10884+
1087710885
TEST_F(FormatTest, UTF8CharacterLiteralCpp03) {
1087810886
format::FormatStyle Style = format::getLLVMStyle();
1087910887
Style.Standard = FormatStyle::LS_Cpp03;

0 commit comments

Comments
 (0)