[PATCH] D103538: [clangd] Run code completion on each token coverd by --check-lines

Adam Czachorowski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 2 10:48:36 PDT 2021


adamcz created this revision.
Herald added subscribers: usaxena95, kadircet, arphaman.
adamcz requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

In --check mode we do not run code completion because it is too slow,
especially on larger files. With the introducation of --check-lines we
can narrow down the scope and thus we can afford to do code completion.

We vlog() the top completion result, but that's not really the point.
The most value will come from being able to reproduce crashes that occur
during code completion and require preamble build or index (and thus are
more difficult to reproduce with -code-complete-at).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103538

Files:
  clang-tools-extra/clangd/tool/Check.cpp
  clang-tools-extra/clangd/tool/ClangdMain.cpp


Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===================================================================
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -62,7 +62,8 @@
 // Implemented in Check.cpp.
 bool check(const llvm::StringRef File,
            llvm::function_ref<bool(const Position &)> ShouldCheckLine,
-           const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts);
+           const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts,
+           const bool EnableCodeCompletion);
 
 namespace {
 
@@ -929,7 +930,11 @@
       uint32_t Line = Pos.line + 1; // Position::line is 0-based.
       return Line >= Begin && Line <= End;
     };
-    return check(Path, ShouldCheckLine, TFS, Opts)
+    // For now code completion is enabled any time the range is limited via
+    // --check-lines. If it turns out to be to slow, we can introduce a
+    // dedicated flag for that instead.
+    return check(Path, ShouldCheckLine, TFS, Opts,
+                 /*EnableCodeCompletion=*/!CheckFileLines.empty())
                ? 0
                : static_cast<int>(ErrorResultCode::CheckFailed);
   }
Index: clang-tools-extra/clangd/tool/Check.cpp
===================================================================
--- clang-tools-extra/clangd/tool/Check.cpp
+++ clang-tools-extra/clangd/tool/Check.cpp
@@ -193,10 +193,15 @@
 
   // Run AST-based features at each token in the file.
   void testLocationFeatures(
-      llvm::function_ref<bool(const Position &)> ShouldCheckLine) {
+      llvm::function_ref<bool(const Position &)> ShouldCheckLine,
+      const bool EnableCodeCompletion) {
     log("Testing features at each token (may be slow in large files)");
     auto &SM = AST->getSourceManager();
     auto SpelledTokens = AST->getTokens().spelledTokens(SM.getMainFileID());
+
+    CodeCompleteOptions CCOpts = Opts.CodeComplete;
+    CCOpts.Index = &Index;
+
     for (const auto &Tok : SpelledTokens) {
       unsigned Start = AST->getSourceManager().getFileOffset(Tok.location());
       unsigned End = Start + Tok.length();
@@ -228,8 +233,12 @@
       auto Hover = getHover(*AST, Pos, Style, &Index);
       vlog("    hover: {0}", Hover.hasValue());
 
-      // FIXME: it'd be nice to include code completion, but it's too slow.
-      // Maybe in combination with a line restriction?
+      if (EnableCodeCompletion) {
+        Position EndPos = offsetToPosition(Inputs.Contents, End);
+        auto CC = codeComplete(File, EndPos, Preamble.get(), Inputs, CCOpts);
+        vlog("    code completion: {0}",
+             CC.Completions.empty() ? "<empty>" : CC.Completions[0].Name);
+      }
     }
   }
 };
@@ -238,7 +247,8 @@
 
 bool check(llvm::StringRef File,
            llvm::function_ref<bool(const Position &)> ShouldCheckLine,
-           const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts) {
+           const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts,
+           const bool EnableCodeCompletion) {
   llvm::SmallString<0> FakeFile;
   llvm::Optional<std::string> Contents;
   if (File.empty()) {
@@ -262,7 +272,7 @@
   if (!C.buildCommand(TFS) || !C.buildInvocation(TFS, Contents) ||
       !C.buildAST())
     return false;
-  C.testLocationFeatures(ShouldCheckLine);
+  C.testLocationFeatures(ShouldCheckLine, EnableCodeCompletion);
 
   log("All checks completed, {0} errors", C.ErrCount);
   return C.ErrCount == 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103538.349325.patch
Type: text/x-patch
Size: 3456 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210602/14938a78/attachment.bin>


More information about the cfe-commits mailing list