1 //===-- LSPClient.h - Helper for ClangdLSPServer tests ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H 11 12 #include <llvm/ADT/Optional.h> 13 #include <llvm/Support/Error.h> 14 #include <llvm/Support/JSON.h> 15 #include <condition_variable> 16 #include <deque> 17 #include <mutex> 18 19 namespace clang { 20 namespace clangd { 21 class Transport; 22 23 // A client library for talking to ClangdLSPServer in tests. 24 // Manages serialization of messages, pairing requests/repsonses, and implements 25 // the Transport abstraction. 26 class LSPClient { 27 class TransportImpl; 28 std::unique_ptr<TransportImpl> T; 29 30 public: 31 // Represents the result of an LSP call: a promise for a result or error. 32 class CallResult { 33 public: 34 ~CallResult(); 35 // Blocks up to 10 seconds for the result to be ready. 36 // Records a test failure if there was no reply. 37 llvm::Expected<llvm::json::Value> take(); 38 // Like take(), but records a test failure if the result was an error. 39 llvm::json::Value takeValue(); 40 41 private: 42 // Should be called once to provide the value. 43 void set(llvm::Expected<llvm::json::Value> V); 44 45 llvm::Optional<llvm::Expected<llvm::json::Value>> Value; 46 std::mutex Mu; 47 std::condition_variable CV; 48 49 friend TransportImpl; // Calls set(). 50 }; 51 52 LSPClient(); 53 ~LSPClient(); 54 LSPClient(LSPClient &&) = delete; 55 LSPClient &operator=(LSPClient &&) = delete; 56 57 // Enqueue an LSP method call, returns a promise for the reply. Threadsafe. 58 CallResult &call(llvm::StringRef Method, llvm::json::Value Params); 59 // Enqueue an LSP notification. Threadsafe. 60 void notify(llvm::StringRef Method, llvm::json::Value Params); 61 // Returns matching notifications since the last call to takeNotifications. 62 std::vector<llvm::json::Value> takeNotifications(llvm::StringRef Method); 63 // The transport is shut down after all pending messages are sent. 64 void stop(); 65 66 // Shorthand for common LSP methods. Relative paths are passed to testPath(). 67 static llvm::json::Value uri(llvm::StringRef Path); 68 static llvm::json::Value documentID(llvm::StringRef Path); 69 void didOpen(llvm::StringRef Path, llvm::StringRef Content); 70 void didChange(llvm::StringRef Path, llvm::StringRef Content); 71 void didClose(llvm::StringRef Path); 72 // Blocks until the server is idle (using the 'sync' protocol extension). 73 void sync(); 74 // sync()s to ensure pending diagnostics arrive, and returns the newest set. 75 llvm::Optional<std::vector<llvm::json::Value>> 76 diagnostics(llvm::StringRef Path); 77 78 // Get the transport used to connect this client to a ClangdLSPServer. 79 Transport &transport(); 80 81 private: 82 }; 83 84 } // namespace clangd 85 } // namespace clang 86 87 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H 88