[clangd] Remove duplicates from code completion

Summary:
This patch removes hidden items from code completion.
Items can be hidden, e.g., by other items in the child scopes.
This patch addresses a particular problem of a duplicate completion
item for the class in the following example:

    struct Adapter { void method(); };
    void Adapter::method() {
       Adapter^
    }

We should probably investigate if there are other duplicates in
completion and remove them, possibly adding assertions that it never
happens.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: cfe-commits, klimek

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

llvm-svn: 322185
This commit is contained in:
Ilya Biryukov 2018-01-10 13:51:09 +00:00
parent 400c7b3c7a
commit f60bf347c9
2 changed files with 23 additions and 0 deletions

View File

@ -294,6 +294,13 @@ public:
std::priority_queue<CompletionCandidate> Candidates;
for (unsigned I = 0; I < NumResults; ++I) {
auto &Result = Results[I];
// We drop hidden items, as they cannot be found by the lookup after
// inserting the corresponding completion item and only produce noise and
// duplicates in the completion list. However, there is one exception. If
// Result has a Qualifier which is non-informative, we can refer to an
// item by adding that qualifier, so we don't filter out this item.
if (Result.Hidden && (!Result.Qualifier || Result.QualifierIsInformative))
continue;
if (!ClangdOpts.IncludeIneligibleResults &&
(Result.Availability == CXAvailability_NotAvailable ||
Result.Availability == CXAvailability_NotAccessible))

View File

@ -592,6 +592,22 @@ TEST(CompletionTest, ASTIndexMultiFile) {
Doc("Doooc"), Detail("void"))));
}
TEST(CompletionTest, NoDuplicates) {
auto Items = completions(R"cpp(
struct Adapter {
void method();
};
void Adapter::method() {
Adapter^
}
)cpp")
.items;
// Make sure there are no duplicate entries of 'Adapter'.
EXPECT_THAT(Items, ElementsAre(Named("Adapter"), Named("~Adapter")));
}
} // namespace
} // namespace clangd
} // namespace clang