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")); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits