summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-06-23 11:46:03 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-06-23 11:46:03 +0000
commit598aad0fe0d99790d34390533e51e3d0e85531ef (patch)
treef107f40c5f661836791205db8444e72df6699acb
parent4c8bc8646c93899503aa9efbb92832e952c4bbec (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.rst9
-rw-r--r--include/clang/Format/Format.h8
-rw-r--r--lib/Format/Format.cpp70
-rw-r--r--unittests/Format/FormatTest.cpp8
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;