diff options
Diffstat (limited to 'clang-tools-extra/unittests/clangd/SyncAPI.cpp')
-rw-r--r-- | clang-tools-extra/unittests/clangd/SyncAPI.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/clang-tools-extra/unittests/clangd/SyncAPI.cpp b/clang-tools-extra/unittests/clangd/SyncAPI.cpp new file mode 100644 index 00000000000..2c5c544c985 --- /dev/null +++ b/clang-tools-extra/unittests/clangd/SyncAPI.cpp @@ -0,0 +1,66 @@ +//===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +#include "SyncAPI.h" + +namespace clang { +namespace clangd { + +namespace { +/// A helper that waits for async callbacks to fire and exposes their result in +/// the output variable. Intended to be used in the following way: +/// T Result; +/// someAsyncFunc(Param1, Param2, /*Callback=*/capture(Result)); +template <typename T> struct CaptureProxy { + CaptureProxy(T &Target) : Target(&Target) {} + + CaptureProxy(const CaptureProxy &) = delete; + CaptureProxy &operator=(const CaptureProxy &) = delete; + // We need move ctor to return a value from the 'capture' helper. + CaptureProxy(CaptureProxy &&Other) : Target(Other.Target) { + Other.Target = nullptr; + } + CaptureProxy &operator=(CaptureProxy &&) = delete; + + operator UniqueFunction<void(T)>() && { + assert(!Future.valid() && "conversion to callback called multiple times"); + Future = Promise.get_future(); + return BindWithForward([](std::promise<T> Promise, + T Value) { Promise.set_value(std::move(Value)); }, + std::move(Promise)); + } + + ~CaptureProxy() { + if (!Target) + return; + assert(Future.valid() && "conversion to callback was not called"); + *Target = Future.get(); + } + +private: + T *Target; + std::promise<T> Promise; + std::future<T> Future; +}; + +template <typename T> CaptureProxy<T> capture(T &Target) { + return CaptureProxy<T>(Target); +} +} // namespace + +Tagged<CompletionList> +runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, + clangd::CodeCompleteOptions Opts, + llvm::Optional<StringRef> OverridenContents) { + Tagged<CompletionList> Result; + Server.codeComplete(File, Pos, Opts, capture(Result), OverridenContents); + return Result; +} + +} // namespace clangd +} // namespace clang |