[clang-tools-extra] r342025 - [clangd] Implement a Proof-of-Concept tool for symbol index exploration

Kirill Bobyrev via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 12 00:32:54 PDT 2018


Author: omtcyfz
Date: Wed Sep 12 00:32:54 2018
New Revision: 342025

URL: http://llvm.org/viewvc/llvm-project?rev=342025&view=rev
Log:
[clangd] Implement a Proof-of-Concept tool for symbol index exploration

Reviewed By: sammccall, ilya-biryukov

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

Added:
    clang-tools-extra/trunk/clangd/index/dex/dexp/
    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/CMakeLists.txt

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=342025&r1=342024&r2=342025&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Wed Sep 12 00:32:54 2018
@@ -74,3 +74,4 @@ if( LLVM_LIB_FUZZING_ENGINE OR LLVM_USE_
 endif()
 add_subdirectory(tool)
 add_subdirectory(global-symbol-builder)
+add_subdirectory(index/dex/dexp)

Added: 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=342025&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/clangd/index/dex/dexp/CMakeLists.txt Wed Sep 12 00:32:54 2018
@@ -0,0 +1,15 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
+
+set(LLVM_LINK_COMPONENTS
+  LineEditor
+  Support
+  )
+
+add_clang_executable(dexp
+  Dexp.cpp
+  )
+
+target_link_libraries(dexp
+  PRIVATE
+  clangDaemon
+  )

Added: 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=342025&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp (added)
+++ clang-tools-extra/trunk/clangd/index/dex/dexp/Dexp.cpp Wed Sep 12 00:32:54 2018
@@ -0,0 +1,161 @@
+//===--- Dexp.cpp - Dex EXPloration tool ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a simple interactive tool which can be used to manually
+// evaluate symbol search quality of Clangd index.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../../../index/SymbolYAML.h"
+#include "../Dex.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/LineEditor/LineEditor.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Signals.h"
+
+using clang::clangd::FuzzyFindRequest;
+using clang::clangd::loadIndex;
+using clang::clangd::Symbol;
+using clang::clangd::SymbolIndex;
+using llvm::StringRef;
+
+namespace {
+
+llvm::cl::opt<std::string>
+    SymbolCollection("symbol-collection-file",
+                     llvm::cl::desc("Path to the file with symbol collection"),
+                     llvm::cl::Positional, llvm::cl::Required);
+
+static const std::string Overview = R"(
+This is an **experimental** interactive tool to process user-provided search
+queries over given symbol collection obtained via global-symbol-builder. The
+tool can be used to evaluate search quality of existing index implementations
+and manually construct non-trivial test cases.
+
+Type use "help" request to get information about the details.
+)";
+
+void reportTime(StringRef Name, llvm::function_ref<void()> F) {
+  const auto TimerStart = std::chrono::high_resolution_clock::now();
+  F();
+  const auto TimerStop = std::chrono::high_resolution_clock::now();
+  const auto Duration = std::chrono::duration_cast<std::chrono::milliseconds>(
+      TimerStop - TimerStart);
+  llvm::outs() << llvm::formatv("{0} took {1:ms+n}.\n", Name, Duration);
+}
+
+void fuzzyFind(llvm::StringRef UnqualifiedName, const SymbolIndex &Index) {
+  FuzzyFindRequest Request;
+  Request.MaxCandidateCount = 10;
+  Request.Query = UnqualifiedName;
+  // FIXME(kbobyrev): Print symbol final scores to see the distribution.
+  static const auto OutputFormat = "{0,-4} | {1,-40} | {2,-25}\n";
+  llvm::outs() << llvm::formatv(OutputFormat, "Rank", "Symbol ID",
+                                "Symbol Name");
+  size_t Rank = 0;
+  Index.fuzzyFind(Request, [&](const Symbol &Sym) {
+    llvm::outs() << llvm::formatv(OutputFormat, Rank++, Sym.ID.str(), Sym.Name);
+  });
+}
+
+static const std::string HelpMessage = R"(dexp commands:
+
+> find Name
+
+Constructs fuzzy find request given unqualified symbol name and returns top 10
+symbols retrieved from index.
+
+> lookup SymbolID
+
+Retrieves symbol names given USR.
+)";
+
+void help() { llvm::outs() << HelpMessage; }
+
+void lookup(StringRef USR, const SymbolIndex &Index) {
+  llvm::DenseSet<clang::clangd::SymbolID> IDs{clang::clangd::SymbolID{USR}};
+  clang::clangd::LookupRequest Request{IDs};
+  bool FoundSymbol = false;
+  Index.lookup(Request, [&](const Symbol &Sym) {
+    if (!FoundSymbol)
+      FoundSymbol = true;
+    llvm::outs() << SymbolToYAML(Sym);
+  });
+  if (!FoundSymbol)
+    llvm::outs() << "not found\n";
+}
+
+// FIXME(kbobyrev): Make this an actual REPL: probably use LLVM Command Line
+// library for parsing flags and arguments.
+// FIXME(kbobyrev): Ideas for commands:
+// * symbol lookup: print out symbol in YAML format given SymbolID
+// * 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
+//   could build one)
+// * show number of tokens of each kind
+// * print out tokens with the most dense posting lists
+// * print out tokens with least dense posting lists
+void dispatch(StringRef Request, const SymbolIndex &Index) {
+  llvm::SmallVector<StringRef, 2> Arguments;
+  Request.split(Arguments, ' ');
+  if (Arguments.empty()) {
+    llvm::outs() << "Request can not be empty.\n";
+    help();
+    return;
+  }
+
+  if (Arguments.front() == "find") {
+    if (Arguments.size() != 2) {
+      llvm::outs() << "find request must specify unqualified symbol name.\n";
+      return;
+    }
+    reportTime("fuzzy find request",
+               [&]() { fuzzyFind(Arguments.back(), Index); });
+  } else if (Arguments.front() == "lookup") {
+    if (Arguments.size() != 2) {
+      llvm::outs() << "lookup request must specify symbol ID .\n";
+      return;
+    }
+    reportTime("lookup request", [&]() { lookup(Arguments.back(), Index); });
+  } else if (Arguments.front() == "help") {
+    help();
+  } else {
+    llvm::outs() << "Unknown command. Try 'help'\n";
+  }
+}
+
+} // namespace
+
+int main(int argc, const char *argv[]) {
+  llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
+  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+
+  std::unique_ptr<SymbolIndex> Index;
+  reportTime("Dex build", [&]() {
+    Index = loadIndex(SymbolCollection, /*URISchemes=*/{},
+                      /*UseDex=*/true);
+  });
+
+  if (!Index) {
+    llvm::outs()
+        << "ERROR: Please provide a valid path to symbol collection file.\n";
+    return -1;
+  }
+
+  llvm::LineEditor LE("dexp");
+
+  while (llvm::Optional<std::string> Request = LE.readLine())
+    dispatch(Request.getValue(), *Index);
+
+  return 0;
+}




More information about the cfe-commits mailing list