hokein updated this revision to Diff 181009.
hokein marked 3 inline comments as done.
hokein added a comment.

Address comments.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56492/new/

https://reviews.llvm.org/D56492

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

Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -729,6 +729,64 @@
                         Doc("Doooc"), ReturnType("void"))));
 }
 
+TEST(CompletionTest, DocumentationFromIndex) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  FS.Files[testPath("foo.h")] = R"cpp(
+      class Foo {
+      public:
+        // Doc for foo
+        int foo();
+
+        // Doc for foo int
+        int foo2(int);
+        // Doc for foo bool
+        int foo2(bool);
+      };
+  )cpp";
+
+  auto File = testPath("bar.cpp");
+  Annotations Test(R"cpp(
+      #include "foo.h"
+      void test() {
+        Foo f;
+        f.^
+      }
+  )cpp");
+  auto Opts = ClangdServer::optsForTest();
+  {
+    // Run code completion without index, verify that we don't get any docs from
+    // Sema.
+    Opts.BuildDynamicSymbolIndex = false;
+    ClangdServer Server(CDB, FS, DiagConsumer, Opts);
+    runAddDocument(Server, File, Test.code());
+    auto Results = cantFail(runCodeComplete(Server, File, Test.point(), {}));
+    EXPECT_THAT(
+        Results.Completions,
+        Contains((Named("foo"), Kind(CompletionItemKind::Method), Doc(""))));
+    EXPECT_THAT(
+        Results.Completions,
+        Contains((Named("foo2"), Kind(CompletionItemKind::Method), Doc(""))));
+  }
+  {
+    Opts.BuildDynamicSymbolIndex = true;
+    ClangdServer Server(CDB, FS, DiagConsumer, Opts);
+    runAddDocument(Server, File, Test.code());
+    clangd::CodeCompleteOptions CCOpts;
+    CCOpts.BundleOverloads = true;
+    auto Results =
+        cantFail(runCodeComplete(Server, File, Test.point(), CCOpts));
+    EXPECT_THAT(Results.Completions,
+                Contains((Named("foo"), Kind(CompletionItemKind::Method),
+                          Doc("Doc for foo"))));
+    // No doc for overload bundle.
+    EXPECT_THAT(
+        Results.Completions,
+        Contains((Named("foo2"), Kind(CompletionItemKind::Method), Doc(""))));
+  }
+}
+
 TEST(CompletionTest, Documentation) {
   auto Results = completions(
       R"cpp(
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -1366,11 +1366,45 @@
     auto Top = mergeResults(Recorder->Results, IndexResults);
     CodeCompleteResult Output;
 
+    // Keys are indices into Output vector.
+    llvm::DenseMap<size_t, SymbolID> OutputIndex;
+    LookupRequest DocIndexRequest;
     // Convert the results to final form, assembling the expensive strings.
-    for (auto &C : Top) {
-      Output.Completions.push_back(toCodeCompletion(C.first));
-      Output.Completions.back().Score = C.second;
+    for (size_t I = 0; I < Top.size(); ++I) {
+      const auto& Bundle = Top[I].first;
+      const auto& Scope = Top[I].second;
+      Output.Completions.push_back(toCodeCompletion(Bundle));
+      Output.Completions.back().Score = Scope;
       Output.Completions.back().CompletionTokenRange = TextEditRange;
+
+      if (Opts.IncludeComments &&
+          Output.Completions.back().Documentation.empty()) {
+        if (Bundle.size() != 1)
+          continue;
+        const auto *SemaR = Bundle.front().SemaResult;
+        if (!SemaR)
+          continue;
+        if (auto ID =
+                getSymbolID(*SemaR, Recorder->CCSema->getSourceManager())) {
+          OutputIndex[I] = *ID;
+          DocIndexRequest.IDs.insert(*ID);
+        }
+      }
+    }
+    // Sema doesn't load docs from the preamble, so we get the docs from the
+    // index and assemble them for the final results.
+    if (!DocIndexRequest.IDs.empty() && Opts.Index) {
+      llvm::DenseMap<SymbolID, std::string> FetchedDocs;
+      Opts.Index->lookup(DocIndexRequest, [&](const Symbol &S) {
+        if (!S.Documentation.empty())
+          FetchedDocs[S.ID] = S.Documentation;
+      });
+      for (auto IndexAndID : OutputIndex) {
+        auto FetchDocsIt = FetchedDocs.find(IndexAndID.second);
+        if (FetchDocsIt != FetchedDocs.end())
+          Output.Completions[IndexAndID.first].Documentation =
+              FetchDocsIt->second;
+      }
     }
     Output.HasMore = Incomplete;
     Output.Context = Recorder->CCContext.getKind();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to