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:} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits