kadircet created this revision.
kadircet added reviewers: ioeric, ilya-biryukov.
Herald added subscribers: cfe-commits, arphaman, jkorous, MaskRay.
kadircet added a dependency: D52225: [clang] Implement Override Suggestions in 
Sema..

Since we plan to move handling of override suggestions to Sema with
https://reviews.llvm.org/D52225 this patch just makes sure clangd-side has no 
logic related to that
anymore and updates tests.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52226

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

Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -1806,6 +1806,58 @@
   )cpp");
 }
 
+TEST(CompletionTest, SuggestOverridesWithPartialMatches) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+  auto File = testPath("foo.cpp");
+  const Annotations Test(R"cpp(
+  class A {
+   public:
+    virtual void vfunc(bool param);
+    virtual void vfunc(bool param, int p);
+    void func(bool param);
+  };
+  class B : public A {
+  virtual int ttt(bool param) const;
+  void vfunc(bool param, int p) override;
+  };
+  class C : public B {
+   public:
+    void vfunc(bool param) override;
+    $1^vo$2^id $3^
+  };
+  )cpp");
+  runAddDocument(Server, File, Test.code());
+  {
+    const auto Results = completions(Server, Test.code(), Test.point("1"));
+    EXPECT_THAT(
+        Results.Completions,
+        AllOf(Contains(Labeled("void vfunc(bool param, int p) override")),
+              Not(Contains(Labeled("void vfunc(bool param) override"))),
+              Contains(Labeled("int ttt(bool param) const override"))));
+  }
+  {
+    const auto Results = completions(Server, Test.code(), Test.point("2"));
+    EXPECT_THAT(
+        Results.Completions,
+        AllOf(Contains(Labeled("void vfunc(bool param, int p) override")),
+              Not(Contains(Labeled("void vfunc(bool param) override"))),
+              Not(Contains(Labeled("int ttt(bool param) const override")))));
+  }
+  {
+    const auto Results = completions(Server, Test.code(), Test.point("3"));
+    EXPECT_THAT(
+        Results.Completions,
+        AllOf(Not(Contains(Labeled("void vfunc(bool param, int p) override"))),
+              Not(Contains(Labeled("void vfunc(bool param) override"))),
+              Not(Contains(Labeled("int ttt(bool param) const override")))));
+  }
+}
+
+
 TEST(SpeculateCompletionFilter, Filters) {
   Annotations F(R"cpp($bof^
       $bol^
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -195,55 +195,6 @@
   return HeaderFile{std::move(*Resolved), /*Verbatim=*/false};
 }
 
-// First traverses all method definitions inside current class/struct/union
-// definition. Than traverses base classes to find virtual methods that haven't
-// been overriden within current context.
-// FIXME(kadircet): Currently we cannot see declarations below completion point.
-// It is because Sema gets run only upto completion point. Need to find a
-// solution to run it for the whole class/struct/union definition.
-static std::vector<CodeCompletionResult>
-getNonOverridenMethodCompletionResults(const DeclContext *DC, Sema *S) {
-  const auto *CR = llvm::dyn_cast<CXXRecordDecl>(DC);
-  // If not inside a class/struct/union return empty.
-  if (!CR)
-    return {};
-  // First store overrides within current class.
-  // These are stored by name to make querying fast in the later step.
-  llvm::StringMap<std::vector<FunctionDecl *>> Overrides;
-  for (auto *Method : CR->methods()) {
-    if (!Method->isVirtual() || !Method->getIdentifier())
-      continue;
-    Overrides[Method->getName()].push_back(Method);
-  }
-
-  std::vector<CodeCompletionResult> Results;
-  for (const auto &Base : CR->bases()) {
-    const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl();
-    if (!BR)
-      continue;
-    for (auto *Method : BR->methods()) {
-      if (!Method->isVirtual() || !Method->getIdentifier())
-        continue;
-      const auto it = Overrides.find(Method->getName());
-      bool IsOverriden = false;
-      if (it != Overrides.end()) {
-        for (auto *MD : it->second) {
-          // If the method in current body is not an overload of this virtual
-          // function, then it overrides this one.
-          if (!S->IsOverload(MD, Method, false)) {
-            IsOverriden = true;
-            break;
-          }
-        }
-      }
-      if (!IsOverriden)
-        Results.emplace_back(Method, 0);
-    }
-  }
-
-  return Results;
-}
-
 /// A code completion result, in clang-native form.
 /// It may be promoted to a CompletionItem if it's among the top-ranked results.
 struct CompletionCandidate {
@@ -253,9 +204,6 @@
   const Symbol *IndexResult = nullptr;
   llvm::SmallVector<StringRef, 1> RankedIncludeHeaders;
 
-  // States whether this item is an override suggestion.
-  bool IsOverride = false;
-
   // Returns a token identifying the overload set this is part of.
   // 0 indicates it's not part of any overload set.
   size_t overloadSet() const {
@@ -424,30 +372,21 @@
         Completion.Documentation = getDocComment(ASTCtx, *C.SemaResult,
                                                  /*CommentsFromHeader=*/false);
     }
-    if (C.IsOverride)
-      S.OverrideSuffix = true;
   }
 
   CodeCompletion build() {
     Completion.ReturnType = summarizeReturnType();
     Completion.Signature = summarizeSignature();
     Completion.SnippetSuffix = summarizeSnippet();
     Completion.BundleSize = Bundled.size();
-    if (summarizeOverride()) {
-      Completion.Name = Completion.ReturnType + ' ' +
-                        std::move(Completion.Name) +
-                        std::move(Completion.Signature) + " override";
-      Completion.Signature.clear();
-    }
     return std::move(Completion);
   }
 
 private:
   struct BundledEntry {
     std::string SnippetSuffix;
     std::string Signature;
     std::string ReturnType;
-    bool OverrideSuffix;
   };
 
   // If all BundledEntrys have the same value for a property, return it.
@@ -495,12 +434,6 @@
     return "(…)";
   }
 
