26 IncludeSorter::IncludeStyle Style) {
33 if (Style == IncludeSorter::IS_LLVM) {
37 if (Style == IncludeSorter::IS_Google_ObjC) {
38 const StringRef Canonical =
40 ".hpp",
".mm",
".m"}),
41 {
"_unittest",
"_regtest",
"_test",
"Test"});
45 size_t StartIndex = Canonical.find_last_of(
'/');
46 if (StartIndex == StringRef::npos)
48 return Canonical.substr(0, Canonical.find_first_of(
'+', StartIndex));
52 {
"_unittest",
"_regtest",
"_test"});
63 bool IsAngled, IncludeSorter::IncludeStyle Style) {
71 return IncludeFile.ends_with(
".h") ? IncludeSorter::IK_CSystemInclude
72 : IncludeSorter::IK_CXXSystemInclude;
75 if (CanonicalFile.ends_with(CanonicalInclude) ||
76 CanonicalInclude.ends_with(CanonicalFile)) {
77 return IncludeSorter::IK_MainTUInclude;
79 if ((Style == IncludeSorter::IS_Google) ||
80 (Style == IncludeSorter::IS_Google_ObjC)) {
81 const std::pair<StringRef, StringRef> Parts =
82 CanonicalInclude.split(
"/public/");
83 StringRef FileCopy = CanonicalFile;
84 if (FileCopy.consume_front(Parts.first) &&
85 FileCopy.consume_back(Parts.second)) {
87 if (FileCopy ==
"/internal/" || FileCopy ==
"/proto/")
88 return IncludeSorter::IK_MainTUInclude;
91 if (Style == IncludeSorter::IS_Google_ObjC) {
92 if (IncludeFile.ends_with(
".generated.h") ||
93 IncludeFile.ends_with(
".proto.h") ||
94 IncludeFile.ends_with(
".pbobjc.h")) {
95 return IncludeSorter::IK_GeneratedInclude;
98 return IncludeSorter::IK_NonSystemInclude;
102 IncludeSorter::IncludeStyle Style) {
103 if (Style == IncludeSorter::IncludeStyle::IS_Google_ObjC) {
104 const std::pair<const char *, const char *> &Mismatch =
105 llvm::mismatch(LHS, RHS);
106 if ((Mismatch.first != LHS.end()) && (Mismatch.second != RHS.end())) {
107 if ((*Mismatch.first ==
'.') && (*Mismatch.second ==
'+'))
109 if ((*Mismatch.first ==
'+') && (*Mismatch.second ==
'.'))
113 return LHS.compare(RHS);
116IncludeSorter::IncludeSorter(
const SourceManager *SourceMgr, FileID FileID,
117 StringRef FileName, IncludeStyle Style)
118 : SourceMgr(SourceMgr), Style(Style), CurrentFileID(FileID),
138 determineIncludeKind(CanonicalFile, FileName, IsAngled, Style);
144IncludeSorter::createIncludeInsertion(StringRef FileName,
bool IsAngled) {
145 std::string IncludeStmt;
146 if (Style == IncludeStyle::IS_Google_ObjC) {
147 IncludeStmt = IsAngled
148 ? llvm::Twine(
"#import <" + FileName +
">\n").str()
149 : llvm::Twine(
"#import \"" + FileName +
"\"\n").str();
151 IncludeStmt = IsAngled
152 ? llvm::Twine(
"#include <" + FileName +
">\n").str()
153 : llvm::Twine(
"#include \"" + FileName +
"\"\n").str();
155 if (SourceLocations.empty()) {
158 IncludeStmt.append(
"\n");
159 return FixItHint::CreateInsertion(
160 SourceMgr->getLocForStartOfFile(CurrentFileID), IncludeStmt);
166 if (!IncludeBucket[IncludeKind].empty()) {
167 for (
const std::string &IncludeEntry : IncludeBucket[IncludeKind]) {
169 const auto &
Location = IncludeLocations[IncludeEntry][0];
170 return FixItHint::CreateInsertion(
Location.getBegin(), IncludeStmt);
172 if (FileName == IncludeEntry)
177 const std::string &LastInclude = IncludeBucket[IncludeKind].back();
178 const SourceRange LastIncludeLocation =
179 IncludeLocations[LastInclude].back();
180 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
188 IncludeKinds NonEmptyKind = IK_InvalidInclude;
189 for (
int I = IK_InvalidInclude - 1; I >= 0; --I) {
190 if (!IncludeBucket[I].empty()) {
191 NonEmptyKind =
static_cast<IncludeKinds
>(I);
192 if (NonEmptyKind < IncludeKind)
196 if (NonEmptyKind == IK_InvalidInclude)
199 if (NonEmptyKind < IncludeKind) {
201 const std::string &LastInclude = IncludeBucket[NonEmptyKind].back();
202 const SourceRange LastIncludeLocation =
203 IncludeLocations[LastInclude].back();
204 IncludeStmt =
'\n' + IncludeStmt;
205 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
209 const std::string &FirstInclude = IncludeBucket[NonEmptyKind][0];
210 const SourceRange FirstIncludeLocation =
211 IncludeLocations[FirstInclude].back();
212 IncludeStmt.append(
"\n");
213 return FixItHint::CreateInsertion(FirstIncludeLocation.getBegin(),