summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/include-fixer/SymbolIndexManager.cpp33
-rw-r--r--clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp6
-rw-r--r--clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml21
-rw-r--r--clang-tools-extra/test/include-fixer/ranking.cpp6
4 files changed, 63 insertions, 3 deletions
diff --git a/clang-tools-extra/include-fixer/SymbolIndexManager.cpp b/clang-tools-extra/include-fixer/SymbolIndexManager.cpp
index 2a0547a473a..1800fab4199 100644
--- a/clang-tools-extra/include-fixer/SymbolIndexManager.cpp
+++ b/clang-tools-extra/include-fixer/SymbolIndexManager.cpp
@@ -17,6 +17,37 @@
namespace clang {
namespace include_fixer {
+using clang::find_all_symbols::SymbolInfo;
+
+/// Sorts and uniques SymbolInfos based on the popularity info in SymbolInfo.
+static void rankByPopularity(std::vector<SymbolInfo> &Symbols) {
+ // First collect occurrences per header file.
+ std::map<llvm::StringRef, unsigned> HeaderPopularity;
+ for (const SymbolInfo &Symbol : Symbols) {
+ unsigned &Popularity = HeaderPopularity[Symbol.getFilePath()];
+ Popularity = std::max(Popularity, Symbol.getNumOccurrences());
+ }
+
+ // Sort by the gathered popularities. Use file name as a tie breaker so we can
+ // deduplicate.
+ std::sort(Symbols.begin(), Symbols.end(),
+ [&](const SymbolInfo &A, const SymbolInfo &B) {
+ auto APop = HeaderPopularity[A.getFilePath()];
+ auto BPop = HeaderPopularity[B.getFilePath()];
+ if (APop != BPop)
+ return APop > BPop;
+ return A.getFilePath() < B.getFilePath();
+ });
+
+ // Deduplicate based on the file name. They will have the same popularity and
+ // we don't want to suggest the same header twice.
+ Symbols.erase(std::unique(Symbols.begin(), Symbols.end(),
+ [](const SymbolInfo &A, const SymbolInfo &B) {
+ return A.getFilePath() == B.getFilePath();
+ }),
+ Symbols.end());
+}
+
std::vector<std::string>
SymbolIndexManager::search(llvm::StringRef Identifier) const {
// The identifier may be fully qualified, so split it and get all the context
@@ -45,6 +76,8 @@ SymbolIndexManager::search(llvm::StringRef Identifier) const {
DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got "
<< Symbols.size() << " results...\n");
+ rankByPopularity(Symbols);
+
for (const auto &Symbol : Symbols) {
// Match the identifier name without qualifier.
if (Symbol.getName() == Names.back()) {
diff --git a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
index 7b5c9f9359c..6e385fe617f 100644
--- a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
+++ b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
@@ -98,11 +98,11 @@ createSymbolIndexManager(StringRef FilePath) {
std::vector<std::string> Headers;
SmallVector<StringRef, 4> CommaSplits;
Split.second.split(CommaSplits, ",");
- for (StringRef Header : CommaSplits)
+ for (size_t I = 0, E = CommaSplits.size(); I != E; ++I)
Symbols.push_back(find_all_symbols::SymbolInfo(
Split.first.trim(),
- find_all_symbols::SymbolInfo::SymbolKind::Unknown, Header.trim(), 1,
- {}));
+ find_all_symbols::SymbolInfo::SymbolKind::Unknown,
+ CommaSplits[I].trim(), 1, {}, /*NumOccurrences=*/E - I));
}
SymbolIndexMgr->addSymbolIndex(
llvm::make_unique<include_fixer::InMemorySymbolIndex>(Symbols));
diff --git a/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml b/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml
index 7e60fc2e9ae..4d9c219150a 100644
--- a/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml
+++ b/clang-tools-extra/test/include-fixer/Inputs/fake_yaml_db.yaml
@@ -22,3 +22,24 @@ LineNumber: 1
Type: Class
NumOccurrences: 1
...
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: ../include/bar.h
+LineNumber: 2
+Type: Class
+NumOccurrences: 3
+...
+Name: bar
+Contexts:
+ - ContextType: Namespace
+ ContextName: a
+ - ContextType: Namespace
+ ContextName: b
+FilePath: ../include/zbar.h
+LineNumber: 1
+Type: Class
+NumOccurrences: 3
diff --git a/clang-tools-extra/test/include-fixer/ranking.cpp b/clang-tools-extra/test/include-fixer/ranking.cpp
new file mode 100644
index 00000000000..13cd7890282
--- /dev/null
+++ b/clang-tools-extra/test/include-fixer/ranking.cpp
@@ -0,0 +1,6 @@
+// RUN: clang-include-fixer -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s -implicit-check-not=.h
+
+// CHECK: "../include/bar.h"
+// CHECK-NEXT: "../include/zbar.h"
+
+bar b;
OpenPOWER on IntegriCloud