1 //===------------ IncludeSorter.h - clang-tidy ----------------------------===//
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_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H
11 
12 #include "../ClangTidyCheck.h"
13 #include <string>
14 
15 namespace clang {
16 namespace tidy {
17 namespace utils {
18 
19 /// Class used by ``IncludeInserterCallback`` to record the names of the
20 /// inclusions in a given source file being processed and generate the necessary
21 /// commands to sort the inclusions according to the precedence encoded in
22 /// ``IncludeKinds``.
23 class IncludeSorter {
24 public:
25   /// Supported include styles.
26   enum IncludeStyle { IS_LLVM = 0, IS_Google = 1, IS_Google_ObjC };
27 
28   /// The classifications of inclusions, in the order they should be sorted.
29   enum IncludeKinds {
30     IK_MainTUInclude = 0,    ///< e.g. ``#include "foo.h"`` when editing foo.cc
31     IK_CSystemInclude = 1,   ///< e.g. ``#include <stdio.h>``
32     IK_CXXSystemInclude = 2, ///< e.g. ``#include <vector>``
33     IK_NonSystemInclude = 3, ///< e.g. ``#include "bar.h"``
34     IK_GeneratedInclude = 4, ///< e.g. ``#include "bar.proto.h"``
35     IK_InvalidInclude = 5    ///< total number of valid ``IncludeKind``s
36   };
37 
38   /// ``IncludeSorter`` constructor; takes the FileID and name of the file to be
39   /// processed by the sorter.
40   IncludeSorter(const SourceManager *SourceMgr, const FileID FileID,
41                 StringRef FileName, IncludeStyle Style);
42 
43   /// Adds the given include directive to the sorter.
44   void AddInclude(StringRef FileName, bool IsAngled,
45                   SourceLocation HashLocation, SourceLocation EndLocation);
46 
47   /// Creates a quoted inclusion directive in the right sort order. Returns None
48   /// on error or if header inclusion directive for header already exists.
49   Optional<FixItHint> CreateIncludeInsertion(StringRef FileName, bool IsAngled);
50 
51 private:
52   typedef SmallVector<SourceRange, 1> SourceRangeVector;
53 
54   const SourceManager *SourceMgr;
55   const IncludeStyle Style;
56   FileID CurrentFileID;
57   /// The file name stripped of common suffixes.
58   StringRef CanonicalFile;
59   /// Locations of visited include directives.
60   SourceRangeVector SourceLocations;
61   /// Mapping from file name to #include locations.
62   llvm::StringMap<SourceRangeVector> IncludeLocations;
63   /// Includes sorted into buckets.
64   SmallVector<std::string, 1> IncludeBucket[IK_InvalidInclude];
65 };
66 
67 } // namespace utils
68 
69 template <> struct OptionEnumMapping<utils::IncludeSorter::IncludeStyle> {
70   static ArrayRef<std::pair<utils::IncludeSorter::IncludeStyle, StringRef>>
71   getEnumMapping();
72 };
73 } // namespace tidy
74 } // namespace clang
75 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H
76