-  bool summarizeOverride() const {
-    if (auto *OverrideSuffix = onlyValue<&BundledEntry::OverrideSuffix>())
-      return *OverrideSuffix;
-    return false;
-  }
-
   ASTContext &ASTCtx;
   CodeCompletion Completion;
   SmallVector<BundledEntry, 1> Bundled;
@@ -1358,11 +1291,8 @@
                             ? queryIndex()
                             : SymbolSlab();
     trace::Span Tracer("Populate CodeCompleteResult");
-    // Merge Sema, Index and Override results, score them, and pick the
-    // winners.
-    const auto Overrides = getNonOverridenMethodCompletionResults(
-        Recorder->CCSema->CurContext, Recorder->CCSema);
-    auto Top = mergeResults(Recorder->Results, IndexResults, Overrides);
+    // Merge Sema and Index results, score them, and pick the winners.
+    auto Top = mergeResults(Recorder->Results, IndexResults);
     CodeCompleteResult Output;
 
     // Convert the results to final form, assembling the expensive strings.
@@ -1413,26 +1343,22 @@
     return std::move(ResultsBuilder).build();
   }
 
-  // Merges Sema, Index and Override results where possible, to form
-  // CompletionCandidates. Groups overloads if desired, to form
-  // CompletionCandidate::Bundles. The bundles are scored and top results are
-  // returned, best to worst.
+  // Merges Sema and Index results where possible, to form CompletionCandidates.
+  // Groups overloads if desired, to form CompletionCandidate::Bundles. The
+  // bundles are scored and top results are returned, best to worst.
   std::vector<ScoredBundle>
   mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
-               const SymbolSlab &IndexResults,
-               const std::vector<CodeCompletionResult> &OverrideResults) {
+               const SymbolSlab &IndexResults) {
     trace::Span Tracer("Merge and score results");
     std::vector<CompletionCandidate::Bundle> Bundles;
     llvm::DenseMap<size_t, size_t> BundleLookup;
     auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
-                            const Symbol *IndexResult,
-                            bool IsOverride) {
+                            const Symbol *IndexResult) {
       CompletionCandidate C;
       C.SemaResult = SemaResult;
       C.IndexResult = IndexResult;
       if (C.IndexResult)
         C.RankedIncludeHeaders = getRankedIncludes(*C.IndexResult);
-      C.IsOverride = IsOverride;
       C.Name = IndexResult ? IndexResult->Name : Recorder->getName(*SemaResult);
       if (auto OverloadSet = Opts.BundleOverloads ? C.overloadSet() : 0) {
         auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
@@ -1459,19 +1385,12 @@
     };
     // Emit all Sema results, merging them with Index results if possible.
     for (auto &SemaResult : Recorder->Results)
-      AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult), false);
-    // Handle OverrideResults the same way we deal with SemaResults. Since these
-    // results use the same structs as a SemaResult it is safe to do that, but
-    // we need to make sure we dont' duplicate things in future if Sema starts
-    // to provide them as well.
-    for (auto &OverrideResult : OverrideResults)
-      AddToBundles(&OverrideResult, CorrespondingIndexResult(OverrideResult),
-                   true);
+      AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult));
     // Now emit any Index-only results.
     for (const auto &IndexResult : IndexResults) {
       if (UsedIndexResults.count(&IndexResult))
         continue;
-      AddToBundles(/*SemaResult=*/nullptr, &IndexResult, false);
+      AddToBundles(/*SemaResult=*/nullptr, &IndexResult);
     }
     // We only keep the best N results at any time, in "native" format.
     TopN<ScoredBundle, ScoredBundleGreater> Top(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to