Febbe created this revision.
Herald added a project: All.
Febbe requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change aims to remove all duplicate include directives, 
instead of only those, which are in the same block.

This change might be a bit controversial, since it will also remove includes, 
which are in custom splitted blocks like:

  #include "a.h"
  /* some code */
  
  // following include must stay!:
  #include "a.h"

This is a follow up patch for D143691 <https://reviews.llvm.org/D143691>, but 
can be freestanding.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143870

Files:
  clang/lib/Format/Format.cpp
  clang/unittests/Format/SortIncludesTest.cpp

Index: clang/unittests/Format/SortIncludesTest.cpp
===================================================================
--- clang/unittests/Format/SortIncludesTest.cpp
+++ clang/unittests/Format/SortIncludesTest.cpp
@@ -268,9 +268,7 @@
             "#include <b>\n"
             "#include <c>\n"
             "/* clang-format offically */\n"
-            "#include <a>\n"
-            "#include <b>\n"
-            "#include <c>\n"
+            "\n"
             "/* clang-format onwards */\n",
             sort("#include <b>\n"
                  "#include <a>\n"
@@ -899,6 +897,19 @@
                  "\n"
                  "#include <c>\n"
                  "#include <b>\n"));
+
+  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
+  EXPECT_EQ("#include \"MyProject/MyLibrary/c_main.h\"\n"
+            "\n"
+            "#include <MyProject/MySubLibrary/MySubClass.h>\n"
+            "//\n",
+            sort("#include \"MyProject/MyLibrary/c_main.h\"\n"
+                 "#include \"MyProject/MyLibrary/c_main.h\"\n"
+                 "#include <MyProject/MySubLibrary/MySubClass.h>\n"
+                 "#include <MyProject/MySubLibrary/MySubClass.h>\n"
+                 "//\n"
+                 "#include <MyProject/MySubLibrary/MySubClass.h>\n",
+                 "c_main.cpp", 2U));
 }
 
 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
@@ -924,11 +935,10 @@
   EXPECT_EQ(26u, newCursor(Code, 52));
 }
 
-TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
+TEST_F(SortIncludesTest, DeduplicateInAllBlocks) {
   EXPECT_EQ("#include <a>\n"
             "#include <b>\n"
             "\n"
-            "#include <b>\n"
             "#include <c>\n",
             sort("#include <a>\n"
                  "#include <b>\n"
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -38,6 +38,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Path.h"
@@ -2858,6 +2859,7 @@
 // #include in the duplicate #includes.
 static void sortCppIncludes(const FormatStyle &Style,
                             const SmallVectorImpl<IncludeDirective> &Includes,
+                            llvm::StringSet<> &AllIncludes,
                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
                             StringRef Code, tooling::Replacements &Replaces,
                             unsigned *Cursor) {
@@ -2900,12 +2902,14 @@
   }
 
   // Deduplicate #includes.
-  Indices.erase(std::unique(Indices.begin(), Indices.end(),
-                            [&](unsigned LHSI, unsigned RHSI) {
-                              return Includes[LHSI].Text.trim() ==
-                                     Includes[RHSI].Text.trim();
-                            }),
-                Indices.end());
+
+  Indices.erase(
+      std::remove_if(
+          Indices.begin(), Indices.end(),
+          [&](unsigned val) {
+            return !AllIncludes.try_emplace(Includes[val].Text.trim()).second;
+          }),
+      Indices.end());
 
   int CurrentCategory = Includes.front().Category;
 
@@ -2966,6 +2970,7 @@
                       .Default(0);
   unsigned SearchFrom = 0;
   SmallVector<StringRef, 4> Matches;
+  llvm::StringSet<> AllIncludes{};
   SmallVector<IncludeDirective, 16> IncludesInBlock;
 
   // FIXME: Do some validation, e.g. edit distance of the base name, to fix
@@ -3032,16 +3037,20 @@
             Categories.getSortIncludePriority(IncludeName, FirstIncludeBlock);
         // Todo(remove before merge): reason for removal: every header can have
         // 0,0 priority
+
         IncludesInBlock.push_back(
             {IncludeName, Line, Prev, Category, Priority});
+
       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
-        sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
-                        Replaces, Cursor);
+        sortCppIncludes(Style, IncludesInBlock, AllIncludes, Ranges, FileName,
+                        Code, Replaces, Cursor);
         IncludesInBlock.clear();
-        if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers.
+        if (Trimmed.startswith("#pragma hdrstop")) { // Precompiled headers.
           FirstIncludeBlock = true;
-        else
+          AllIncludes.clear();
+        } else {
           FirstIncludeBlock = false;
+        }
       }
     }
     if (Pos == StringRef::npos || Pos + 1 == Code.size())
@@ -3052,8 +3061,8 @@
     SearchFrom = Pos + 1;
   }
   if (!IncludesInBlock.empty()) {
-    sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
-                    Cursor);
+    sortCppIncludes(Style, IncludesInBlock, AllIncludes, Ranges, FileName, Code,
+                    Replaces, Cursor);
   }
   return Replaces;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to