r263943 - clang-format: Make include sorting's main include detection configurable.

Daniel Jasper via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 21 07:11:27 PDT 2016


Author: djasper
Date: Mon Mar 21 09:11:27 2016
New Revision: 263943

URL: http://llvm.org/viewvc/llvm-project?rev=263943&view=rev
Log:
clang-format: Make include sorting's main include detection configurable.

This patch adds a regular expression to configure suffixes of an
included file to check whether it is the "main" include of the current
file. Previously, clang-format has allowed arbitrary suffixes on the
formatted file, which is still the case when no IncludeMainRegex is
specified.

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
    cfe/trunk/unittests/Format/SortIncludesTest.cpp

Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=263943&r1=263942&r2=263943&view=diff
==============================================================================
--- cfe/trunk/docs/ClangFormatStyleOptions.rst (original)
+++ cfe/trunk/docs/ClangFormatStyleOptions.rst Mon Mar 21 09:11:27 2016
@@ -519,6 +519,19 @@ the configuration (without a prefix: ``A
       - Regex:           '.\*'
         Priority:        1
 
+**IncludeIsMainRegex** (``std::string``)
+  Specify a regular expression of suffixes that are allowed in the
+  file-to-main-include mapping.
+
+  When guessing whether a #include is the "main" include (to assign
+  category 0, see above), use this regex of allowed suffixes to the header
+  stem. A partial match is done, so that:
+  - "" means "arbitrary suffix"
+  - "$" means "no suffix"
+
+  For example, if configured to "(_test)?$", then a header a.h would be seen
+  as the "main" include in both a.cc and a_test.cc.
+
 **IndentCaseLabels** (``bool``)
   Indent case labels one level from the switch statement.
 
@@ -532,6 +545,22 @@ the configuration (without a prefix: ``A
   Indent if a function definition or declaration is wrapped after the
   type.
 
+**JavaScriptQuotes** (``JavaScriptQuoteStyle``)
+  The JavaScriptQuoteStyle to use for JavaScript strings.
+
+  Possible values:
+
+  * ``JSQS_Leave`` (in configuration: ``Leave``)
+    Leave string quotes as they are.
+
+  * ``JSQS_Single`` (in configuration: ``Single``)
+    Always use single quotes.
+
+  * ``JSQS_Double`` (in configuration: ``Double``)
+    Always use double quotes.
+
+
+
 **KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
   If true, empty lines at the start of blocks are kept.
 

Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=263943&r1=263942&r2=263943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Mon Mar 21 09:11:27 2016
@@ -401,6 +401,19 @@ struct FormatStyle {
   /// \endcode
   std::vector<IncludeCategory> IncludeCategories;
 
+  /// \brief Specify a regular expression of suffixes that are allowed in the
+  /// file-to-main-include mapping.
+  ///
+  /// When guessing whether a #include is the "main" include (to assign
+  /// category 0, see above), use this regex of allowed suffixes to the header
+  /// stem. A partial match is done, so that:
+  /// - "" means "arbitrary suffix"
+  /// - "$" means "no suffix"
+  ///
+  /// For example, if configured to "(_test)?$", then a header a.h would be seen
+  /// as the "main" include in both a.cc and a_test.cc.
+  std::string IncludeIsMainRegex;
+
   /// \brief Indent case labels one level from the switch statement.
   ///
   /// When ``false``, use the same indentation level as for the switch statement.

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=263943&r1=263942&r2=263943&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Mon Mar 21 09:11:27 2016
@@ -300,6 +300,7 @@ template <> struct MappingTraits<FormatS
                    Style.ExperimentalAutoDetectBinPacking);
     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
     IO.mapOptional("IncludeCategories", Style.IncludeCategories);
+    IO.mapOptional("IncludeIsMainRegex", Style.IncludeIsMainRegex);
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
     IO.mapOptional("IndentWidth", Style.IndentWidth);
     IO.mapOptional("IndentWrappedFunctionNames",
@@ -517,6 +518,7 @@ FormatStyle getLLVMStyle() {
   LLVMStyle.IncludeCategories = {{"^\"(llvm|llvm-c|clang|clang-c)/", 2},
                                  {"^(<|\"(gtest|isl|json)/)", 3},
                                  {".*", 1}};
+  LLVMStyle.IncludeIsMainRegex = "$";
   LLVMStyle.IndentCaseLabels = false;
   LLVMStyle.IndentWrappedFunctionNames = false;
   LLVMStyle.IndentWidth = 2;
@@ -569,6 +571,7 @@ FormatStyle getGoogleStyle(FormatStyle::
   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
   GoogleStyle.DerivePointerAlignment = true;
   GoogleStyle.IncludeCategories = {{"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}};
+  GoogleStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
   GoogleStyle.IndentCaseLabels = true;
   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
   GoogleStyle.ObjCSpaceAfterProperty = false;
@@ -1961,8 +1964,12 @@ tooling::Replacements sortIncludes(const
           StringRef HeaderStem =
               llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1));
           if (FileStem.startswith(HeaderStem)) {
-            Category = 0;
-            MainIncludeFound = true;
+            llvm::Regex MainIncludeRegex(
+                (HeaderStem + Style.IncludeIsMainRegex).str());
+            if (MainIncludeRegex.match(FileStem)) {
+              Category = 0;
+              MainIncludeFound = true;
+            }
           }
         }
         IncludesInBlock.push_back({IncludeName, Line, Prev, Category});

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=263943&r1=263942&r2=263943&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Mar 21 09:11:27 2016
@@ -9941,6 +9941,7 @@ TEST_F(FormatTest, ParsesConfiguration)
               SpacesBeforeTrailingComments, 1234u);
   CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u);
   CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
+  CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
 
   Style.PointerAlignment = FormatStyle::PAS_Middle;
   CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
@@ -10099,6 +10100,7 @@ TEST_F(FormatTest, ParsesConfiguration)
               "  - Regex: .*\n"
               "    Priority: 1",
               IncludeCategories, ExpectedCategories);
+  CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$");
 }
 
 TEST_F(FormatTest, ParsesConfigurationWithLanguages) {

Modified: cfe/trunk/unittests/Format/SortIncludesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/SortIncludesTest.cpp?rev=263943&r1=263942&r2=263943&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/SortIncludesTest.cpp (original)
+++ cfe/trunk/unittests/Format/SortIncludesTest.cpp Mon Mar 21 09:11:27 2016
@@ -175,6 +175,7 @@ TEST_F(SortIncludesTest, HandlesMultilin
 }
 
 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
+  Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
   EXPECT_EQ("#include \"llvm/a.h\"\n"
             "#include \"b.h\"\n"
             "#include \"c.h\"\n",
@@ -188,7 +189,7 @@ TEST_F(SortIncludesTest, LeavesMainHeade
             sort("#include \"llvm/a.h\"\n"
                  "#include \"c.h\"\n"
                  "#include \"b.h\"\n",
-                 "a_main.cc"));
+                 "a_test.cc"));
   EXPECT_EQ("#include \"llvm/input.h\"\n"
             "#include \"b.h\"\n"
             "#include \"c.h\"\n",
@@ -197,6 +198,24 @@ TEST_F(SortIncludesTest, LeavesMainHeade
                  "#include \"b.h\"\n",
                  "input.mm"));
 
+  // Don't allow prefixes.
+  EXPECT_EQ("#include \"b.h\"\n"
+            "#include \"c.h\"\n"
+            "#include \"llvm/not_a.h\"\n",
+            sort("#include \"llvm/not_a.h\"\n"
+                 "#include \"c.h\"\n"
+                 "#include \"b.h\"\n",
+                 "a.cc"));
+
+  // Don't do this for _main and other suffixes.
+  EXPECT_EQ("#include \"b.h\"\n"
+            "#include \"c.h\"\n"
+            "#include \"llvm/a.h\"\n",
+            sort("#include \"llvm/a.h\"\n"
+                 "#include \"c.h\"\n"
+                 "#include \"b.h\"\n",
+                 "a_main.cc"));
+
   // Don't do this in headers.
   EXPECT_EQ("#include \"b.h\"\n"
             "#include \"c.h\"\n"




More information about the cfe-commits mailing list