Home | History | Annotate | Line # | Download | only in Inclusions
      1 //===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
     10 #define LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
     11 
     12 #include "llvm/Support/YAMLTraits.h"
     13 #include <string>
     14 #include <vector>
     15 
     16 namespace clang {
     17 namespace tooling {
     18 
     19 /// Style for sorting and grouping C++ #include directives.
     20 struct IncludeStyle {
     21   /// Styles for sorting multiple ``#include`` blocks.
     22   enum IncludeBlocksStyle {
     23     /// Sort each ``#include`` block separately.
     24     /// \code
     25     ///    #include "b.h"               into      #include "b.h"
     26     ///
     27     ///    #include <lib/main.h>                  #include "a.h"
     28     ///    #include "a.h"                         #include <lib/main.h>
     29     /// \endcode
     30     IBS_Preserve,
     31     /// Merge multiple ``#include`` blocks together and sort as one.
     32     /// \code
     33     ///    #include "b.h"               into      #include "a.h"
     34     ///                                           #include "b.h"
     35     ///    #include <lib/main.h>                  #include <lib/main.h>
     36     ///    #include "a.h"
     37     /// \endcode
     38     IBS_Merge,
     39     /// Merge multiple ``#include`` blocks together and sort as one.
     40     /// Then split into groups based on category priority. See
     41     /// ``IncludeCategories``.
     42     /// \code
     43     ///    #include "b.h"               into      #include "a.h"
     44     ///                                           #include "b.h"
     45     ///    #include <lib/main.h>
     46     ///    #include "a.h"                         #include <lib/main.h>
     47     /// \endcode
     48     IBS_Regroup,
     49   };
     50 
     51   /// Dependent on the value, multiple ``#include`` blocks can be sorted
     52   /// as one and divided based on category.
     53   IncludeBlocksStyle IncludeBlocks;
     54 
     55   /// See documentation of ``IncludeCategories``.
     56   struct IncludeCategory {
     57     /// The regular expression that this category matches.
     58     std::string Regex;
     59     /// The priority to assign to this category.
     60     int Priority;
     61     /// The custom priority to sort before grouping.
     62     int SortPriority;
     63     /// If the regular expression is case sensitive.
     64     bool RegexIsCaseSensitive;
     65     bool operator==(const IncludeCategory &Other) const {
     66       return Regex == Other.Regex && Priority == Other.Priority &&
     67              RegexIsCaseSensitive == Other.RegexIsCaseSensitive;
     68     }
     69   };
     70 
     71   /// Regular expressions denoting the different ``#include`` categories
     72   /// used for ordering ``#includes``.
     73   ///
     74   /// `POSIX extended
     75   /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
     76   /// regular expressions are supported.
     77   ///
     78   /// These regular expressions are matched against the filename of an include
     79   /// (including the <> or "") in order. The value belonging to the first
     80   /// matching regular expression is assigned and ``#includes`` are sorted first
     81   /// according to increasing category number and then alphabetically within
     82   /// each category.
     83   ///
     84   /// If none of the regular expressions match, INT_MAX is assigned as
     85   /// category. The main header for a source file automatically gets category 0.
     86   /// so that it is generally kept at the beginning of the ``#includes``
     87   /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you
     88   /// can also assign negative priorities if you have certain headers that
     89   /// always need to be first.
     90   ///
     91   /// There is a third and optional field ``SortPriority`` which can used while
     92   /// ``IncludeBlocks = IBS_Regroup`` to define the priority in which
     93   /// ``#includes`` should be ordered. The value of ``Priority`` defines the
     94   /// order of ``#include blocks`` and also allows the grouping of ``#includes``
     95   /// of different priority. ``SortPriority`` is set to the value of
     96   /// ``Priority`` as default if it is not assigned.
     97   ///
     98   /// Each regular expression can be marked as case sensitive with the field
     99   /// ``CaseSensitive``, per default it is not.
    100   ///
    101   /// To configure this in the .clang-format file, use:
    102   /// \code{.yaml}
    103   ///   IncludeCategories:
    104   ///     - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
    105   ///       Priority:        2
    106   ///       SortPriority:    2
    107   ///       CaseSensitive:   true
    108   ///     - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
    109   ///       Priority:        3
    110   ///     - Regex:           '<[[:alnum:].]+>'
    111   ///       Priority:        4
    112   ///     - Regex:           '.*'
    113   ///       Priority:        1
    114   ///       SortPriority:    0
    115   /// \endcode
    116   std::vector<IncludeCategory> IncludeCategories;
    117 
    118   /// Specify a regular expression of suffixes that are allowed in the
    119   /// file-to-main-include mapping.
    120   ///
    121   /// When guessing whether a #include is the "main" include (to assign
    122   /// category 0, see above), use this regex of allowed suffixes to the header
    123   /// stem. A partial match is done, so that:
    124   /// - "" means "arbitrary suffix"
    125   /// - "$" means "no suffix"
    126   ///
    127   /// For example, if configured to "(_test)?$", then a header a.h would be seen
    128   /// as the "main" include in both a.cc and a_test.cc.
    129   std::string IncludeIsMainRegex;
    130 
    131   /// Specify a regular expression for files being formatted
    132   /// that are allowed to be considered "main" in the
    133   /// file-to-main-include mapping.
    134   ///
    135   /// By default, clang-format considers files as "main" only when they end
    136   /// with: ``.c``, ``.cc``, ``.cpp``, ``.c++``, ``.cxx``, ``.m`` or ``.mm``
    137   /// extensions.
    138   /// For these files a guessing of "main" include takes place
    139   /// (to assign category 0, see above). This config option allows for
    140   /// additional suffixes and extensions for files to be considered as "main".
    141   ///
    142   /// For example, if this option is configured to ``(Impl\.hpp)$``,
    143   /// then a file ``ClassImpl.hpp`` is considered "main" (in addition to
    144   /// ``Class.c``, ``Class.cc``, ``Class.cpp`` and so on) and "main
    145   /// include file" logic will be executed (with *IncludeIsMainRegex* setting
    146   /// also being respected in later phase). Without this option set,
    147   /// ``ClassImpl.hpp`` would not have the main include file put on top
    148   /// before any other include.
    149   std::string IncludeIsMainSourceRegex;
    150 };
    151 
    152 } // namespace tooling
    153 } // namespace clang
    154 
    155 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory)
    156 
    157 namespace llvm {
    158 namespace yaml {
    159 
    160 template <>
    161 struct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> {
    162   static void mapping(IO &IO,
    163                       clang::tooling::IncludeStyle::IncludeCategory &Category);
    164 };
    165 
    166 template <>
    167 struct ScalarEnumerationTraits<
    168     clang::tooling::IncludeStyle::IncludeBlocksStyle> {
    169   static void
    170   enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value);
    171 };
    172 
    173 } // namespace yaml
    174 } // namespace llvm
    175 
    176 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
    177