hokein updated this revision to Diff 180843.
hokein added a comment.

Add a comment.


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 ScoredBundle &BundleAndScope = Top[i];
+      const CompletionCandidate::Bundle &CandidateBundle = BundleAndScope.first;
+      Output.Completions.push_back(toCodeCompletion(CandidateBundle));
+      Output.Completions.back().Score = BundleAndScope.second;
       Output.Completions.back().CompletionTokenRange = TextEditRange;
+
+      if (Opts.IncludeComments &&
+          Output.Completions.back().Documentation.empty()) {
+        if (CandidateBundle.size() == 1) {
+          if (const CodeCompletionResult *SemaR =
+                  CandidateBundle.front().SemaResult) {
+            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