This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE344508: [clangd] dump xrefs information in dexp tool. 
(authored by hokein, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D53019?vs=169683&id=169684#toc

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53019

Files:
  clangd/index/dex/dexp/CMakeLists.txt
  clangd/index/dex/dexp/Dexp.cpp

Index: clangd/index/dex/dexp/Dexp.cpp
===================================================================
--- clangd/index/dex/dexp/Dexp.cpp
+++ clangd/index/dex/dexp/Dexp.cpp
@@ -12,8 +12,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "../../Serialization.h"
-#include "../Dex.h"
+#include "Dex.h"
+#include "Serialization.h"
+#include "SourceCode.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -52,6 +53,26 @@
   llvm::outs() << llvm::formatv("{0} took {1:ms+n}.\n", Name, Duration);
 }
 
+std::vector<clang::clangd::SymbolID>
+getSymbolIDsFromIndex(llvm::StringRef QualifiedName, const SymbolIndex *Index) {
+  FuzzyFindRequest Request;
+  // Remove leading "::" qualifier as FuzzyFind doesn't need leading "::"
+  // qualifier for global scope.
+  bool IsGlobalScope = QualifiedName.consume_front("::");
+  auto Names = clang::clangd::splitQualifiedName(QualifiedName);
+  if (IsGlobalScope || !Names.first.empty())
+    Request.Scopes = {Names.first};
+
+  Request.Query = Names.second;
+  std::vector<clang::clangd::SymbolID> SymIDs;
+  Index->fuzzyFind(Request, [&](const Symbol &Sym) {
+    std::string SymQualifiedName = (Sym.Scope + Sym.Name).str();
+    if (QualifiedName == SymQualifiedName)
+      SymIDs.push_back(Sym.ID);
+  });
+  return SymIDs;
+}
+
 // REPL commands inherit from Command and contain their options as members.
 // Creating a Command populates parser options, parseAndRun() resets them.
 class Command {
@@ -88,7 +109,6 @@
 };
 
 // FIXME(kbobyrev): Ideas for more commands:
-// * find symbol references: print set of reference locations
 // * load/swap/reload index: this would make it possible to get rid of llvm::cl
 //   usages in the tool driver and actually use llvm::cl library in the REPL.
 // * show posting list density histogram (our dump data somewhere so that user
@@ -139,19 +159,32 @@
   cl::opt<std::string> ID{
       "id",
       cl::Positional,
-      cl::Required,
       cl::desc("Symbol ID to look up (hex)"),
   };
+  cl::opt<std::string> Name{
+      "name", cl::desc("Qualified name to look up."),
+  };
 
   void run() override {
-    auto SID = clang::clangd::SymbolID::fromStr(ID);
-    if (!SID) {
-      llvm::outs() << llvm::toString(SID.takeError()) << "\n";
+    if (ID.getNumOccurrences() == 0 && Name.getNumOccurrences() == 0) {
+      llvm::outs()
+          << "Missing required argument: please provide id or -name.\n";
       return;
     }
+    std::vector<clang::clangd::SymbolID> IDs;
+    if (ID.getNumOccurrences()) {
+      auto SID = clang::clangd::SymbolID::fromStr(ID);
+      if (!SID) {
+        llvm::outs() << llvm::toString(SID.takeError()) << "\n";
+        return;
+      }
+      IDs.push_back(*SID);
+    } else {
+      IDs = getSymbolIDsFromIndex(Name, Index);
+    }
 
     clang::clangd::LookupRequest Request;
-    Request.IDs = {*SID};
+    Request.IDs.insert(IDs.begin(), IDs.end());
     bool FoundSymbol = false;
     Index->lookup(Request, [&](const Symbol &Sym) {
       FoundSymbol = true;
@@ -162,13 +195,62 @@
   }
 };
 
+class Refs : public Command {
+  cl::opt<std::string> ID{
+      "id", cl::Positional,
+      cl::desc("Symbol ID of the symbol being queried (hex)."),
+  };
+  cl::opt<std::string> Name{
+      "name", cl::desc("Qualified name of the symbol being queried."),
+  };
+  cl::opt<std::string> Filter{
+      "filter", cl::init(".*"),
+      cl::desc(
+          "Print all results from files matching this regular expression."),
+  };
+
+  void run() override {
+    if (ID.getNumOccurrences() == 0 && Name.getNumOccurrences() == 0) {
+      llvm::outs()
+          << "Missing required argument: please provide id or -name.\n";
+      return;
+    }
+    std::vector<clang::clangd::SymbolID> IDs;
+    if (ID.getNumOccurrences()) {
+      auto SID = clang::clangd::SymbolID::fromStr(ID);
+      if (!SID) {
+        llvm::outs() << llvm::toString(SID.takeError()) << "\n";
+        return;
+      }
+      IDs.push_back(*SID);
+    } else {
+      IDs = getSymbolIDsFromIndex(Name, Index);
+    }
+    clang::clangd::RefsRequest RefRequest;
+    RefRequest.IDs.insert(IDs.begin(), IDs.end());
+    llvm::Regex RegexFilter(Filter);
+    Index->refs(RefRequest, [&RegexFilter](const clang::clangd::Ref &R) {
+      auto U = clang::clangd::URI::parse(R.Location.FileURI);
+      if (!U) {
+        llvm::outs() << U.takeError();
+        return;
+      }
+      if (RegexFilter.match(U->body()))
+        llvm::outs() << R << "\n";
+    });
+  }
+};
+
 struct {
   const char *Name;
   const char *Description;
   std::function<std::unique_ptr<Command>()> Implementation;
 } CommandInfo[] = {
     {"find", "Search for symbols with fuzzyFind", llvm::make_unique<FuzzyFind>},
-    {"lookup", "Dump symbol details by ID", llvm::make_unique<Lookup>},
+    {"lookup", "Dump symbol details by ID or qualified name",
+     llvm::make_unique<Lookup>},
+    {"refs", "Find references by ID or qualified name",
+     llvm::make_unique<Refs>},
 };
 
 } // namespace
Index: clangd/index/dex/dexp/CMakeLists.txt
===================================================================
--- clangd/index/dex/dexp/CMakeLists.txt
+++ clangd/index/dex/dexp/CMakeLists.txt
@@ -1,3 +1,5 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
 
 set(LLVM_LINK_COMPONENTS
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to