11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/Path.h"
17 #define DEBUG_TYPE "clang-include-fixer"
20 namespace include_fixer {
23 using find_all_symbols::SymbolAndSignals;
28 llvm::StringRef Header) {
35 for (
auto FileI = llvm::sys::path::begin(
FileName),
36 FileE = llvm::sys::path::end(
FileName);
37 FileI != FileE; ++FileI) {
39 for (
auto HeaderI = llvm::sys::path::begin(Header),
40 HeaderE = llvm::sys::path::end(Header), I = FileI;
41 HeaderI != HeaderE && *I == *HeaderI && I != FileE; ++I, ++HeaderI) {
44 MaxSegments = std::max(Segments, MaxSegments);
49 static void rank(std::vector<SymbolAndSignals> &Symbols,
51 llvm::StringMap<double>
Score;
52 for (
const auto &Symbol : Symbols) {
56 (1.0 + std::log2(1 + Symbol.Signals.Seen));
57 double &S =
Score[Symbol.Symbol.getFilePath()];
58 S = std::max(S, NewScore);
62 llvm::sort(Symbols.begin(), Symbols.end(),
64 auto AS = Score[A.Symbol.getFilePath()];
65 auto BS = Score[B.Symbol.getFilePath()];
68 return A.Symbol.getFilePath() < B.Symbol.getFilePath();
72 std::vector<find_all_symbols::SymbolInfo>
78 llvm::SmallVector<llvm::StringRef, 8> Names;
79 Identifier.split(Names,
"::");
81 bool IsFullyQualified =
false;
82 if (Identifier.startswith(
"::")) {
83 Names.erase(Names.begin());
84 IsFullyQualified =
true;
91 bool TookPrefix =
false;
92 std::vector<SymbolAndSignals> MatchedSymbols;
94 std::vector<SymbolAndSignals> Symbols;
95 for (
const auto &DB : SymbolIndices) {
96 auto Res = DB.get()->search(Names.back());
97 Symbols.insert(Symbols.end(), Res.begin(), Res.end());
100 LLVM_DEBUG(llvm::dbgs() <<
"Searching " << Names.back() <<
"... got "
101 << Symbols.size() <<
" results...\n");
103 for (
auto &SymAndSig : Symbols) {
106 bool IsMatched =
true;
107 auto SymbolContext = Symbol.getContexts().begin();
108 auto IdentiferContext = Names.rbegin() + 1;
110 while (IdentiferContext != Names.rend() &&
111 SymbolContext != Symbol.getContexts().end()) {
112 if (SymbolContext->second == *IdentiferContext) {
115 }
else if (SymbolContext->first ==
127 if (IsFullyQualified)
128 IsMatched &= (SymbolContext == Symbol.getContexts().end());
132 if (IsMatched && IdentiferContext == Names.rend()) {
138 Symbol.getSymbolKind() ==
143 MatchedSymbols.push_back(std::move(SymAndSig));
148 }
while (MatchedSymbols.empty() && !Names.empty() && IsNestedSearch);
152 std::vector<SymbolInfo> Res;
153 Res.reserve(MatchedSymbols.size());
154 for (
auto &SymAndSig : MatchedSymbols)
155 Res.push_back(std::move(SymAndSig.Symbol));