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

Reply via email to