Index: clang-tools-extra/trunk/clangd/ClangdServer.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -234,6 +234,9 @@ /// and AST and rebuild them from scratch. std::future forceReparse(PathRef File); + /// DEPRECATED. Please use a callback-based version, this API is deprecated + /// and will soon be removed. + /// /// Run code completion for \p File at \p Pos. /// /// Request is processed asynchronously. You can use the returned future to @@ -253,6 +256,14 @@ llvm::Optional OverridenContents = llvm::None, IntrusiveRefCntPtr *UsedFS = nullptr); + /// A version of `codeComplete` that runs \p Callback on the processing thread + /// when codeComplete results become available. + void codeComplete( + UniqueFunction>)> Callback, + PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None, + IntrusiveRefCntPtr *UsedFS = nullptr); + /// Provide signature help for \p File at \p Pos. If \p OverridenContents is /// not None, they will used only for signature help, i.e. no diagnostics /// update will be scheduled and a draft for \p File will not be updated. If Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -198,6 +198,28 @@ ClangdServer::codeComplete(PathRef File, Position Pos, llvm::Optional OverridenContents, IntrusiveRefCntPtr *UsedFS) { + using ResultType = Tagged>; + + std::promise ResultPromise; + + auto Callback = [](std::promise ResultPromise, + ResultType Result) -> void { + ResultPromise.set_value(std::move(Result)); + }; + + std::future ResultFuture = ResultPromise.get_future(); + codeComplete(BindWithForward(Callback, std::move(ResultPromise)), File, Pos, + OverridenContents, UsedFS); + return ResultFuture; +} + +void ClangdServer::codeComplete( + UniqueFunction>)> Callback, + PathRef File, Position Pos, llvm::Optional OverridenContents, + IntrusiveRefCntPtr *UsedFS) { + using CallbackType = + UniqueFunction>)>; + std::string Contents; if (OverridenContents) { Contents = *OverridenContents; @@ -216,9 +238,6 @@ std::shared_ptr Resources = Units.getFile(File); assert(Resources && "Calling completion on non-added file"); - using PackagedTask = - std::packaged_task>()>; - // Remember the current Preamble and use it when async task starts executing. // At the point when async task starts executing, we may have a different // Preamble in Resources. However, we assume the Preamble that we obtain here @@ -226,26 +245,25 @@ std::shared_ptr Preamble = Resources->getPossiblyStalePreamble(); // A task that will be run asynchronously. - PackagedTask Task([=]() mutable { // 'mutable' to reassign Preamble variable. - if (!Preamble) { - // Maybe we built some preamble before processing this request. - Preamble = Resources->getPossiblyStalePreamble(); - } - // FIXME(ibiryukov): even if Preamble is non-null, we may want to check - // both the old and the new version in case only one of them matches. + auto Task = + // 'mutable' to reassign Preamble variable. + [=](CallbackType Callback) mutable { + if (!Preamble) { + // Maybe we built some preamble before processing this request. + Preamble = Resources->getPossiblyStalePreamble(); + } + // FIXME(ibiryukov): even if Preamble is non-null, we may want to check + // both the old and the new version in case only one of them matches. + + std::vector Result = clangd::codeComplete( + File, Resources->getCompileCommand(), + Preamble ? &Preamble->Preamble : nullptr, Contents, Pos, + TaggedFS.Value, PCHs, CodeCompleteOpts, Logger); - std::vector Result = clangd::codeComplete( - File, Resources->getCompileCommand(), - Preamble ? &Preamble->Preamble : nullptr, Contents, Pos, TaggedFS.Value, - PCHs, CodeCompleteOpts, Logger); - return make_tagged(std::move(Result), std::move(TaggedFS.Tag)); - }); + Callback(make_tagged(std::move(Result), std::move(TaggedFS.Tag))); + }; - auto Future = Task.get_future(); - // FIXME(ibiryukov): to reduce overhead for wrapping the same callable - // multiple times, ClangdScheduler should return future<> itself. - WorkScheduler.addToFront([](PackagedTask Task) { Task(); }, std::move(Task)); - return Future; + WorkScheduler.addToFront(std::move(Task), std::move(Callback)); } Tagged