[clang-tools-extra] 3cb1220 - [clangd] Add `score` extension to workspace/symbol response.

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 6 02:57:46 PDT 2020


Author: Sam McCall
Date: 2020-10-06T11:57:38+02:00
New Revision: 3cb1220709fa556d4d29ce0e25fd30a16895ae24

URL: https://github.com/llvm/llvm-project/commit/3cb1220709fa556d4d29ce0e25fd30a16895ae24
DIFF: https://github.com/llvm/llvm-project/commit/3cb1220709fa556d4d29ce0e25fd30a16895ae24.diff

LOG: [clangd] Add `score` extension to workspace/symbol response.

The protocol doesn't really incorporate ranking.
As with code completion, most clients respect what the server sends, but
VSCode re-ranks items, with predictable results.
See https://github.com/clangd/vscode-clangd/issues/81

There's no filterText field so we may be unable to construct a good workaround.
But expose the score so we may be able to do this on the client in future.

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

Added: 
    

Modified: 
    clang-tools-extra/clangd/FindSymbols.cpp
    clang-tools-extra/clangd/Protocol.cpp
    clang-tools-extra/clangd/Protocol.h
    clang-tools-extra/clangd/test/symbols.test

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index e86c01d4076eb..8e21ae22dcd92 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -96,12 +96,13 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
       return;
     }
 
-    SymbolKind SK = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind);
-    std::string Scope = std::string(Sym.Scope);
-    llvm::StringRef ScopeRef = Scope;
-    ScopeRef.consume_back("::");
-    SymbolInformation Info = {(Sym.Name + Sym.TemplateSpecializationArgs).str(),
-                              SK, *Loc, std::string(ScopeRef)};
+    llvm::StringRef Scope = Sym.Scope;
+    Scope.consume_back("::");
+    SymbolInformation Info;
+    Info.name = (Sym.Name + Sym.TemplateSpecializationArgs).str();
+    Info.kind = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind);
+    Info.location = *Loc;
+    Info.containerName = Scope.str();
 
     SymbolQualitySignals Quality;
     Quality.merge(Sym);
@@ -121,6 +122,8 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
     dlog("FindSymbols: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, Sym.Name, Score,
          Quality, Relevance);
 
+    // Exposed score excludes fuzzy-match component, for client-side re-ranking.
+    Info.score = Score / Relevance.NameMatch;
     Top.push({Score, std::move(Info)});
   });
   for (auto &R : std::move(Top).items())

diff  --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 61a691f2048f0..5d50a7bea0349 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -662,12 +662,15 @@ bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R,
 }
 
 llvm::json::Value toJSON(const SymbolInformation &P) {
-  return llvm::json::Object{
+  llvm::json::Object O{
       {"name", P.name},
       {"kind", static_cast<int>(P.kind)},
       {"location", P.location},
       {"containerName", P.containerName},
   };
+  if (P.score)
+    O["score"] = *P.score;
+  return std::move(O);
 }
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &O,

diff  --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 4ef94e6e01db9..6f395ffb21c53 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1015,6 +1015,14 @@ struct SymbolInformation {
 
   /// The name of the symbol containing this symbol.
   std::string containerName;
+
+  /// The score that clangd calculates to rank the returned symbols.
+  /// This excludes the fuzzy-matching score between `name` and the query.
+  /// (Specifically, the last ::-separated component).
+  /// This can be used to re-rank results as the user types, using client-side
+  /// fuzzy-matching (that score should be multiplied with this one).
+  /// This is a clangd extension, set only for workspace/symbol responses.
+  llvm::Optional<float> score;
 };
 llvm::json::Value toJSON(const SymbolInformation &);
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);
@@ -1175,11 +1183,11 @@ struct CompletionItem {
   /// Indicates if this item is deprecated.
   bool deprecated = false;
 
-  /// This is Clangd extension.
-  /// The score that Clangd calculates to rank completion items. This score can
-  /// be used to adjust the ranking on the client side.
-  /// NOTE: This excludes fuzzy matching score which is typically calculated on
-  /// the client side.
+  /// The score that clangd calculates to rank the returned completions.
+  /// This excludes the fuzzy-match between `filterText` and the partial word.
+  /// This can be used to re-rank results as the user types, using client-side
+  /// fuzzy-matching (that score should be multiplied with this one).
+  /// This is a clangd extension.
   float score = 0.f;
 
   // TODO: Add custom commitCharacters for some of the completion items. For

diff  --git a/clang-tools-extra/clangd/test/symbols.test b/clang-tools-extra/clangd/test/symbols.test
index 38c5359074e57..6ab058da88362 100644
--- a/clang-tools-extra/clangd/test/symbols.test
+++ b/clang-tools-extra/clangd/test/symbols.test
@@ -23,7 +23,8 @@
 # CHECK-NEXT:          },
 # CHECK-NEXT:          "uri": "file://{{.*}}/vector.h"
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "name": "vector"
+# CHECK-NEXT:        "name": "vector",
+# CHECK-NEXT:        "score": {{.*}}
 # CHECK-NEXT:      }
 # CHECK-NEXT:    ]
 # CHECK-NEXT:}


        


More information about the cfe-commits mailing list