diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/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 ShouldCheckLine) { + llvm::function_ref 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() ? "" : CC.Completions[0].Name); + } } } }; @@ -238,7 +247,8 @@ bool check(llvm::StringRef File, llvm::function_ref ShouldCheckLine, - const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts) { + const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, + bool EnableCodeCompletion) { llvm::SmallString<0> FakeFile; llvm::Optional 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; diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -62,7 +62,8 @@ // Implemented in Check.cpp. bool check(const llvm::StringRef File, llvm::function_ref ShouldCheckLine, - const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts); + const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, + 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(ErrorResultCode::CheckFailed); }