]> granicus.if.org Git - clang/commitdiff
clang-format: Extend detection of the "main" #include to use the filename
authorDaniel Jasper <djasper@google.com>
Mon, 21 Dec 2015 12:14:17 +0000 (12:14 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 21 Dec 2015 12:14:17 +0000 (12:14 +0000)
Before, the first (non-system) header in a file was considered to be
the main include. This is conservative as it makes clang-format change
the #include order less often. Instead implement some basic usage of
the filename itself. With this patch, clang-format considers every
header to be a main include if the header file's basename is a prefix
to the filename the #include is in.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256148 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp
unittests/Format/SortIncludesTest.cpp

index 97195aa9462a6288748b44b727e3ebb8e44c0db5..c9058a587e6eb1f103d1fde429c4d125d4501788 100644 (file)
@@ -1809,13 +1809,11 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
   //
   // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix
   // cases where the first #include is unlikely to be the main header.
-  bool LookForMainHeader = FileName.endswith(".c") ||
-                           FileName.endswith(".cc") ||
-                           FileName.endswith(".cpp")||
-                           FileName.endswith(".c++")||
-                           FileName.endswith(".cxx") ||
-                           FileName.endswith(".m")||
-                           FileName.endswith(".mm");
+  bool IsSource = FileName.endswith(".c") || FileName.endswith(".cc") ||
+                  FileName.endswith(".cpp") || FileName.endswith(".c++") ||
+                  FileName.endswith(".cxx") || FileName.endswith(".m") ||
+                  FileName.endswith(".mm");
+  StringRef FileStem = llvm::sys::path::stem(FileName);
 
   // Create pre-compiled regular expressions for the #include categories.
   SmallVector<llvm::Regex, 4> CategoryRegexs;
@@ -1838,19 +1836,19 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
     if (!FormattingOff && !Line.endswith("\\")) {
       if (IncludeRegex.match(Line, &Matches)) {
         StringRef IncludeName = Matches[2];
-        int Category;
-        if (LookForMainHeader && !IncludeName.startswith("<")) {
-          Category = 0;
-        } else {
-          Category = INT_MAX;
-          for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) {
-            if (CategoryRegexs[i].match(IncludeName)) {
-              Category = Style.IncludeCategories[i].Priority;
-              break;
-            }
+        int Category = INT_MAX;
+        for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) {
+          if (CategoryRegexs[i].match(IncludeName)) {
+            Category = Style.IncludeCategories[i].Priority;
+            break;
           }
         }
-        LookForMainHeader = false;
+        if (IsSource && Category > 0 && IncludeName.startswith("\"")) {
+          StringRef HeaderStem =
+              llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1));
+          if (FileStem.startswith(HeaderStem))
+            Category = 0;
+        }
         IncludesInBlock.push_back({IncludeName, Line, Prev, Category});
       } else if (!IncludesInBlock.empty()) {
         sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces,
index 9b0db349b04143e41d54d90a4e8569ca0a22329e..ce83091b7154b3f2d424b4ad43b7ca19d9c09f19 100644 (file)
@@ -166,11 +166,19 @@ TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
             "#include \"c.h\"\n",
             sort("#include \"llvm/a.h\"\n"
                  "#include \"c.h\"\n"
-                 "#include \"b.h\"\n"));
+                 "#include \"b.h\"\n",
+                 "a.cc"));
   EXPECT_EQ("#include \"llvm/a.h\"\n"
             "#include \"b.h\"\n"
             "#include \"c.h\"\n",
             sort("#include \"llvm/a.h\"\n"
+                 "#include \"c.h\"\n"
+                 "#include \"b.h\"\n",
+                 "a_main.cc"));
+  EXPECT_EQ("#include \"llvm/input.h\"\n"
+            "#include \"b.h\"\n"
+            "#include \"c.h\"\n",
+            sort("#include \"llvm/input.h\"\n"
                  "#include \"c.h\"\n"
                  "#include \"b.h\"\n",
                  "input.mm"));
@@ -182,15 +190,27 @@ TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
             sort("#include \"llvm/a.h\"\n"
                  "#include \"c.h\"\n"
                  "#include \"b.h\"\n",
-                 "some_header.h"));
+                 "a.h"));
 }
 
 TEST_F(SortIncludesTest, NegativePriorities) {
   Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
   EXPECT_EQ("#include \"important_os_header.h\"\n"
-            "#include \"a.h\"\n",
-            sort("#include \"a.h\"\n"
-                 "#include \"important_os_header.h\"\n"));
+            "#include \"c_main.h\"\n"
+            "#include \"a_other.h\"\n",
+            sort("#include \"c_main.h\"\n"
+                 "#include \"a_other.h\"\n"
+                 "#include \"important_os_header.h\"\n",
+                 "c_main.cc"));
+
+  // check stable when re-run
+  EXPECT_EQ("#include \"important_os_header.h\"\n"
+            "#include \"c_main.h\"\n"
+            "#include \"a_other.h\"\n",
+            sort("#include \"important_os_header.h\"\n"
+                 "#include \"c_main.h\"\n"
+                 "#include \"a_other.h\"\n",
+                 "c_main.cc"));
 }
 
 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {