ilya-biryukov created this revision. Herald added a subscriber: klimek. Previously, completion options were set per ClangdServer instance. It will allow to change completion preferences during the lifetime of a single ClangdServer instance.
Also rewrote ClangdCompletionTest.CompletionOptions to reuse single ClangdServer instance, the test now runs 2x faster on my machine. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40654 Files: clangd/ClangdLSPServer.cpp clangd/ClangdLSPServer.h clangd/ClangdServer.cpp clangd/ClangdServer.h unittests/clangd/ClangdTests.cpp
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,25 +492,29 @@ ClangdServer Server(CDB, DiagConsumer, FS, /*AsyncThreadsCount=*/0, /*StorePreamblesInMemory=*/true, - clangd::CodeCompleteOptions(), EmptyLogger::getInstance()); auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; 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,17 +675,19 @@ // 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")); } { 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(); 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<StringRef> ResourceDir = llvm::None); @@ -254,13 +253,15 @@ /// while returned future is not yet ready. std::future<Tagged<CompletionList>> codeComplete(PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional<StringRef> OverridenContents = llvm::None, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr); /// A version of `codeComplete` that runs \p Callback on the processing thread /// when codeComplete results become available. void codeComplete(UniqueFunction<void(Tagged<CompletionList>)> Callback, PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional<StringRef> OverridenContents = llvm::None, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr); @@ -327,7 +328,6 @@ llvm::Optional<std::string> RootPath; std::shared_ptr<PCHContainerOperations> 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<StringRef> ResourceDir) : Logger(Logger), CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider), ResourceDir(ResourceDir ? ResourceDir->str() : getStandardResourceDir()), PCHs(std::make_shared<PCHContainerOperations>()), 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<Tagged<CompletionList>> ClangdServer::codeComplete(PathRef File, Position Pos, + const clangd::CodeCompleteOptions &Opts, llvm::Optional<StringRef> OverridenContents, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) { using ResultType = Tagged<CompletionList>; @@ -239,13 +238,14 @@ std::future<ResultType> ResultFuture = ResultPromise.get_future(); codeComplete(BindWithForward(Callback, std::move(ResultPromise)), File, Pos, - OverridenContents, UsedFS); + Opts, OverridenContents, UsedFS); return ResultFuture; } void ClangdServer::codeComplete( UniqueFunction<void(Tagged<CompletionList>)> Callback, PathRef File, - Position Pos, llvm::Optional<StringRef> OverridenContents, + Position Pos, const clangd::CodeCompleteOptions &Opts, + llvm::Optional<StringRef> OverridenContents, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) { using CallbackType = UniqueFunction<void(Tagged<CompletionList>)>; @@ -274,6 +274,7 @@ std::shared_ptr<const PreambleData> Preamble = Resources->getPossiblyStalePreamble(); // A task that will be run asynchronously. + auto CodeCompleteOpts = Opts; auto Task = // 'mutable' to reassign Preamble variable. [=](CallbackType Callback) mutable { 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<StringRef> ResourceDir, llvm::Optional<Path> 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");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits