This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE332226: [clangd] Don't query index when completing 
inside classes (authored by ibiryukov, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D46795?vs=146571&id=146574#toc

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D46795

Files:
  clangd/CodeComplete.cpp
  unittests/clangd/CodeCompleteTests.cpp

Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -825,6 +825,67 @@
                                           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
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -759,9 +759,9 @@
   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 @@
   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 @@
   }
 
   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);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to