r306094 - [clang-format] Add a SortUsingDeclaration option and enable it by default

Krasimir Georgiev via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 23 04:46:03 PDT 2017


Author: krasimir
Date: Fri Jun 23 06:46:03 2017
New Revision: 306094

URL: http://llvm.org/viewvc/llvm-project?rev=306094&view=rev
Log:
[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

Modified:
    cfe/trunk/docs/ClangFormatStyleOptions.rst
    cfe/trunk/include/clang/Format/Format.h
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=306094&r1=306093&r2=306094&view=diff
==============================================================================
--- cfe/trunk/docs/ClangFormatStyleOptions.rst (original)
+++ cfe/trunk/docs/ClangFormatStyleOptions.rst Fri Jun 23 06:46:03 2017
@@ -1475,6 +1475,15 @@ the configuration (without a prefix: ``A
      #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.
 

Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=306094&r1=306093&r2=306094&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Fri Jun 23 06:46:03 2017
@@ -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:

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=306094&r1=306093&r2=306094&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Fri Jun 23 06:46:03 2017
@@ -379,6 +379,7 @@ template <> struct MappingTraits<FormatS
     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 For
     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();
-  };
+  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.Language == FormatStyle::LK_Cpp &&
-      Style.FixNamespaceComments) {
-    NamespaceEndCommentsFixer CommentsFixer(*Env, Expanded);
-    return reformatAfterApplying(CommentsFixer);
+    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,

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=306094&r1=306093&r2=306094&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Jun 23 06:46:03 2017
@@ -9333,6 +9333,7 @@ TEST_F(FormatTest, ParsesConfigurationBo
   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, SortIncludesAfte
   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;




More information about the cfe-commits mailing list