diff options
author | Krasimir Georgiev <krasimir@google.com> | 2017-06-23 11:46:03 +0000 |
---|---|---|
committer | Krasimir Georgiev <krasimir@google.com> | 2017-06-23 11:46:03 +0000 |
commit | 598aad0fe0d99790d34390533e51e3d0e85531ef (patch) | |
tree | f107f40c5f661836791205db8444e72df6699acb | |
parent | 4c8bc8646c93899503aa9efbb92832e952c4bbec (diff) |
[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
-rw-r--r-- | docs/ClangFormatStyleOptions.rst | 9 | ||||
-rw-r--r-- | include/clang/Format/Format.h | 8 | ||||
-rw-r--r-- | lib/Format/Format.cpp | 70 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 8 |
4 files changed, 69 insertions, 26 deletions
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 8555f06875..6133ca9900 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -1475,6 +1475,15 @@ the configuration (without a prefix: ``Auto``). #include "b.h" vs. #include "a.h" #include "a.h" #include "b.h" +**SortUsingDeclarations** (``bool``) + If ``true``, clang-format will sort using declarations. + + .. code-block:: c++ + + false: true: + using std::cout; vs. using std::cin; + using std::cin; using std::cout; + **SpaceAfterCStyleCast** (``bool``) If ``true``, a space is inserted after C style casts. diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 72f31943ed..c1b62477ed 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -1270,6 +1270,14 @@ struct FormatStyle { /// \endcode bool SortIncludes; + /// \brief If ``true``, clang-format will sort using declarations. + /// \code + /// false: true: + /// using std::cout; vs. using std::cin; + /// using std::cin; using std::cout; + /// \endcode + bool SortUsingDeclarations; + /// \brief If ``true``, a space is inserted after C style casts. /// \code /// true: false: diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 3e3667bfd8..7659d56adf 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -379,6 +379,7 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("PointerAlignment", Style.PointerAlignment); IO.mapOptional("ReflowComments", Style.ReflowComments); IO.mapOptional("SortIncludes", Style.SortIncludes); + IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations); IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast); IO.mapOptional("SpaceAfterTemplateKeyword", Style.SpaceAfterTemplateKeyword); IO.mapOptional("SpaceBeforeAssignmentOperators", @@ -619,6 +620,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.DisableFormat = false; LLVMStyle.SortIncludes = true; + LLVMStyle.SortUsingDeclarations = true; return LLVMStyle; } @@ -773,6 +775,7 @@ FormatStyle getNoStyle() { FormatStyle NoStyle = getLLVMStyle(); NoStyle.DisableFormat = true; NoStyle.SortIncludes = false; + NoStyle.SortUsingDeclarations = false; return NoStyle; } @@ -1879,38 +1882,53 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, return tooling::Replacements(); if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) return tooling::Replacements(); - auto Env = Environment::CreateVirtualEnvironment(Code, FileName, Ranges); - - 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(Fixes, Ranges)); - Formatter Format(*NewEnv, Expanded, Status); - return Fixes.merge(Format.process()); - } - } - Formatter Format(*Env, Expanded, Status); - return Format.process(); - }; - if (Style.Language == FormatStyle::LK_Cpp && - Style.FixNamespaceComments) { - NamespaceEndCommentsFixer CommentsFixer(*Env, Expanded); - return reformatAfterApplying(CommentsFixer); + typedef std::function<tooling::Replacements(const Environment &)> + AnalyzerPass; + SmallVector<AnalyzerPass, 4> Passes; + + if (Style.Language == FormatStyle::LK_Cpp) { + if (Style.FixNamespaceComments) + Passes.emplace_back([&](const Environment &Env) { + return NamespaceEndCommentsFixer(Env, Expanded).process(); + }); + + if (Style.SortUsingDeclarations) + Passes.emplace_back([&](const Environment &Env) { + return UsingDeclarationsSorter(Env, Expanded).process(); + }); } if (Style.Language == FormatStyle::LK_JavaScript && - Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) { - JavaScriptRequoter Requoter(*Env, Expanded); - return reformatAfterApplying(Requoter); + Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) + Passes.emplace_back([&](const Environment &Env) { + return JavaScriptRequoter(Env, Expanded).process(); + }); + + Passes.emplace_back([&](const Environment &Env) { + return Formatter(Env, Expanded, Status).process(); + }); + + std::unique_ptr<Environment> Env = + Environment::CreateVirtualEnvironment(Code, FileName, Ranges); + llvm::Optional<std::string> CurrentCode = None; + tooling::Replacements Fixes; + for (size_t I = 0, E = Passes.size(); I < E; ++I) { + tooling::Replacements PassFixes = Passes[I](*Env); + auto NewCode = applyAllReplacements( + CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes); + if (NewCode) { + Fixes = Fixes.merge(PassFixes); + if (I + 1 < E) { + CurrentCode = std::move(*NewCode); + Env = Environment::CreateVirtualEnvironment( + *CurrentCode, FileName, + tooling::calculateRangesAfterReplacements(Fixes, Ranges)); + } + } } - Formatter Format(*Env, Expanded, Status); - return Format.process(); + return Fixes; } tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index b43f735d4c..64bb28e0be 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -9333,6 +9333,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(Cpp11BracedListStyle); CHECK_PARSE_BOOL(ReflowComments); CHECK_PARSE_BOOL(SortIncludes); + CHECK_PARSE_BOOL(SortUsingDeclarations); CHECK_PARSE_BOOL(SpacesInParentheses); CHECK_PARSE_BOOL(SpacesInSquareBrackets); CHECK_PARSE_BOOL(SpacesInAngles); @@ -10874,6 +10875,13 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) { EXPECT_EQ(Expected, *Result); } +TEST_F(FormatTest, FormatSortsUsingDeclarations) { + EXPECT_EQ("using std::cin;\n" + "using std::cout;", + format("using std::cout;\n" + "using std::cin;", getGoogleStyle())); +} + TEST_F(FormatTest, UTF8CharacterLiteralCpp03) { format::FormatStyle Style = format::getLLVMStyle(); Style.Standard = FormatStyle::LS_Cpp03; |