From cabab29af2d86ec03459cc3b57dd727b0a9c96d2 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Fri, 24 May 2019 10:18:39 +0000 Subject: [PATCH] [CodeComplete] Filter override completions by function name Summary: We put only part of the signature starting with a function name into "typed text" chunks now, previously the whole signature was "typed text". This leads to meaningful fuzzy match scores, giving better signals to compare with other completion items. Ideally, we would not display the result type to the user, but that requires adding a new kind of completion chunk. Reviewers: kadircet Reviewed By: kadircet Subscribers: jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D62298 llvm-svn: 361623 --- .../clangd/unittests/CodeCompleteTests.cpp | 14 +++++-- clang/lib/Sema/SemaCodeComplete.cpp | 47 +++++++++++++--------- clang/test/CodeCompletion/overrides.cpp | 12 +++--- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index e584597..8f8376e 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -49,6 +49,9 @@ class IgnoreDiagnostics : public DiagnosticsConsumer { // GMock helpers for matching completion items. MATCHER_P(Named, Name, "") { return arg.Name == Name; } +MATCHER_P(NameStartsWith, Prefix, "") { + return llvm::StringRef(arg.Name).startswith(Prefix); +} MATCHER_P(Scope, S, "") { return arg.Scope == S; } MATCHER_P(Qualifier, Q, "") { return arg.RequiredQualifier == Q; } MATCHER_P(Labeled, Label, "") { @@ -1946,10 +1949,13 @@ TEST(CompletionTest, SuggestOverrides) { }; )cpp"); const auto Results = completions(Text); - EXPECT_THAT(Results.Completions, - AllOf(Contains(Labeled("void vfunc(bool param, int p) override")), - Contains(Labeled("void ttt(bool param) const override")), - Not(Contains(Labeled("void vfunc(bool param) override"))))); + EXPECT_THAT( + Results.Completions, + AllOf(Contains(AllOf(Labeled("void vfunc(bool param, int p) override"), + NameStartsWith("vfunc"))), + Contains(AllOf(Labeled("void ttt(bool param) const override"), + NameStartsWith("ttt"))), + Not(Contains(Labeled("void vfunc(bool param) override"))))); } TEST(CompletionTest, OverridesNonIdentName) { diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index e6c0b68..27e6842 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/Path.h" #include #include +#include #include using namespace clang; @@ -1828,19 +1829,6 @@ static void AddStaticAssertResult(CodeCompletionBuilder &Builder, Results.AddResult(CodeCompletionResult(Builder.TakeString())); } -static void printOverrideString(llvm::raw_ostream &OS, - CodeCompletionString *CCS) { - for (const auto &C : *CCS) { - if (C.Kind == CodeCompletionString::CK_Optional) - printOverrideString(OS, C.Optional); - else - OS << C.Text; - // Add a space after return type. - if (C.Kind == CodeCompletionString::CK_ResultType) - OS << ' '; - } -} - static void AddOverrideResults(ResultBuilder &Results, const CodeCompletionContext &CCContext, CodeCompletionBuilder &Builder) { @@ -3162,19 +3150,42 @@ CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString( PP, Ctx, Result, IncludeBriefComments, CCContext, Policy); } +static void printOverrideString(const CodeCompletionString &CCS, + std::string &BeforeName, + std::string &NameAndSignature) { + bool SeenTypedChunk = false; + for (auto &Chunk : CCS) { + if (Chunk.Kind == CodeCompletionString::CK_Optional) { + assert(SeenTypedChunk && "optional parameter before name"); + // Note that we put all chunks inside into NameAndSignature. + printOverrideString(*Chunk.Optional, NameAndSignature, NameAndSignature); + continue; + } + SeenTypedChunk |= Chunk.Kind == CodeCompletionString::CK_TypedText; + if (SeenTypedChunk) + NameAndSignature += Chunk.Text; + else + BeforeName += Chunk.Text; + } +} + CodeCompletionString * CodeCompletionResult::createCodeCompletionStringForOverride( Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, bool IncludeBriefComments, const CodeCompletionContext &CCContext, PrintingPolicy &Policy) { - std::string OverrideSignature; - llvm::raw_string_ostream OS(OverrideSignature); auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result, /*IncludeBriefComments=*/false, CCContext, Policy); - printOverrideString(OS, CCS); - OS << " override"; - Result.AddTypedTextChunk(Result.getAllocator().CopyString(OS.str())); + std::string BeforeName; + std::string NameAndSignature; + // For overrides all chunks go into the result, none are informative. + printOverrideString(*CCS, BeforeName, NameAndSignature); + NameAndSignature += " override"; + + Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName)); + Result.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Result.AddTypedTextChunk(Result.getAllocator().CopyString(NameAndSignature)); return Result.TakeString(); } diff --git a/clang/test/CodeCompletion/overrides.cpp b/clang/test/CodeCompletion/overrides.cpp index 06cff6a..6645569 100644 --- a/clang/test/CodeCompletion/overrides.cpp +++ b/clang/test/CodeCompletion/overrides.cpp @@ -11,23 +11,23 @@ void vfunc(bool param, int p) override; class C : public B { public: void vfunc(bool param) override; - void + vf }; -// Runs completion at ^void. +// Runs completion at ^vf // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:3 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: COMPLETION: Pattern : int ttt(bool param, int x = 3) const override{{$}} // CHECK-CC1: COMPLETION: Pattern : void vfunc(bool param, int p) override{{$}} // CHECK-CC1-NOT: COMPLETION: Pattern : void vfunc(bool param) override{{$}} // -// Runs completion at vo^id. +// Runs completion at vf^ // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:5 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s -// CHECK-CC2: COMPLETION: Pattern : void vfunc(bool param, int p) override{{$}} // CHECK-CC2-NOT: COMPLETION: Pattern : int ttt(bool param, int x = 3) const override{{$}} +// CHECK-CC2: COMPLETION: Pattern : void vfunc(bool param, int p) override{{$}} // CHECK-CC2-NOT: COMPLETION: Pattern : void vfunc(bool param) override{{$}} // -// Runs completion at void ^. -// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:8 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s +// Runs completion at void ^ on line 13. +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:13:8 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3-NOT: COMPLETION: Pattern : int ttt(bool param, int x = 3) const override{{$}} // CHECK-CC3-NOT: COMPLETION: Pattern : void vfunc(bool param, int p) override{{$}} // CHECK-CC3-NOT: COMPLETION: Pattern : void vfunc(bool param) override{{$}} -- 2.7.4