diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 6fc6c5d21c24e54..52c1ceef7425985 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1850,6 +1850,8 @@ CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const { if (InsertInclude && InsertInclude->Insertion) LSP.additionalTextEdits.push_back(*InsertInclude->Insertion); + LSP.score = Score.ExcludingName; + return LSP; } diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index d607ffbbc815722..1e71c2ab37f5e99 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -869,6 +869,7 @@ llvm::json::Value toJSON(const CompletionItem &CI) { Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits); if (CI.deprecated) Result["deprecated"] = CI.deprecated; + Result["score"] = CI.score; return std::move(Result); } diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 3275cbbd17b1291..80a11ee003077b3 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1094,6 +1094,13 @@ 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. + float score = 0.f; + // TODO(krasimir): The following optional fields defined by the language // server protocol are unsupported: // diff --git a/clang-tools-extra/clangd/test/completion-auto-trigger.test b/clang-tools-extra/clangd/test/completion-auto-trigger.test index 46871b9d3e34cdd..cf7261e904330f5 100644 --- a/clang-tools-extra/clangd/test/completion-auto-trigger.test +++ b/clang-tools-extra/clangd/test/completion-auto-trigger.test @@ -24,6 +24,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " size", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}size", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "size", @@ -46,6 +47,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 10, # CHECK-NEXT: "label": " default_capacity", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}default_capacity", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "default_capacity", @@ -86,6 +88,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 6, # CHECK-NEXT: "label": " ns_member", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}ns_member", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "ns_member", diff --git a/clang-tools-extra/clangd/test/completion-snippets.test b/clang-tools-extra/clangd/test/completion-snippets.test index 22cd0821b2241d1..7dc980943859b5c 100644 --- a/clang-tools-extra/clangd/test/completion-snippets.test +++ b/clang-tools-extra/clangd/test/completion-snippets.test @@ -33,6 +33,7 @@ # CHECK-NEXT: "insertTextFormat": 2, # CHECK-NEXT: "kind": 3, # CHECK-NEXT: "label": " func_with_args(int a, int b)", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}func_with_args" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "func_with_args(${1:int a}, ${2:int b})", diff --git a/clang-tools-extra/clangd/test/completion.test b/clang-tools-extra/clangd/test/completion.test index 0094d4740b2590b..d6376b3bfe51bd0 100644 --- a/clang-tools-extra/clangd/test/completion.test +++ b/clang-tools-extra/clangd/test/completion.test @@ -17,6 +17,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}a" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "a", @@ -50,6 +51,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " b", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}b" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "b", diff --git a/clang-tools-extra/clangd/test/protocol.test b/clang-tools-extra/clangd/test/protocol.test index 3e16c9ec9b334a3..5e852d1d9deebca 100644 --- a/clang-tools-extra/clangd/test/protocol.test +++ b/clang-tools-extra/clangd/test/protocol.test @@ -39,6 +39,7 @@ Content-Length: 146 # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } @@ -68,6 +69,7 @@ Content-Length: 146 # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } @@ -97,6 +99,7 @@ Content-Length: 146 # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 67b8abb722be07d..a39c7431044f45b 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1627,6 +1627,7 @@ TEST(CompletionTest, Render) { Include.Header = "\"foo.h\""; C.Kind = CompletionItemKind::Method; C.Score.Total = 1.0; + C.Score.ExcludingName = .5; C.Origin = SymbolOrigin::AST | SymbolOrigin::Static; CodeCompleteOptions Opts; @@ -1644,6 +1645,7 @@ TEST(CompletionTest, Render) { EXPECT_THAT(R.additionalTextEdits, IsEmpty()); EXPECT_EQ(R.sortText, sortText(1.0, "x")); EXPECT_FALSE(R.deprecated); + EXPECT_EQ(R.score, .5f); Opts.EnableSnippets = true; R = C.render(Opts);