Index: clangd/ClangdLSPServer.h =================================================================== --- clangd/ClangdLSPServer.h +++ clangd/ClangdLSPServer.h @@ -96,7 +96,8 @@ // before ClangdServer. DirectoryBasedGlobalCompilationDatabase CDB; RealFileSystemProvider FSProvider; - + /// Options used for code completion + clangd::CodeCompleteOptions CCOpts; // Server must be the last member of the class to allow its destructor to exit // the worker thread that may otherwise run an async callback on partially // destructed instance of ClangdLSPServer. Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -194,14 +194,15 @@ } void ClangdLSPServer::onCompletion(Ctx C, TextDocumentPositionParams &Params) { - auto List = Server - .codeComplete( - Params.textDocument.uri.file, - Position{Params.position.line, Params.position.character}) - .get() // FIXME(ibiryukov): This could be made async if we - // had an API that would allow to attach callbacks to - // futures returned by ClangdServer. - .Value; + auto List = + Server + .codeComplete( + Params.textDocument.uri.file, + Position{Params.position.line, Params.position.character}, CCOpts) + .get() // FIXME(ibiryukov): This could be made async if we + // had an API that would allow to attach callbacks to + // futures returned by ClangdServer. + .Value; C.reply(List); } @@ -240,9 +241,9 @@ llvm::Optional ResourceDir, llvm::Optional CompileCommandsDir) : Out(Out), CDB(/*Logger=*/Out, std::move(CompileCommandsDir)), - Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount, - StorePreamblesInMemory, CCOpts, - /*Logger=*/Out, ResourceDir) {} + CCOpts(CCOpts), Server(CDB, /*DiagConsumer=*/*this, FSProvider, + AsyncThreadsCount, StorePreamblesInMemory, + /*Logger=*/Out, ResourceDir) {} bool ClangdLSPServer::run(std::istream &In) { assert(!IsDone && "Run was called before"); Index: clangd/ClangdServer.h =================================================================== --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -210,7 +210,6 @@ DiagnosticsConsumer &DiagConsumer, FileSystemProvider &FSProvider, unsigned AsyncThreadsCount, bool StorePreamblesInMemory, - const clangd::CodeCompleteOptions &CodeCompleteOpts, clangd::Logger &Logger, llvm::Optional ResourceDir = llvm::None); @@ -254,6 +253,7 @@ /// while returned future is not yet ready. std::future> codeComplete(PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional OverridenContents = llvm::None, IntrusiveRefCntPtr *UsedFS = nullptr); @@ -261,6 +261,7 @@ /// when codeComplete results become available. void codeComplete(UniqueFunction)> Callback, PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional OverridenContents = llvm::None, IntrusiveRefCntPtr *UsedFS = nullptr); @@ -327,7 +328,6 @@ llvm::Optional RootPath; std::shared_ptr PCHs; bool StorePreamblesInMemory; - clangd::CodeCompleteOptions CodeCompleteOpts; /// Used to serialize diagnostic callbacks. /// FIXME(ibiryukov): get rid of an extra map and put all version counters /// into CppFile. Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -173,16 +173,14 @@ DiagnosticsConsumer &DiagConsumer, FileSystemProvider &FSProvider, unsigned AsyncThreadsCount, - bool StorePreamblesInMemory, - const clangd::CodeCompleteOptions &CodeCompleteOpts, - clangd::Logger &Logger, + bool StorePreamblesInMemory, clangd::Logger &Logger, llvm::Optional ResourceDir) : Logger(Logger), CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider), ResourceDir(ResourceDir ? ResourceDir->str() : getStandardResourceDir()), PCHs(std::make_shared()), StorePreamblesInMemory(StorePreamblesInMemory), - CodeCompleteOpts(CodeCompleteOpts), WorkScheduler(AsyncThreadsCount) {} + WorkScheduler(AsyncThreadsCount) {} void ClangdServer::setRootPath(PathRef RootPath) { std::string NewRootPath = llvm::sys::path::convert_to_slash( @@ -226,6 +224,7 @@ std::future> ClangdServer::codeComplete(PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional OverridenContents, IntrusiveRefCntPtr *UsedFS) { using ResultType = Tagged; @@ -239,13 +238,14 @@ std::future ResultFuture = ResultPromise.get_future(); codeComplete(BindWithForward(Callback, std::move(ResultPromise)), File, Pos, - OverridenContents, UsedFS); + Opts, OverridenContents, UsedFS); return ResultFuture; } void ClangdServer::codeComplete( UniqueFunction)> Callback, PathRef File, - Position Pos, llvm::Optional OverridenContents, + Position Pos, const clangd::CodeCompleteOptions &Opts, + llvm::Optional OverridenContents, IntrusiveRefCntPtr *UsedFS) { using CallbackType = UniqueFunction)>; @@ -274,6 +274,7 @@ std::shared_ptr Preamble = Resources->getPossiblyStalePreamble(); // A task that will be run asynchronously. + auto CodeCompleteOpts = Opts; auto Task = // 'mutable' to reassign Preamble variable. [=](CallbackType Callback) mutable { Index: unittests/clangd/ClangdTests.cpp =================================================================== --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -333,7 +333,6 @@ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true); ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); for (const auto &FileWithContents : ExtraFiles) FS.Files[getVirtualTestFilePath(FileWithContents.first)] = @@ -398,7 +397,6 @@ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true); ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); const auto SourceContents = R"cpp( @@ -445,7 +443,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); const auto SourceContents = R"cpp( @@ -495,7 +492,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, /*AsyncThreadsCount=*/0, /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); auto FooCpp = getVirtualTestFilePath("foo.cpp"); @@ -503,17 +499,22 @@ FS.Files[FooCpp] = SourceContents; FS.ExpectedFile = FooCpp; + // Use default completion options. + clangd::CodeCompleteOptions CCOpts; + // No need to sync reparses, because requests are processed on the calling // thread. FS.Tag = "123"; Server.addDocument(FooCpp, SourceContents); - EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).get().Tag, FS.Tag); + EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag, + FS.Tag); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); FS.Tag = "321"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); - EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).get().Tag, FS.Tag); + EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag, + FS.Tag); } // Only enable this test on Unix @@ -531,7 +532,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, /*AsyncThreadsCount=*/0, /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); // Just a random gcc version string @@ -582,7 +582,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, /*AsyncThreadsCount=*/0, /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); // No need to sync reparses, because reparses are performed on the calling // thread to true. @@ -651,7 +650,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); auto FooCpp = getVirtualTestFilePath("foo.cpp"); @@ -677,9 +675,11 @@ // other async operations). Server.addDocument(FooCpp, SourceContents); + // Use default completion options. + clangd::CodeCompleteOptions CCOpts; { auto CodeCompletionResults1 = - Server.codeComplete(FooCpp, CompletePos, None).get().Value; + Server.codeComplete(FooCpp, CompletePos, CCOpts, None).get().Value; EXPECT_TRUE(ContainsItem(CodeCompletionResults1, "aba")); EXPECT_FALSE(ContainsItem(CodeCompletionResults1, "cbc")); } @@ -687,7 +687,7 @@ { auto CodeCompletionResultsOverriden = Server - .codeComplete(FooCpp, CompletePos, + .codeComplete(FooCpp, CompletePos, CCOpts, StringRef(OverridenSourceContents)) .get() .Value; @@ -697,7 +697,7 @@ { auto CodeCompletionResults2 = - Server.codeComplete(FooCpp, CompletePos, None).get().Value; + Server.codeComplete(FooCpp, CompletePos, CCOpts, None).get().Value; EXPECT_TRUE(ContainsItem(CodeCompletionResults2, "aba")); EXPECT_FALSE(ContainsItem(CodeCompletionResults2, "cbc")); } @@ -708,10 +708,8 @@ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true); CDB.ExtraClangFlags.push_back("-xc++"); ErrorCheckingDiagConsumer DiagConsumer; - clangd::CodeCompleteOptions Opts; - Opts.Limit = 2; ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), - /*StorePreamblesInMemory=*/true, Opts, + /*StorePreamblesInMemory=*/true, EmptyLogger::getInstance()); auto FooCpp = getVirtualTestFilePath("foo.cpp"); @@ -728,9 +726,11 @@ "complete"); Server.addDocument(FooCpp, Completion.Text); + clangd::CodeCompleteOptions Opts; + Opts.Limit = 2; /// For after-dot completion we must always get consistent results. auto Results = Server - .codeComplete(FooCpp, Completion.MarkerPos, + .codeComplete(FooCpp, Completion.MarkerPos, Opts, StringRef(Completion.Text)) .get() .Value; @@ -807,10 +807,10 @@ StringWithPos MemberCompletion = parseTextMarker(MemberCompletionSourceTemplate, "complete"); + ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), + /*StorePreamblesInMemory=*/true, + EmptyLogger::getInstance()); auto TestWithOpts = [&](clangd::CodeCompleteOptions Opts) { - ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), - /*StorePreamblesInMemory=*/true, Opts, - EmptyLogger::getInstance()); // No need to sync reparses here as there are no asserts on diagnostics (or // other async operations). Server.addDocument(FooCpp, GlobalCompletion.Text); @@ -822,7 +822,7 @@ /// For after-dot completion we must always get consistent results. { auto Results = Server - .codeComplete(FooCpp, MemberCompletion.MarkerPos, + .codeComplete(FooCpp, MemberCompletion.MarkerPos, Opts, StringRef(MemberCompletion.Text)) .get() .Value; @@ -858,7 +858,7 @@ // Global completion differs based on the Opts that were passed. { auto Results = Server - .codeComplete(FooCpp, GlobalCompletion.MarkerPos, + .codeComplete(FooCpp, GlobalCompletion.MarkerPos, Opts, StringRef(GlobalCompletion.Text)) .get() .Value; @@ -895,13 +895,13 @@ }; clangd::CodeCompleteOptions CCOpts; - for (bool IncludeMacros : {true, false}){ + for (bool IncludeMacros : {true, false}) { CCOpts.IncludeMacros = IncludeMacros; - for (bool IncludeGlobals : {true, false}){ + for (bool IncludeGlobals : {true, false}) { CCOpts.IncludeGlobals = IncludeGlobals; - for (bool IncludeBriefComments : {true, false}){ + for (bool IncludeBriefComments : {true, false}) { CCOpts.IncludeBriefComments = IncludeBriefComments; - for (bool EnableSnippets : {true, false}){ + for (bool EnableSnippets : {true, false}) { CCOpts.EnableSnippets = EnableSnippets; for (bool IncludeCodePatterns : {true, false}) { CCOpts.IncludeCodePatterns = IncludeCodePatterns; @@ -1015,7 +1015,6 @@ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true); ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); // Prepare some random distributions for the test. @@ -1109,7 +1108,10 @@ // requests as opposed to AddDocument/RemoveDocument, which are implicitly // cancelled by any subsequent AddDocument/RemoveDocument request to the // same file. - Server.codeComplete(FilePaths[FileIndex], Pos).wait(); + Server + .codeComplete(FilePaths[FileIndex], Pos, + clangd::CodeCompleteOptions()) + .wait(); }; auto FindDefinitionsRequest = [&]() { @@ -1176,7 +1178,6 @@ ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); auto SourceContents = R"cpp( @@ -1303,7 +1304,6 @@ MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true); ClangdServer Server(CDB, DiagConsumer, FS, 4, /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); Server.addDocument(FooCpp, SourceContentsWithErrors); StartSecondReparse.wait();