27 IncludeSorter::IncludeStyle Style) {
34 if (Style == IncludeSorter::IS_LLVM) {
38 if (Style == IncludeSorter::IS_Google_ObjC) {
39 const StringRef Canonical =
41 ".hpp",
".mm",
".m"}),
42 {
"_unittest",
"_regtest",
"_test",
"Test"});
46 size_t StartIndex = Canonical.find_last_of(
'/');
47 if (StartIndex == StringRef::npos)
49 return Canonical.substr(0, Canonical.find_first_of(
'+', StartIndex));
53 {
"_unittest",
"_regtest",
"_test"});
64 bool IsAngled, IncludeSorter::IncludeStyle Style) {
72 return IncludeFile.ends_with(
".h") ? IncludeSorter::IK_CSystemInclude
73 : IncludeSorter::IK_CXXSystemInclude;
76 if (CanonicalFile.ends_with(CanonicalInclude) ||
77 CanonicalInclude.ends_with(CanonicalFile)) {
78 return IncludeSorter::IK_MainTUInclude;
80 if ((Style == IncludeSorter::IS_Google) ||
81 (Style == IncludeSorter::IS_Google_ObjC)) {
82 const std::pair<StringRef, StringRef> Parts =
83 CanonicalInclude.split(
"/public/");
84 StringRef FileCopy = CanonicalFile;
85 if (FileCopy.consume_front(Parts.first) &&
86 FileCopy.consume_back(Parts.second)) {
88 if (FileCopy ==
"/internal/" || FileCopy ==
"/proto/")
89 return IncludeSorter::IK_MainTUInclude;
92 if (Style == IncludeSorter::IS_Google_ObjC) {
93 if (IncludeFile.ends_with(
".generated.h") ||
94 IncludeFile.ends_with(
".proto.h") ||
95 IncludeFile.ends_with(
".pbobjc.h")) {
96 return IncludeSorter::IK_GeneratedInclude;
99 return IncludeSorter::IK_NonSystemInclude;
103 IncludeSorter::IncludeStyle Style) {
104 if (Style == IncludeSorter::IncludeStyle::IS_Google_ObjC) {
105 const std::pair<const char *, const char *> &Mismatch =
106 std::mismatch(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
107 if ((Mismatch.first != LHS.end()) && (Mismatch.second != RHS.end())) {
108 if ((*Mismatch.first ==
'.') && (*Mismatch.second ==
'+'))
110 if ((*Mismatch.first ==
'+') && (*Mismatch.second ==
'.'))
114 return LHS.compare(RHS);
117IncludeSorter::IncludeSorter(
const SourceManager *SourceMgr, FileID FileID,
118 StringRef FileName, IncludeStyle Style)
119 : SourceMgr(SourceMgr), Style(Style), CurrentFileID(FileID),
139 determineIncludeKind(CanonicalFile, FileName, IsAngled, Style);
145IncludeSorter::createIncludeInsertion(StringRef FileName,
bool IsAngled) {
146 std::string IncludeStmt;
147 if (Style == IncludeStyle::IS_Google_ObjC) {
148 IncludeStmt = IsAngled
149 ? llvm::Twine(
"#import <" + FileName +
">\n").str()
150 : llvm::Twine(
"#import \"" + FileName +
"\"\n").str();
152 IncludeStmt = IsAngled
153 ? llvm::Twine(
"#include <" + FileName +
">\n").str()
154 : llvm::Twine(
"#include \"" + FileName +
"\"\n").str();
156 if (SourceLocations.empty()) {
159 IncludeStmt.append(
"\n");
160 return FixItHint::CreateInsertion(
161 SourceMgr->getLocForStartOfFile(CurrentFileID), IncludeStmt);
167 if (!IncludeBucket[IncludeKind].empty()) {
168 for (
const std::string &IncludeEntry : IncludeBucket[IncludeKind]) {
170 const auto &
Location = IncludeLocations[IncludeEntry][0];
171 return FixItHint::CreateInsertion(
Location.getBegin(), IncludeStmt);
173 if (FileName == IncludeEntry)
178 const std::string &LastInclude = IncludeBucket[IncludeKind].back();
179 const SourceRange LastIncludeLocation =
180 IncludeLocations[LastInclude].back();
181 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
189 IncludeKinds NonEmptyKind = IK_InvalidInclude;
190 for (
int I = IK_InvalidInclude - 1; I >= 0; --I) {
191 if (!IncludeBucket[I].empty()) {
192 NonEmptyKind =
static_cast<IncludeKinds
>(I);
193 if (NonEmptyKind < IncludeKind)
197 if (NonEmptyKind == IK_InvalidInclude)
200 if (NonEmptyKind < IncludeKind) {
202 const std::string &LastInclude = IncludeBucket[NonEmptyKind].back();
203 const SourceRange LastIncludeLocation =
204 IncludeLocations[LastInclude].back();
205 IncludeStmt =
'\n' + IncludeStmt;
206 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
210 const std::string &FirstInclude = IncludeBucket[NonEmptyKind][0];
211 const SourceRange FirstIncludeLocation =
212 IncludeLocations[FirstInclude].back();
213 IncludeStmt.append(
"\n");
214 return FixItHint::CreateInsertion(FirstIncludeLocation.getBegin(),