[clangd] Code completion: drop explicit injected names/operators, ignore Sema priority
Summary:
Now we have most of Sema's code completion signals incorporated in Quality,
which will allow us to give consistent ranking to sema/index results.
Therefore we can/should stop using Sema priority as an explicit signal.
This fixes some issues like namespaces always having a terrible score.
The most important missing signals are:
- Really dumb/rarely useful completions like:
SomeStruct().^SomeStruct
SomeStruct().^operator=
SomeStruct().~SomeStruct()
We already filter out destructors, this patch adds injected names and
operators to that list.
- type matching the expression context.
Ilya has a plan to add this in a way that's compatible with indexes
(design doc should be shared real soon now!)
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D47871
llvm-svn: 334192
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 6fb1d9a..0859d63 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -467,6 +467,25 @@
llvm_unreachable("unknown code completion context");
}
+// Some member calls are blacklisted because they're so rarely useful.
+static bool isBlacklistedMember(const NamedDecl &D) {
+ // Destructor completion is rarely useful, and works inconsistently.
+ // (s.^ completes ~string, but s.~st^ is an error).
+ if (D.getKind() == Decl::CXXDestructor)
+ return true;
+ // Injected name may be useful for A::foo(), but who writes A::A::foo()?
+ if (auto *R = dyn_cast_or_null<RecordDecl>(&D))
+ if (R->isInjectedClassName())
+ return true;
+ // Explicit calls to operators are also rare.
+ auto NameKind = D.getDeclName().getNameKind();
+ if (NameKind == DeclarationName::CXXOperatorName ||
+ NameKind == DeclarationName::CXXLiteralOperatorName ||
+ NameKind == DeclarationName::CXXConversionFunctionName)
+ return true;
+ return false;
+}
+
// The CompletionRecorder captures Sema code-complete output, including context.
// It filters out ignored results (but doesn't apply fuzzy-filtering yet).
// It doesn't do scoring or conversion to CompletionItem yet, as we want to
@@ -520,9 +539,9 @@
(Result.Availability == CXAvailability_NotAvailable ||
Result.Availability == CXAvailability_NotAccessible))
continue;
- // Destructor completion is rarely useful, and works inconsistently.
- // (s.^ completes ~string, but s.~st^ is an error).
- if (dyn_cast_or_null<CXXDestructorDecl>(Result.Declaration))
+ if (Result.Declaration &&
+ !Context.getBaseType().isNull() // is this a member-access context?
+ && isBlacklistedMember(*Result.Declaration))
continue;
// We choose to never append '::' to completion results in clangd.
Result.StartsNestedNameSpecifier = false;