summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2016-05-31 14:33:28 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2016-05-31 14:33:28 +0000
commit658d28014bf98019cd253dbada51dffdde8093ff (patch)
tree2572e84041b33ad124ef290e0a8731b904acad94
parent30bffb9dcf8c9b53c924e3145a71e20e6ee0c04f (diff)
downloadbcm5719-llvm-658d28014bf98019cd253dbada51dffdde8093ff.tar.gz
bcm5719-llvm-658d28014bf98019cd253dbada51dffdde8093ff.zip
[include-fixer] Rank symbols based on the number of occurrences we found while merging.
This sorts based on the popularity of the header, not the symbol. If there are mutliple matching symbols in one header we take the maximum popularity for that header and deduplicate. If we know nothing we sort lexicographically based on the header path. Differential Revision: http://reviews.llvm.org/D20814 llvm-svn: 271283
-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