ioeric created this revision. ioeric added a reviewer: sammccall. Herald added subscribers: cfe-commits, jkorous-apple, ilya-biryukov, klimek.
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. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D44305 Files: clangd/index/FileIndex.cpp clangd/index/FileIndex.h clangd/index/Index.h clangd/index/MemIndex.cpp clangd/index/MemIndex.h clangd/index/Merge.cpp unittests/clangd/CodeCompleteTests.cpp unittests/clangd/IndexTests.cpp
Index: unittests/clangd/IndexTests.cpp =================================================================== --- unittests/clangd/IndexTests.cpp +++ unittests/clangd/IndexTests.cpp @@ -89,19 +89,30 @@ return generateSymbols(Names, WeakSymbols); } +std::string getQualifiedName(const Symbol &Sym) { + return (Sym.Scope + (Sym.Scope.empty() ? "" : "::") + 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; return Matches; } +// Returns the qualified name of the symbol with ID in the index, or "" if there +// is no such symbol. +std::string getSymbol(const SymbolIndex &I, const SymbolID &ID) { + std::string Res = ""; + I.getSymbol(ID, [&](const Symbol &Sym) { Res = getQualifiedName(Sym); }); + return Res; +} + TEST(MemIndexTest, MemIndexSymbolsRecycled) { MemIndex I; std::weak_ptr<SlabAndPointers> Symbols; @@ -209,7 +220,14 @@ EXPECT_THAT(match(I, Req), UnorderedElementsAre("ns::ABC", "ns::abc")); } -TEST(MergeTest, MergeIndex) { +TEST(MemIndexTest, GetSymbol) { + MemIndex I; + I.build(generateSymbols({"ns::abc", "ns::xyz"})); + EXPECT_EQ(getSymbol(I, SymbolID("ns::abc")), "ns::abc"); + EXPECT_EQ(getSymbol(I, SymbolID("ns::nonono")), ""); +} + +TEST(MergeIndexTest, FuzzyFind) { MemIndex I, J; I.build(generateSymbols({"ns::A", "ns::B"})); J.build(generateSymbols({"ns::B", "ns::C"})); @@ -219,6 +237,16 @@ UnorderedElementsAre("ns::A", "ns::B", "ns::C")); } +TEST(MergeIndexTest, GetSymbol) { + MemIndex I, J; + I.build(generateSymbols({"ns::A", "ns::B"})); + J.build(generateSymbols({"ns::B", "ns::C"})); + EXPECT_EQ(getSymbol(*mergeIndex(&I, &J), SymbolID("ns::A")), "ns::A"); + EXPECT_EQ(getSymbol(*mergeIndex(&I, &J), SymbolID("ns::B")), "ns::B"); + EXPECT_EQ(getSymbol(*mergeIndex(&I, &J), SymbolID("ns::C")), "ns::C"); + EXPECT_EQ(getSymbol(*mergeIndex(&I, &J), SymbolID("ns::D")), ""); +} + TEST(MergeTest, Merge) { Symbol L, R; L.ID = R.ID = SymbolID("hello"); Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -690,6 +690,12 @@ return true; } + bool getSymbol( + const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> /*Callback*/) const override { + return false; + } + const std::vector<FuzzyFindRequest> allRequests() const { return Requests; } private: Index: clangd/index/Merge.cpp =================================================================== --- clangd/index/Merge.cpp +++ clangd/index/Merge.cpp @@ -52,6 +52,23 @@ return More; } + bool + getSymbol(const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> Callback) const override { + SymbolSlab::Builder B; // Used to store the symbol from dynamic index. + if (!Dynamic->getSymbol(ID, [&](const Symbol &S) { B.insert(S); })) + return Static->getSymbol(ID, Callback); + + const auto *DynS = B.find(ID); + assert(DynS != nullptr); + if (!Static->getSymbol(ID, [&](const Symbol &S) { + Symbol::Details Scratch; + Callback(mergeSymbol(*DynS, S, &Scratch)); + })) + Callback(*DynS); + return true; + } + private: const SymbolIndex *Dynamic, *Static; }; Index: clangd/index/MemIndex.h =================================================================== --- clangd/index/MemIndex.h +++ clangd/index/MemIndex.h @@ -31,6 +31,10 @@ fuzzyFind(const FuzzyFindRequest &Req, llvm::function_ref<void(const Symbol &)> Callback) const override; + virtual bool + getSymbol(const SymbolID &ID, + 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. Index: clangd/index/MemIndex.cpp =================================================================== --- clangd/index/MemIndex.cpp +++ clangd/index/MemIndex.cpp @@ -60,6 +60,16 @@ return More; } +bool MemIndex::getSymbol( + const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> Callback) const { + auto I = Index.find(ID); + if (I == Index.end()) + return false; + Callback(*I->second); + return true; +} + std::unique_ptr<SymbolIndex> MemIndex::build(SymbolSlab Slab) { struct Snapshot { SymbolSlab Slab; Index: clangd/index/Index.h =================================================================== --- clangd/index/Index.h +++ clangd/index/Index.h @@ -260,8 +260,15 @@ fuzzyFind(const FuzzyFindRequest &Req, llvm::function_ref<void(const Symbol &)> Callback) const = 0; + /// Gets a symbol with the given symbol ID and applies \p Callback on the + /// symbol. + /// The returned symbol must be deep-copied if it's used outside Callback. + /// Returns true if a symbol with ID was found. + virtual bool + getSymbol(const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> Callback) const = 0; + // FIXME: add interfaces for more index use cases: - // - Symbol getSymbolInfo(SymbolID); // - getAllOccurrences(SymbolID); }; Index: clangd/index/FileIndex.h =================================================================== --- clangd/index/FileIndex.h +++ clangd/index/FileIndex.h @@ -63,6 +63,10 @@ fuzzyFind(const FuzzyFindRequest &Req, llvm::function_ref<void(const Symbol &)> Callback) const override; + bool + getSymbol(const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> Callback) const override; + private: FileSymbols FSymbols; MemIndex Index; Index: clangd/index/FileIndex.cpp =================================================================== --- clangd/index/FileIndex.cpp +++ clangd/index/FileIndex.cpp @@ -91,5 +91,11 @@ return Index.fuzzyFind(Req, Callback); } +bool FileIndex::getSymbol( + const SymbolID &ID, + llvm::function_ref<void(const Symbol &)> Callback) const { + return Index.getSymbol(ID, Callback); +} + } // namespace clangd } // namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits