r249392 - clang-format: Make IncludeCategories configurable in .clang-format file.

Daniel Jasper via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 6 04:54:22 PDT 2015


Author: djasper
Date: Tue Oct  6 06:54:18 2015
New Revision: 249392

URL: http://llvm.org/viewvc/llvm-project?rev=249392&view=rev
Log:
clang-format: Make IncludeCategories configurable in .clang-format file.

This was made much easier by introducing an IncludeCategory struct to
replace the previously used std::pair.

Also, cleaned up documentation and added examples.

Modified:
    cfe/trunk/docs/ClangFormatStyleOptions.rst
    cfe/trunk/docs/tools/dump_format_style.py
    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=249392&r1=249391&r2=249392&view=diff
==============================================================================
--- cfe/trunk/docs/ClangFormatStyleOptions.rst (original)
+++ cfe/trunk/docs/ClangFormatStyleOptions.rst Tue Oct  6 06:54:18 2015
@@ -155,21 +155,29 @@ the configuration (without a prefix: ``A
 
   This applies to round brackets (parentheses), angle brackets and square
   brackets. This will result in formattings like
-  \code
-  someLongFunction(argument1,
-  argument2);
-  \endcode
+  .. code-block:: c++
+    someLongFunction(argument1,
+                     argument2);
 
 **AlignConsecutiveAssignments** (``bool``)
   If ``true``, aligns consecutive assignments.
 
   This will align the assignment operators of consecutive lines. This
   will result in formattings like
-  \code
-  int aaaa = 12;
-  int b    = 23;
-  int ccc  = 23;
-  \endcode
+  .. code-block:: c++
+    int aaaa = 12;
+    int b    = 23;
+    int ccc  = 23;
+
+**AlignConsecutiveDeclarations** (``bool``)
+  If ``true``, aligns consecutive declarations.
+
+  This will align the declaration names of consecutive lines. This
+  will result in formattings like
+  .. code-block:: c++
+    int         aaaa = 12;
+    float       b = 23;
+    std::string ccc = 23;
 
 **AlignEscapedNewlinesLeft** (``bool``)
   If ``true``, aligns escaped newlines as far left as possible.
@@ -381,14 +389,17 @@ the configuration (without a prefix: ``A
   instead of as function calls.
 
   These are expected to be macros of the form:
-  \code
-  FOREACH(<variable-declaration>, ...)
-  <loop-body>
-  \endcode
+  .. code-block:: c++
+    FOREACH(<variable-declaration>, ...)
+      <loop-body>
+
+  In the .clang-format configuration file, this can be configured like:
+  .. code-block:: c++
+    ForEachMacros: ['RANGES_FOR', 'FOREACH']
 
   For example: BOOST_FOREACH.
 
-**IncludeCategories** (``std::vector<std::pair<std::string, unsigned>>``)
+**IncludeCategories** (``std::vector<IncludeCategory>``)
   Regular expressions denoting the different #include categories used
   for ordering #includes.
 
@@ -403,6 +414,16 @@ the configuration (without a prefix: ``A
   so that it is kept at the beginning of the #includes
   (http://llvm.org/docs/CodingStandards.html#include-style).
 
+  To configure this in the .clang-format file, use:
+  .. code-block:: c++
+    IncludeCategories:
+      - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+        Priority:        2
+      - Regex:           '^(<|"(gtest|isl|json)/)'
+        Priority:        3
+      - Regex:           '.\*'
+        Priority:        1
+
 **IndentCaseLabels** (``bool``)
   Indent case labels one level from the switch statement.
 

Modified: cfe/trunk/docs/tools/dump_format_style.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/tools/dump_format_style.py?rev=249392&r1=249391&r2=249392&view=diff
==============================================================================
--- cfe/trunk/docs/tools/dump_format_style.py (original)
+++ cfe/trunk/docs/tools/dump_format_style.py Tue Oct  6 06:54:18 2015
@@ -86,7 +86,11 @@ class EnumValue:
         doxygen2rst(indent(self.comment, 2)))
 
 def clean_comment_line(line):
-  return line[3:].strip() + '\n'
+  if line == '/// \\code':
+    return '.. code-block:: c++\n'
+  if line == '/// \\endcode':
+    return ''
+  return line[4:] + '\n'
 
 def read_options(header):
   class State:
@@ -139,8 +143,6 @@ def read_options(header):
       elif line == '};':
         state = State.InStruct
         nested_structs[nested_struct.name] = nested_struct
-      else:
-        raise Exception('Invalid format, expected struct field comment or };')
     elif state == State.InNestedFieldComent:
       if line.startswith('///'):
         comment += clean_comment_line(line)
@@ -168,7 +170,7 @@ def read_options(header):
   for option in options:
     if not option.type in ['bool', 'unsigned', 'int', 'std::string',
                            'std::vector<std::string>',
-                           'std::vector<std::pair<std::string, unsigned>>']:
+                           'std::vector<IncludeCategory>']:
       if enums.has_key(option.type):
         option.enum = enums[option.type]
       elif nested_structs.has_key(option.type):

Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=249392&r1=249391&r2=249392&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Tue Oct  6 06:54:18 2015
@@ -48,8 +48,8 @@ struct FormatStyle {
   /// This applies to round brackets (parentheses), angle brackets and square
   /// brackets. This will result in formattings like
   /// \code
-  /// someLongFunction(argument1,
-  ///                  argument2);
+  ///   someLongFunction(argument1,
+  ///                    argument2);
   /// \endcode
   bool AlignAfterOpenBracket;
 
@@ -58,9 +58,9 @@ struct FormatStyle {
   /// This will align the assignment operators of consecutive lines. This
   /// will result in formattings like
   /// \code
-  /// int aaaa = 12;
-  /// int b    = 23;
-  /// int ccc  = 23;
+  ///   int aaaa = 12;
+  ///   int b    = 23;
+  ///   int ccc  = 23;
   /// \endcode
   bool AlignConsecutiveAssignments;
 
@@ -69,9 +69,9 @@ struct FormatStyle {
   /// This will align the declaration names of consecutive lines. This
   /// will result in formattings like
   /// \code
-  /// int         aaaa = 12;
-  /// float       b = 23;
-  /// std::string ccc = 23;
+  ///   int         aaaa = 12;
+  ///   float       b = 23;
+  ///   std::string ccc = 23;
   /// \endcode
   bool AlignConsecutiveDeclarations;
 
@@ -297,13 +297,29 @@ struct FormatStyle {
   ///
   /// These are expected to be macros of the form:
   /// \code
-  /// FOREACH(<variable-declaration>, ...)
-  ///   <loop-body>
+  ///   FOREACH(<variable-declaration>, ...)
+  ///     <loop-body>
+  /// \endcode
+  ///
+  /// In the .clang-format configuration file, this can be configured like:
+  /// \code
+  ///   ForEachMacros: ['RANGES_FOR', 'FOREACH']
   /// \endcode
   ///
   /// For example: BOOST_FOREACH.
   std::vector<std::string> ForEachMacros;
 
+  /// \brief See documentation of \c IncludeCategories.
+  struct IncludeCategory {
+    /// \brief The regular expression that this category matches.
+    std::string Regex;
+    /// \brief The priority to assign to this category.
+    unsigned Priority;
+    bool operator==(const IncludeCategory &Other) const {
+      return Regex == Other.Regex && Priority == Other.Priority;
+    }
+  };
+
   /// \brief Regular expressions denoting the different #include categories used
   /// for ordering #includes.
   ///
@@ -317,7 +333,18 @@ struct FormatStyle {
   /// category. The main header for a source file automatically gets category 0,
   /// so that it is kept at the beginning of the #includes
   /// (http://llvm.org/docs/CodingStandards.html#include-style).
-  std::vector<std::pair<std::string, unsigned>> IncludeCategories;
+  ///
+  /// To configure this in the .clang-format file, use:
+  /// \code
+  ///   IncludeCategories:
+  ///     - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+  ///       Priority:        2
+  ///     - Regex:           '^(<|"(gtest|isl|json)/)'
+  ///       Priority:        3
+  ///     - Regex:           '.*'
+  ///       Priority:        1
+  /// \endcode
+  std::vector<IncludeCategory> IncludeCategories;
 
   /// \brief Indent case labels one level from the switch statement.
   ///
@@ -546,6 +573,7 @@ struct FormatStyle {
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
            ForEachMacros == R.ForEachMacros &&
+           IncludeCategories == R.IncludeCategories &&
            IndentCaseLabels == R.IndentCaseLabels &&
            IndentWidth == R.IndentWidth && Language == R.Language &&
            IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=249392&r1=249391&r2=249392&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Tue Oct  6 06:54:18 2015
@@ -37,6 +37,7 @@
 using clang::format::FormatStyle;
 
 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::IncludeCategory)
 
 namespace llvm {
 namespace yaml {
@@ -247,6 +248,7 @@ template <> struct MappingTraits<FormatS
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
+    IO.mapOptional("IncludeCategories", Style.IncludeCategories);
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
     IO.mapOptional("IndentWidth", Style.IndentWidth);
     IO.mapOptional("IndentWrappedFunctionNames",
@@ -307,6 +309,13 @@ template <> struct MappingTraits<FormatS
   }
 };
 
+template <> struct MappingTraits<FormatStyle::IncludeCategory> {
+  static void mapping(IO &IO, FormatStyle::IncludeCategory &Category) {
+    IO.mapOptional("Regex", Category.Regex);
+    IO.mapOptional("Priority", Category.Priority);
+  }
+};
+
 // Allows to read vector<FormatStyle> while keeping default values.
 // IO.getContext() should contain a pointer to the FormatStyle structure, that
 // will be used to get default values for missing keys.
@@ -1737,8 +1746,8 @@ tooling::Replacements sortIncludes(const
 
   // Create pre-compiled regular expressions for the #include categories.
   SmallVector<llvm::Regex, 4> CategoryRegexs;
-  for (const auto &IncludeBlock : Style.IncludeCategories)
-    CategoryRegexs.emplace_back(IncludeBlock.first);
+  for (const auto &Category : Style.IncludeCategories)
+    CategoryRegexs.emplace_back(Category.Regex);
 
   for (;;) {
     auto Pos = Code.find('\n', SearchFrom);
@@ -1753,7 +1762,7 @@ tooling::Replacements sortIncludes(const
           Category = UINT_MAX;
           for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) {
             if (CategoryRegexs[i].match(Matches[1])) {
-              Category = Style.IncludeCategories[i].second;
+              Category = Style.IncludeCategories[i].Priority;
               break;
             }
           }

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=249392&r1=249391&r2=249392&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Oct  6 06:54:18 2015
@@ -9646,6 +9646,8 @@ TEST_F(FormatTest, ParsesConfiguration)
   CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
               FormatStyle::NI_All);
 
+  // FIXME: This is required because parsing a configuration simply overwrites
+  // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
   std::vector<std::string> BoostForeach;
   BoostForeach.push_back("BOOST_FOREACH");
@@ -9655,6 +9657,16 @@ TEST_F(FormatTest, ParsesConfiguration)
   BoostAndQForeach.push_back("Q_FOREACH");
   CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
               BoostAndQForeach);
+
+  Style.IncludeCategories.clear();
+  std::vector<FormatStyle::IncludeCategory> ExpectedCategories = {{"abc/.*", 2},
+                                                                  {".*", 1}};
+  CHECK_PARSE("IncludeCategories:\n"
+              "  - Regex: abc/.*\n"
+              "    Priority: 2\n"
+              "  - Regex: .*\n"
+              "    Priority: 1",
+              IncludeCategories, ExpectedCategories);
 }
 
 TEST_F(FormatTest, ParsesConfigurationWithLanguages) {




More information about the cfe-commits mailing list