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

No noticeable impact on code completions overall except some improvement on
cross-namespace completion.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D57815

Files:
  clangd/CodeComplete.cpp
  clangd/index/Index.cpp
  clangd/index/Index.h
  clangd/index/dex/Dex.cpp
  clangd/index/dex/Token.h
  unittests/clangd/DexTests.cpp

Index: unittests/clangd/DexTests.cpp
===================================================================
--- unittests/clangd/DexTests.cpp
+++ unittests/clangd/DexTests.cpp
@@ -688,6 +688,28 @@
   EXPECT_THAT(Files, ElementsAre(AnyOf("foo.h", "foo.cc")));
 }
 
+TEST(DexTest, PreferredTypesBoosting) {
+  auto Sym1 = symbol("t1");
+  Sym1.Type = "T1";
+  auto Sym2 = symbol("t2");
+  Sym2.Type = "T2";
+
+  std::vector<Symbol> Symbols{Sym1, Sym2};
+  Dex I(Symbols, RefSlab());
+
+  FuzzyFindRequest Req;
+  Req.AnyScope = true;
+  Req.Query = "t";
+  // The best candidate can change depending on the proximity paths.
+  Req.Limit = 1;
+
+  Req.PreferredTypes = {Sym1.Type};
+  EXPECT_THAT(match(I, Req), ElementsAre("t1"));
+
+  Req.PreferredTypes = {Sym2.Type};
+  EXPECT_THAT(match(I, Req), ElementsAre("t2"));
+}
+
 } // namespace
 } // namespace dex
 } // namespace clangd
Index: clangd/index/dex/Token.h
===================================================================
--- clangd/index/dex/Token.h
+++ clangd/index/dex/Token.h
@@ -62,11 +62,11 @@
     /// Example: "file:///path/to/clang-tools-extra/clangd/index/SymbolIndex.h"
     /// and some amount of its parents.
     ProximityURI,
+    /// Type of symbol (see `Symbol::Type`).
+    Type,
     /// Internal Token type for invalid/special tokens, e.g. empty tokens for
     /// llvm::DenseMap.
     Sentinel,
-    /// FIXME(kbobyrev): Add other Token Kinds
-    /// * Type with qualified type name or its USR
   };
 
   Token(Kind TokenKind, llvm::StringRef Data)
@@ -91,6 +91,9 @@
     case Kind::ProximityURI:
       OS << "U=";
       break;
+    case Kind::Type:
+      OS << "Ty=";
+      break;
     case Kind::Sentinel:
       OS << "?=";
       break;
Index: clangd/index/dex/Dex.cpp
===================================================================
--- clangd/index/dex/Dex.cpp
+++ clangd/index/dex/Dex.cpp
@@ -42,7 +42,6 @@
 // Returns the tokens which are given symbols's characteristics. For example,
 // trigrams and scopes.
 // FIXME(kbobyrev): Support more token types:
-// * Types
 // * Namespace proximity
 std::vector<Token> generateSearchTokens(const Symbol &Sym) {
   std::vector<Token> Result = generateIdentifierTrigrams(Sym.Name);
@@ -54,6 +53,8 @@
       Result.emplace_back(Token::Kind::ProximityURI, ProximityURI);
   if (Sym.Flags & Symbol::IndexedForCodeCompletion)
     Result.emplace_back(RestrictedForCodeCompletion);
+  if (!Sym.Type.empty())
+    Result.emplace_back(Token::Kind::Type, Sym.Type);
   return Result;
 }
 
@@ -97,6 +98,27 @@
   return Corpus.unionOf(std::move(BoostingIterators));
 }
 
+// Constructs BOOST iterators for preferred types.
+std::unique_ptr<Iterator> createTypeBoostingIterator(
+    llvm::ArrayRef<std::string> Types,
+    const llvm::DenseMap<Token, PostingList> &InvertedIndex,
+    const Corpus &Corpus) {
+  std::vector<std::unique_ptr<Iterator>> BoostingIterators;
+  SymbolRelevanceSignals PreferredTypeSignals;
+  PreferredTypeSignals.TypeMatchesPreferred = true;
+  auto Boost = PreferredTypeSignals.evaluate();
+  for (const auto &T : Types) {
+    Token Tok(Token::Kind::Type, T);
+    const auto It = InvertedIndex.find(Tok);
+    if (It != InvertedIndex.end()) {
+      BoostingIterators.push_back(
+          Corpus.boost(It->second.iterator(&It->first), Boost));
+    }
+  }
+  BoostingIterators.push_back(Corpus.all());
+  return Corpus.unionOf(std::move(BoostingIterators));
+}
+
 } // namespace
 
 void Dex::buildIndex() {
@@ -176,6 +198,9 @@
   // Add proximity paths boosting (all symbols, some boosted).
   Criteria.push_back(
       createFileProximityIterator(Req.ProximityPaths, InvertedIndex, Corpus));
+  // Add boosting for preferred types.
+  Criteria.push_back(
+      createTypeBoostingIterator(Req.PreferredTypes, InvertedIndex, Corpus));
 
   if (Req.RestrictForCodeCompletion)
     Criteria.push_back(iterator(RestrictedForCodeCompletion));
Index: clangd/index/Index.h
===================================================================
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -454,14 +454,15 @@
   /// Contextually relevant files (e.g. the file we're code-completing in).
   /// Paths should be absolute.
   std::vector<std::string> ProximityPaths;
-
-  // FIXME(ibiryukov): add expected type to the request.
+  /// Preferred types of symbols.
+  std::vector<std::string> PreferredTypes;
 
   bool operator==(const FuzzyFindRequest &Req) const {
     return std::tie(Query, Scopes, Limit, RestrictForCodeCompletion,
-                    ProximityPaths) ==
+                    ProximityPaths, PreferredTypes) ==
            std::tie(Req.Query, Req.Scopes, Req.Limit,
-                    Req.RestrictForCodeCompletion, Req.ProximityPaths);
+                    Req.RestrictForCodeCompletion, Req.ProximityPaths,
+                    Req.PreferredTypes);
   }
   bool operator!=(const FuzzyFindRequest &Req) const { return !(*this == Req); }
 };
Index: clangd/index/Index.cpp
===================================================================
--- clangd/index/Index.cpp
+++ clangd/index/Index.cpp
@@ -179,7 +179,8 @@
       O && O.map("Query", Request.Query) && O.map("Scopes", Request.Scopes) &&
       O.map("AnyScope", Request.AnyScope) && O.map("Limit", Limit) &&
       O.map("RestrictForCodeCompletion", Request.RestrictForCodeCompletion) &&
-      O.map("ProximityPaths", Request.ProximityPaths);
+      O.map("ProximityPaths", Request.ProximityPaths) &&
+      O.map("PreferredTypes", Request.PreferredTypes);
   if (OK && Limit <= std::numeric_limits<uint32_t>::max())
     Request.Limit = Limit;
   return OK;
@@ -193,6 +194,7 @@
       {"Limit", Request.Limit},
       {"RestrictForCodeCompletion", Request.RestrictForCodeCompletion},
       {"ProximityPaths", llvm::json::Array{Request.ProximityPaths}},
+      {"PreferredTypes", llvm::json::Array{Request.PreferredTypes}},
   };
 }
 
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -1333,6 +1333,8 @@
     Req.AnyScope = AllScopes;
     // FIXME: we should send multiple weighted paths here.
     Req.ProximityPaths.push_back(FileName);
+    if (PreferredType)
+      Req.PreferredTypes.push_back(PreferredType->raw());
     vlog("Code complete: fuzzyFind({0:2})", toJSON(Req));
 
     if (SpecFuzzyFind)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to