96 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H11 12#include "llvm/ADT/StringRef.h"13#include <condition_variable>14#include <llvm/Support/Error.h>15#include <llvm/Support/JSON.h>16#include <memory>17#include <mutex>18#include <optional>19#include <vector>20 21namespace clang {22namespace clangd {23class Transport;24 25// A client library for talking to ClangdLSPServer in tests.26// Manages serialization of messages, pairing requests/repsonses, and implements27// the Transport abstraction.28class LSPClient {29 class TransportImpl;30 std::unique_ptr<TransportImpl> T;31 32public:33 // Represents the result of an LSP call: a promise for a result or error.34 class CallResult {35 public:36 ~CallResult();37 // Blocks up to 60 seconds for the result to be ready.38 // Records a test failure if there was no reply.39 llvm::Expected<llvm::json::Value> take();40 // Like take(), but records a test failure if the result was an error.41 llvm::json::Value takeValue();42 43 private:44 // Should be called once to provide the value.45 void set(llvm::Expected<llvm::json::Value> V);46 47 std::optional<llvm::Expected<llvm::json::Value>> Value;48 std::mutex Mu;49 std::condition_variable CV;50 51 friend TransportImpl; // Calls set().52 };53 54 LSPClient();55 ~LSPClient();56 LSPClient(LSPClient &&) = delete;57 LSPClient &operator=(LSPClient &&) = delete;58 59 // Enqueue an LSP method call, returns a promise for the reply. Threadsafe.60 CallResult &call(llvm::StringRef Method, llvm::json::Value Params);61 // Normally, any call from the server to the client will be marked as a test62 // failure. Use this to allow a call to pass through, use takeCallParams() to63 // retrieve it.64 void expectServerCall(llvm::StringRef Method);65 // Enqueue an LSP notification. Threadsafe.66 void notify(llvm::StringRef Method, llvm::json::Value Params);67 // Returns matching notifications since the last call to takeNotifications.68 std::vector<llvm::json::Value> takeNotifications(llvm::StringRef Method);69 // Returns matching parameters since the last call to takeCallParams.70 std::vector<llvm::json::Value> takeCallParams(llvm::StringRef Method);71 // The transport is shut down after all pending messages are sent.72 void stop();73 74 // Shorthand for common LSP methods. Relative paths are passed to testPath().75 static llvm::json::Value uri(llvm::StringRef Path);76 static llvm::json::Value documentID(llvm::StringRef Path);77 void didOpen(llvm::StringRef Path, llvm::StringRef Content);78 void didChange(llvm::StringRef Path, llvm::StringRef Content);79 void didClose(llvm::StringRef Path);80 // Blocks until the server is idle (using the 'sync' protocol extension).81 void sync();82 // sync()s to ensure pending diagnostics arrive, and returns the newest set.83 std::optional<std::vector<llvm::json::Value>>84 diagnostics(llvm::StringRef Path);85 86 // Get the transport used to connect this client to a ClangdLSPServer.87 Transport &transport();88 89private:90};91 92} // namespace clangd93} // namespace clang94 95#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H96