[clang-tools-extra] r332226 - [clangd] Don't query index when completing inside classes
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Mon May 14 03:50:04 PDT 2018
Author: ibiryukov
Date: Mon May 14 03:50:04 2018
New Revision: 332226
URL: http://llvm.org/viewvc/llvm-project?rev=332226&view=rev
Log:
[clangd] Don't query index when completing inside classes
Summary:
We used to query the index when completing after class qualifiers,
e.g. 'ClassName::^'. We should not do that for the same reasons we
don't query the index for member access expressions.
Reviewers: sammccall, ioeric
Reviewed By: sammccall
Subscribers: klimek, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D46795
Modified:
clang-tools-extra/trunk/clangd/CodeComplete.cpp
clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=332226&r1=332225&r2=332226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Mon May 14 03:50:04 2018
@@ -759,9 +759,9 @@ bool semaCodeComplete(std::unique_ptr<Co
return true;
}
-// Should we perform index-based completion in this context?
+// Should we perform index-based completion in a context of the specified kind?
// FIXME: consider allowing completion, but restricting the result types.
-bool allowIndex(enum CodeCompletionContext::Kind K) {
+bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
switch (K) {
case CodeCompletionContext::CCC_TopLevel:
case CodeCompletionContext::CCC_ObjCInterface:
@@ -803,6 +803,33 @@ bool allowIndex(enum CodeCompletionConte
llvm_unreachable("unknown code completion context");
}
+// Should we allow index completions in the specified context?
+bool allowIndex(CodeCompletionContext &CC) {
+ if (!contextAllowsIndex(CC.getKind()))
+ return false;
+ // We also avoid ClassName::bar (but allow namespace::bar).
+ auto Scope = CC.getCXXScopeSpecifier();
+ if (!Scope)
+ return true;
+ NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
+ if (!NameSpec)
+ return true;
+ // We only query the index when qualifier is a namespace.
+ // If it's a class, we rely solely on sema completions.
+ switch (NameSpec->getKind()) {
+ case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ return true;
+ case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ // Unresolved inside a template.
+ case NestedNameSpecifier::Identifier:
+ return false;
+ }
+}
+
} // namespace
clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
@@ -918,7 +945,7 @@ private:
}
SymbolSlab queryIndex() {
- if (!Opts.Index || !allowIndex(Recorder->CCContext.getKind()))
+ if (!Opts.Index || !allowIndex(Recorder->CCContext))
return SymbolSlab();
trace::Span Tracer("Query index");
SPAN_ATTACH(Tracer, "limit", Opts.Limit);
Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=332226&r1=332225&r2=332226&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Mon May 14 03:50:04 2018
@@ -825,6 +825,67 @@ TEST(CompletionTest, GlobalQualifiedQuer
UnorderedElementsAre(""))));
}
+TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
+ auto Completions = completions(
+ R"cpp(
+ struct Foo {
+ int SomeNameOfField;
+ typedef int SomeNameOfTypedefField;
+ };
+
+ Foo::^)cpp",
+ {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
+
+ EXPECT_THAT(Completions.items,
+ AllOf(Contains(Labeled("SomeNameOfField")),
+ Contains(Labeled("SomeNameOfTypedefField")),
+ Not(Contains(Labeled("SomeNameInTheIndex")))));
+}
+
+TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
+ {
+ auto Completions = completions(
+ R"cpp(
+ template <class T>
+ void foo() {
+ T::^
+ }
+ )cpp",
+ {func("::SomeNameInTheIndex")});
+
+ EXPECT_THAT(Completions.items,
+ Not(Contains(Labeled("SomeNameInTheIndex"))));
+ }
+
+ {
+ auto Completions = completions(
+ R"cpp(
+ template <class T>
+ void foo() {
+ T::template Y<int>::^
+ }
+ )cpp",
+ {func("::SomeNameInTheIndex")});
+
+ EXPECT_THAT(Completions.items,
+ Not(Contains(Labeled("SomeNameInTheIndex"))));
+ }
+
+ {
+ auto Completions = completions(
+ R"cpp(
+ template <class T>
+ void foo() {
+ T::foo::^
+ }
+ )cpp",
+ {func("::SomeNameInTheIndex")});
+
+ EXPECT_THAT(Completions.items,
+ Not(Contains(Labeled("SomeNameInTheIndex"))));
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
More information about the cfe-commits
mailing list