[clang-tools-extra] r327487 - [clangd] Add an interface that finds symbol by SymbolID in SymbolIndex.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 14 02:48:05 PDT 2018
Author: ioeric
Date: Wed Mar 14 02:48:05 2018
New Revision: 327487
URL: http://llvm.org/viewvc/llvm-project?rev=327487&view=rev
Log:
[clangd] Add an interface that finds symbol by SymbolID in SymbolIndex.
Summary:
Potential use case: argument go-to-definition result with symbol
information (e.g. function definition in cc file) that might not be in the AST.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: klimek, ilya-biryukov, jkorous-apple, cfe-commits
Differential Revision: https://reviews.llvm.org/D44305
Modified:
clang-tools-extra/trunk/clangd/index/FileIndex.cpp
clang-tools-extra/trunk/clangd/index/FileIndex.h
clang-tools-extra/trunk/clangd/index/Index.h
clang-tools-extra/trunk/clangd/index/MemIndex.cpp
clang-tools-extra/trunk/clangd/index/MemIndex.h
clang-tools-extra/trunk/clangd/index/Merge.cpp
clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
Modified: clang-tools-extra/trunk/clangd/index/FileIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.cpp?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.cpp Wed Mar 14 02:48:05 2018
@@ -93,5 +93,11 @@ bool FileIndex::fuzzyFind(
return Index.fuzzyFind(Req, Callback);
}
+void FileIndex::lookup(
+ const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const {
+ Index.lookup(Req, Callback);
+}
+
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/index/FileIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.h?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.h (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.h Wed Mar 14 02:48:05 2018
@@ -63,6 +63,9 @@ public:
fuzzyFind(const FuzzyFindRequest &Req,
llvm::function_ref<void(const Symbol &)> Callback) const override;
+ void lookup(const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const override;
+
private:
FileSymbols FSymbols;
MemIndex Index;
Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Wed Mar 14 02:48:05 2018
@@ -248,6 +248,10 @@ struct FuzzyFindRequest {
size_t MaxCandidateCount = UINT_MAX;
};
+struct LookupRequest {
+ llvm::DenseSet<SymbolID> IDs;
+};
+
/// \brief Interface for symbol indexes that can be used for searching or
/// matching symbols among a set of symbols based on names or unique IDs.
class SymbolIndex {
@@ -263,8 +267,14 @@ public:
fuzzyFind(const FuzzyFindRequest &Req,
llvm::function_ref<void(const Symbol &)> Callback) const = 0;
+ /// Looks up symbols with any of the given symbol IDs and applies \p Callback
+ /// on each matched symbol.
+ /// The returned symbol must be deep-copied if it's used outside Callback.
+ virtual void
+ lookup(const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const = 0;
+
// FIXME: add interfaces for more index use cases:
- // - Symbol getSymbolInfo(SymbolID);
// - getAllOccurrences(SymbolID);
};
Modified: clang-tools-extra/trunk/clangd/index/MemIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.cpp?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/MemIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.cpp Wed Mar 14 02:48:05 2018
@@ -60,6 +60,15 @@ bool MemIndex::fuzzyFind(
return More;
}
+void MemIndex::lookup(const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const {
+ for (const auto &ID : Req.IDs) {
+ auto I = Index.find(ID);
+ if (I != Index.end())
+ Callback(*I->second);
+ }
+}
+
std::unique_ptr<SymbolIndex> MemIndex::build(SymbolSlab Slab) {
struct Snapshot {
SymbolSlab Slab;
Modified: clang-tools-extra/trunk/clangd/index/MemIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.h?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/MemIndex.h (original)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.h Wed Mar 14 02:48:05 2018
@@ -31,6 +31,10 @@ public:
fuzzyFind(const FuzzyFindRequest &Req,
llvm::function_ref<void(const Symbol &)> Callback) const override;
+ virtual void
+ lookup(const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const override;
+
private:
std::shared_ptr<std::vector<const Symbol *>> Symbols;
// Index is a set of symbols that are deduplicated by symbol IDs.
Modified: clang-tools-extra/trunk/clangd/index/Merge.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Merge.cpp?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Merge.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Merge.cpp Wed Mar 14 02:48:05 2018
@@ -52,6 +52,28 @@ class MergedIndex : public SymbolIndex {
return More;
}
+ void
+ lookup(const LookupRequest &Req,
+ llvm::function_ref<void(const Symbol &)> Callback) const override {
+ SymbolSlab::Builder B;
+
+ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); });
+
+ auto RemainingIDs = Req.IDs;
+ Symbol::Details Scratch;
+ Static->lookup(Req, [&](const Symbol &S) {
+ const Symbol *Sym = B.find(S.ID);
+ RemainingIDs.erase(S.ID);
+ if (!Sym)
+ Callback(S);
+ else
+ Callback(mergeSymbol(*Sym, S, &Scratch));
+ });
+ for (const auto &ID : RemainingIDs)
+ if (const Symbol *Sym = B.find(ID))
+ Callback(*Sym);
+ }
+
private:
const SymbolIndex *Dynamic, *Static;
};
Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Wed Mar 14 02:48:05 2018
@@ -689,6 +689,9 @@ public:
return true;
}
+ void lookup(const LookupRequest &,
+ llvm::function_ref<void(const Symbol &)>) const override {}
+
const std::vector<FuzzyFindRequest> allRequests() const { return Requests; }
private:
Modified: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=327487&r1=327486&r2=327487&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp Wed Mar 14 02:48:05 2018
@@ -29,7 +29,7 @@ Symbol symbol(llvm::StringRef QName) {
Sym.Scope = "";
} else {
Sym.Name = QName.substr(Pos + 2);
- Sym.Scope = QName.substr(0, Pos);
+ Sym.Scope = QName.substr(0, Pos + 2);
}
return Sym;
}
@@ -89,13 +89,16 @@ generateNumSymbols(int Begin, int End,
return generateSymbols(Names, WeakSymbols);
}
+std::string getQualifiedName(const Symbol &Sym) {
+ return (Sym.Scope + Sym.Name).str();
+}
+
std::vector<std::string> match(const SymbolIndex &I,
const FuzzyFindRequest &Req,
bool *Incomplete = nullptr) {
std::vector<std::string> Matches;
bool IsIncomplete = I.fuzzyFind(Req, [&](const Symbol &Sym) {
- Matches.push_back(
- (Sym.Scope + (Sym.Scope.empty() ? "" : "::") + Sym.Name).str());
+ Matches.push_back(getQualifiedName(Sym));
});
if (Incomplete)
*Incomplete = IsIncomplete;
@@ -178,7 +181,7 @@ TEST(MemIndexTest, MatchQualifiedNamesWi
I.build(generateSymbols({"a::y1", "a::y2", "a::x", "b::y2", "y3"}));
FuzzyFindRequest Req;
Req.Query = "y";
- Req.Scopes = {"a"};
+ Req.Scopes = {"a::"};
EXPECT_THAT(match(I, Req), UnorderedElementsAre("a::y1", "a::y2"));
}
@@ -187,7 +190,7 @@ TEST(MemIndexTest, MatchQualifiedNamesWi
I.build(generateSymbols({"a::y1", "a::y2", "a::x", "b::y3", "y3"}));
FuzzyFindRequest Req;
Req.Query = "y";
- Req.Scopes = {"a", "b"};
+ Req.Scopes = {"a::", "b::"};
EXPECT_THAT(match(I, Req), UnorderedElementsAre("a::y1", "a::y2", "b::y3"));
}
@@ -196,7 +199,7 @@ TEST(MemIndexTest, NoMatchNestedScopes)
I.build(generateSymbols({"a::y1", "a::b::y2"}));
FuzzyFindRequest Req;
Req.Query = "y";
- Req.Scopes = {"a"};
+ Req.Scopes = {"a::"};
EXPECT_THAT(match(I, Req), UnorderedElementsAre("a::y1"));
}
@@ -205,16 +208,60 @@ TEST(MemIndexTest, IgnoreCases) {
I.build(generateSymbols({"ns::ABC", "ns::abc"}));
FuzzyFindRequest Req;
Req.Query = "AB";
- Req.Scopes = {"ns"};
+ Req.Scopes = {"ns::"};
EXPECT_THAT(match(I, Req), UnorderedElementsAre("ns::ABC", "ns::abc"));
}
-TEST(MergeTest, MergeIndex) {
+// Returns qualified names of symbols with any of IDs in the index.
+std::vector<std::string> lookup(const SymbolIndex &I,
+ llvm::ArrayRef<SymbolID> IDs) {
+ LookupRequest Req;
+ Req.IDs.insert(IDs.begin(), IDs.end());
+ std::vector<std::string> Results;
+ I.lookup(Req, [&](const Symbol &Sym) {
+ Results.push_back(getQualifiedName(Sym));
+ });
+ return Results;
+}
+
+TEST(MemIndexTest, Lookup) {
+ MemIndex I;
+ I.build(generateSymbols({"ns::abc", "ns::xyz"}));
+ EXPECT_THAT(lookup(I, SymbolID("ns::abc")), UnorderedElementsAre("ns::abc"));
+ EXPECT_THAT(lookup(I, {SymbolID("ns::abc"), SymbolID("ns::xyz")}),
+ UnorderedElementsAre("ns::abc", "ns::xyz"));
+ EXPECT_THAT(lookup(I, {SymbolID("ns::nonono"), SymbolID("ns::xyz")}),
+ UnorderedElementsAre("ns::xyz"));
+ EXPECT_THAT(lookup(I, SymbolID("ns::nonono")), UnorderedElementsAre());
+}
+
+TEST(MergeIndexTest, Lookup) {
+ MemIndex I, J;
+ I.build(generateSymbols({"ns::A", "ns::B"}));
+ J.build(generateSymbols({"ns::B", "ns::C"}));
+ EXPECT_THAT(lookup(*mergeIndex(&I, &J), SymbolID("ns::A")),
+ UnorderedElementsAre("ns::A"));
+ EXPECT_THAT(lookup(*mergeIndex(&I, &J), SymbolID("ns::B")),
+ UnorderedElementsAre("ns::B"));
+ EXPECT_THAT(lookup(*mergeIndex(&I, &J), SymbolID("ns::C")),
+ UnorderedElementsAre("ns::C"));
+ EXPECT_THAT(
+ lookup(*mergeIndex(&I, &J), {SymbolID("ns::A"), SymbolID("ns::B")}),
+ UnorderedElementsAre("ns::A", "ns::B"));
+ EXPECT_THAT(
+ lookup(*mergeIndex(&I, &J), {SymbolID("ns::A"), SymbolID("ns::C")}),
+ UnorderedElementsAre("ns::A", "ns::C"));
+ EXPECT_THAT(lookup(*mergeIndex(&I, &J), SymbolID("ns::D")),
+ UnorderedElementsAre());
+ EXPECT_THAT(lookup(*mergeIndex(&I, &J), {}), UnorderedElementsAre());
+}
+
+TEST(MergeIndexTest, FuzzyFind) {
MemIndex I, J;
I.build(generateSymbols({"ns::A", "ns::B"}));
J.build(generateSymbols({"ns::B", "ns::C"}));
FuzzyFindRequest Req;
- Req.Scopes = {"ns"};
+ Req.Scopes = {"ns::"};
EXPECT_THAT(match(*mergeIndex(&I, &J), Req),
UnorderedElementsAre("ns::A", "ns::B", "ns::C"));
}
More information about the cfe-commits
mailing list