[clang-tools-extra] r344508 - [clangd] dump xrefs information in dexp tool.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 15 05:32:49 PDT 2018


Author: hokein
Date: Mon Oct 15 05:32:49 2018
New Revision: 344508

URL: http://llvm.org/viewvc/llvm-project?rev=344508&view=rev
Log:
[clangd] dump xrefs information in dexp tool.

Reviewers: sammccall

Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Differential Revision: https://reviews.llvm.org/D53019

Modified:
    clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt
    clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp

Modified: clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt?rev=344508&r1=344507&r2=344508&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt Mon Oct 15 05:32:49 2018
@@ -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

Modified: clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp?rev=344508&r1=344507&r2=344508&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp Mon Oct 15 05:32:49 2018
@@ -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 @@ void reportTime(StringRef Name, llvm::fu
   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 @@ public:
 };
 
 // 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 @@ class Lookup : public Command {
   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 Lookup : public Command {
   }
 };
 
+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




More information about the cfe-commits mailing list