blob: 2c5c544c9854907ed349b640fb6efd3c1de04df4 [file] [log] [blame]
//===--- 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