[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