blob: aa2a044f231d8a69d1f168209e9d56436c33f236 [file] [log] [blame]
Ilya Biryukovcd5eb002018-02-12 11:37:28 +00001//===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- C++-*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9#include "SyncAPI.h"
10
11namespace clang {
12namespace clangd {
13
Ilya Biryukovbec5df22018-03-14 17:08:41 +000014void runAddDocument(ClangdServer &Server, PathRef File, StringRef Contents,
Ilya Biryukovb10ef472018-06-13 09:20:41 +000015 WantDiagnostics WantDiags) {
16 Server.addDocument(File, Contents, WantDiags);
Sam McCall7363a2f2018-03-05 17:28:54 +000017 if (!Server.blockUntilIdleForTest())
18 llvm_unreachable("not idle after addDocument");
19}
20
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000021namespace {
22/// A helper that waits for async callbacks to fire and exposes their result in
23/// the output variable. Intended to be used in the following way:
24/// T Result;
25/// someAsyncFunc(Param1, Param2, /*Callback=*/capture(Result));
26template <typename T> struct CaptureProxy {
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000027 CaptureProxy(llvm::Optional<T> &Target) : Target(&Target) {
28 assert(!Target.hasValue());
29 }
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000030
31 CaptureProxy(const CaptureProxy &) = delete;
32 CaptureProxy &operator=(const CaptureProxy &) = delete;
33 // We need move ctor to return a value from the 'capture' helper.
34 CaptureProxy(CaptureProxy &&Other) : Target(Other.Target) {
35 Other.Target = nullptr;
36 }
37 CaptureProxy &operator=(CaptureProxy &&) = delete;
38
39 operator UniqueFunction<void(T)>() && {
40 assert(!Future.valid() && "conversion to callback called multiple times");
41 Future = Promise.get_future();
Sam McCall091557d2018-02-23 07:54:17 +000042 return Bind(
Ilya Biryukov40bf17c2018-02-15 15:41:49 +000043 [](std::promise<std::shared_ptr<T>> Promise, T Value) {
44 Promise.set_value(std::make_shared<T>(std::move(Value)));
45 },
46 std::move(Promise));
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000047 }
48
49 ~CaptureProxy() {
50 if (!Target)
51 return;
52 assert(Future.valid() && "conversion to callback was not called");
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000053 assert(!Target->hasValue());
Ilya Biryukov40bf17c2018-02-15 15:41:49 +000054 Target->emplace(std::move(*Future.get()));
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000055 }
56
57private:
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000058 llvm::Optional<T> *Target;
Ilya Biryukov40bf17c2018-02-15 15:41:49 +000059 // Using shared_ptr to workaround compilation errors with MSVC.
60 // MSVC only allows default-construcitble and copyable objects as future<>
61 // arguments.
62 std::promise<std::shared_ptr<T>> Promise;
63 std::future<std::shared_ptr<T>> Future;
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000064};
65
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000066template <typename T> CaptureProxy<T> capture(llvm::Optional<T> &Target) {
Ilya Biryukovcd5eb002018-02-12 11:37:28 +000067 return CaptureProxy<T>(Target);
68}
69} // namespace
70
Sam McCalla7bb0cc2018-03-12 23:22:35 +000071llvm::Expected<CompletionList>
72runCodeComplete(ClangdServer &Server, PathRef File, Position Pos,
73 clangd::CodeCompleteOptions Opts) {
74 llvm::Optional<llvm::Expected<CompletionList>> Result;
Sam McCalldb3ea4c2018-02-27 17:15:50 +000075 Server.codeComplete(File, Pos, Opts, capture(Result));
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000076 return std::move(*Result);
77}
78
Sam McCalla7bb0cc2018-03-12 23:22:35 +000079llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server,
80 PathRef File, Position Pos) {
81 llvm::Optional<llvm::Expected<SignatureHelp>> Result;
Sam McCalldb3ea4c2018-02-27 17:15:50 +000082 Server.signatureHelp(File, Pos, capture(Result));
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000083 return std::move(*Result);
84}
85
Sam McCalla7bb0cc2018-03-12 23:22:35 +000086llvm::Expected<std::vector<Location>>
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000087runFindDefinitions(ClangdServer &Server, PathRef File, Position Pos) {
Sam McCalla7bb0cc2018-03-12 23:22:35 +000088 llvm::Optional<llvm::Expected<std::vector<Location>>> Result;
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000089 Server.findDefinitions(File, Pos, capture(Result));
90 return std::move(*Result);
91}
92
Sam McCalla7bb0cc2018-03-12 23:22:35 +000093llvm::Expected<std::vector<DocumentHighlight>>
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000094runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos) {
Sam McCalla7bb0cc2018-03-12 23:22:35 +000095 llvm::Optional<llvm::Expected<std::vector<DocumentHighlight>>> Result;
Ilya Biryukov2c5e8e82018-02-15 13:15:47 +000096 Server.findDocumentHighlights(File, Pos, capture(Result));
97 return std::move(*Result);
98}
99
100llvm::Expected<std::vector<tooling::Replacement>>
101runRename(ClangdServer &Server, PathRef File, Position Pos, StringRef NewName) {
102 llvm::Optional<llvm::Expected<std::vector<tooling::Replacement>>> Result;
103 Server.rename(File, Pos, NewName, capture(Result));
104 return std::move(*Result);
105}
106
107std::string runDumpAST(ClangdServer &Server, PathRef File) {
108 llvm::Optional<std::string> Result;
109 Server.dumpAST(File, capture(Result));
110 return std::move(*Result);
Ilya Biryukovcd5eb002018-02-12 11:37:28 +0000111}
112
Marc-Andre Laperleb387b6e2018-04-23 20:00:52 +0000113llvm::Expected<std::vector<SymbolInformation>>
114runWorkspaceSymbols(ClangdServer &Server, StringRef Query, int Limit) {
115 llvm::Optional<llvm::Expected<std::vector<SymbolInformation>>> Result;
116 Server.workspaceSymbols(Query, Limit, capture(Result));
117 return std::move(*Result);
118}
119
Ilya Biryukovcd5eb002018-02-12 11:37:28 +0000120} // namespace clangd
121} // namespace clang