28 IncludeSorter::IncludeStyle Style) {
35 if (Style == IncludeSorter::IS_LLVM) {
39 if (Style == IncludeSorter::IS_Google_ObjC) {
40 const StringRef Canonical =
42 ".hpp",
".mm",
".m"}),
43 {
"_unittest",
"_regtest",
"_test",
"Test"});
47 size_t StartIndex = Canonical.find_last_of(
'/');
48 if (StartIndex == StringRef::npos) {
51 return Canonical.substr(0, Canonical.find_first_of(
'+', StartIndex));
55 {
"_unittest",
"_regtest",
"_test"});
66 bool IsAngled, IncludeSorter::IncludeStyle Style) {
74 return IncludeFile.ends_with(
".h") ? IncludeSorter::IK_CSystemInclude
75 : IncludeSorter::IK_CXXSystemInclude;
78 if (CanonicalFile.ends_with(CanonicalInclude) ||
79 CanonicalInclude.ends_with(CanonicalFile)) {
80 return IncludeSorter::IK_MainTUInclude;
82 if ((Style == IncludeSorter::IS_Google) ||
83 (Style == IncludeSorter::IS_Google_ObjC)) {
84 const std::pair<StringRef, StringRef> Parts =
85 CanonicalInclude.split(
"/public/");
86 StringRef FileCopy = CanonicalFile;
87 if (FileCopy.consume_front(Parts.first) &&
88 FileCopy.consume_back(Parts.second)) {
90 if (FileCopy ==
"/internal/" || FileCopy ==
"/proto/") {
91 return IncludeSorter::IK_MainTUInclude;
95 if (Style == IncludeSorter::IS_Google_ObjC) {
96 if (IncludeFile.ends_with(
".generated.h") ||
97 IncludeFile.ends_with(
".proto.h") ||
98 IncludeFile.ends_with(
".pbobjc.h")) {
99 return IncludeSorter::IK_GeneratedInclude;
102 return IncludeSorter::IK_NonSystemInclude;
106 IncludeSorter::IncludeStyle Style) {
107 if (Style == IncludeSorter::IncludeStyle::IS_Google_ObjC) {
108 const std::pair<const char *, const char *> &Mismatch =
109 std::mismatch(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
110 if ((Mismatch.first != LHS.end()) && (Mismatch.second != RHS.end())) {
111 if ((*Mismatch.first ==
'.') && (*Mismatch.second ==
'+')) {
114 if ((*Mismatch.first ==
'+') && (*Mismatch.second ==
'.')) {
119 return LHS.compare(RHS);
122IncludeSorter::IncludeSorter(
const SourceManager *SourceMgr, FileID FileID,
123 StringRef FileName, IncludeStyle Style)
124 : SourceMgr(SourceMgr), Style(Style), CurrentFileID(FileID),
144 determineIncludeKind(CanonicalFile, FileName, IsAngled, Style);
150IncludeSorter::createIncludeInsertion(StringRef FileName,
bool IsAngled) {
151 std::string IncludeStmt;
152 if (Style == IncludeStyle::IS_Google_ObjC) {
153 IncludeStmt = IsAngled
154 ? llvm::Twine(
"#import <" + FileName +
">\n").str()
155 : llvm::Twine(
"#import \"" + FileName +
"\"\n").str();
157 IncludeStmt = IsAngled
158 ? llvm::Twine(
"#include <" + FileName +
">\n").str()
159 : llvm::Twine(
"#include \"" + FileName +
"\"\n").str();
161 if (SourceLocations.empty()) {
164 IncludeStmt.append(
"\n");
165 return FixItHint::CreateInsertion(
166 SourceMgr->getLocForStartOfFile(CurrentFileID), IncludeStmt);
172 if (!IncludeBucket[IncludeKind].empty()) {
173 for (
const std::string &IncludeEntry : IncludeBucket[IncludeKind]) {
175 const auto &
Location = IncludeLocations[IncludeEntry][0];
176 return FixItHint::CreateInsertion(
Location.getBegin(), IncludeStmt);
178 if (FileName == IncludeEntry) {
184 const std::string &LastInclude = IncludeBucket[IncludeKind].back();
185 const SourceRange LastIncludeLocation =
186 IncludeLocations[LastInclude].back();
187 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
195 IncludeKinds NonEmptyKind = IK_InvalidInclude;
196 for (
int I = IK_InvalidInclude - 1; I >= 0; --I) {
197 if (!IncludeBucket[I].empty()) {
198 NonEmptyKind =
static_cast<IncludeKinds
>(I);
199 if (NonEmptyKind < IncludeKind)
203 if (NonEmptyKind == IK_InvalidInclude) {
207 if (NonEmptyKind < IncludeKind) {
209 const std::string &LastInclude = IncludeBucket[NonEmptyKind].back();
210 const SourceRange LastIncludeLocation =
211 IncludeLocations[LastInclude].back();
212 IncludeStmt =
'\n' + IncludeStmt;
213 return FixItHint::CreateInsertion(LastIncludeLocation.getEnd(),
217 const std::string &FirstInclude = IncludeBucket[NonEmptyKind][0];
218 const SourceRange FirstIncludeLocation =
219 IncludeLocations[FirstInclude].back();
220 IncludeStmt.append(
"\n");
221 return FixItHint::CreateInsertion(FirstIncludeLocation.getBegin(),