ilya-biryukov created this revision. ilya-biryukov added a reviewer: sammccall. Herald added a subscriber: klimek.
This patch removes hidden items from code completion. Hidden items are the ones that are hidden by other items (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. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D41901 Files: clangd/CodeComplete.cpp unittests/clangd/CodeCompleteTests.cpp Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -583,6 +583,22 @@ EXPECT_THAT(Results.items, Has("fooooo", CompletionItemKind::Function)); } +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 Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -294,6 +294,13 @@ 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))
Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -583,6 +583,22 @@ EXPECT_THAT(Results.items, Has("fooooo", CompletionItemKind::Function)); } +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 Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -294,6 +294,13 @@ 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))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits