kbobyrev created this revision.
kbobyrev added reviewers: ilya-biryukov, ioeric, sammccall.
kbobyrev added a project: clang-tools-extra.
Herald added subscribers: kadircet, arphaman, jkorous, MaskRay.

JSON (de)serialization of `FuzzyFindRequest` might be useful for both 
https://reviews.llvm.org/D51090 and https://reviews.llvm.org/D51628. Also, this 
allows precise logging of the fuzzy find requests.


https://reviews.llvm.org/D51852

Files:
  clang-tools-extra/clangd/CodeComplete.cpp
  clang-tools-extra/clangd/index/Index.cpp
  clang-tools-extra/clangd/index/Index.h

Index: clang-tools-extra/clangd/index/Index.h
===================================================================
--- clang-tools-extra/clangd/index/Index.h
+++ clang-tools-extra/clangd/index/Index.h
@@ -19,8 +19,10 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/StringSaver.h"
 #include <array>
+#include <limits>
 #include <mutex>
 #include <string>
 #include <tuple>
@@ -253,11 +255,13 @@
   SymbolFlag Flags = SymbolFlag::None;
   /// FIXME: also add deprecation message and fixit?
 };
-inline Symbol::SymbolFlag  operator|(Symbol::SymbolFlag A, Symbol::SymbolFlag  B) {
+inline Symbol::SymbolFlag operator|(Symbol::SymbolFlag A,
+                                    Symbol::SymbolFlag B) {
   return static_cast<Symbol::SymbolFlag>(static_cast<uint8_t>(A) |
                                          static_cast<uint8_t>(B));
 }
-inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A, Symbol::SymbolFlag B) {
+inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A,
+                                      Symbol::SymbolFlag B) {
   return A = A | B;
 }
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S);
@@ -435,7 +439,7 @@
   std::vector<std::string> Scopes;
   /// \brief The number of top candidates to return. The index may choose to
   /// return more than this, e.g. if it doesn't know which candidates are best.
-  size_t MaxCandidateCount = UINT_MAX;
+  size_t MaxCandidateCount = std::numeric_limits<size_t>::max();
   /// If set to true, only symbols for completion support will be considered.
   bool RestrictForCodeCompletion = false;
   /// Contextually relevant files (e.g. the file we're code-completing in).
@@ -450,6 +454,8 @@
   }
   bool operator!=(const FuzzyFindRequest &Req) const { return !(*this == Req); }
 };
+bool fromJSON(const llvm::json::Value &Value, FuzzyFindRequest &Request);
+llvm::json::Value toJSON(const FuzzyFindRequest &Request);
 
 struct LookupRequest {
   llvm::DenseSet<SymbolID> IDs;
Index: clang-tools-extra/clangd/index/Index.cpp
===================================================================
--- clang-tools-extra/clangd/index/Index.cpp
+++ clang-tools-extra/clangd/index/Index.cpp
@@ -79,10 +79,9 @@
 }
 
 SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const {
-  auto It = std::lower_bound(Symbols.begin(), Symbols.end(), ID,
-                             [](const Symbol &S, const SymbolID &I) {
-                               return S.ID < I;
-                             });
+  auto It = std::lower_bound(
+      Symbols.begin(), Symbols.end(), ID,
+      [](const Symbol &S, const SymbolID &I) { return S.ID < I; });
   if (It != Symbols.end() && It->ID == ID)
     return It;
   return Symbols.end();
@@ -175,6 +174,35 @@
   return Index;
 }
 
+bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request) {
+  json::ObjectMapper O(Parameters);
+  llvm::Optional<int64_t> MaxCandidateCount;
+  bool OK =
+      O && O.map("Query", Request.Query) && O.map("Scopes", Request.Scopes) &&
+      O.map("RestrictForCodeCompletion", Request.RestrictForCodeCompletion) &&
+      O.map("ProximityPaths", Request.ProximityPaths) &&
+      O.map("MaxCandidateCount", MaxCandidateCount);
+  if (MaxCandidateCount)
+    Request.MaxCandidateCount = MaxCandidateCount.getValue();
+  return OK;
+}
+
+llvm::json::Value toJSON(const FuzzyFindRequest &Request) {
+  auto Result = json::Object{
+      {"Query", Request.Query},
+      {"Scopes", json::Array{Request.Scopes}},
+      {"RestrictForCodeCompletion", Request.RestrictForCodeCompletion},
+      {"ProximityPaths", json::Array{Request.ProximityPaths}},
+  };
+  // Typically, MaxCandidateCount is either maximum size_t value or something
+  // small. Since LLVM JSON serializer only supports int64_t, try to cast to
+  // int64_t and make this field "optional".
+  if (Request.MaxCandidateCount <= std::numeric_limits<int64_t>::max())
+    Result["MaxCandidateCount"] =
+        static_cast<int64_t>(Request.MaxCandidateCount);
+  return Result;
+}
+
 bool SwapIndex::fuzzyFind(const FuzzyFindRequest &R,
                           llvm::function_ref<void(const Symbol &)> CB) const {
   return snapshot()->fuzzyFind(R, CB);
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -1381,8 +1381,7 @@
     Req.Scopes = QueryScopes;
     // FIXME: we should send multiple weighted paths here.
     Req.ProximityPaths.push_back(FileName);
-    vlog("Code complete: fuzzyFind(\"{0}\", scopes=[{1}])", Req.Query,
-         llvm::join(Req.Scopes.begin(), Req.Scopes.end(), ","));
+    vlog("Code complete: fuzzyFind({0})", toJSON(Req));
 
     if (SpecFuzzyFind)
       SpecFuzzyFind->NewReq = Req;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to