Mercurial > hg > CbC > CbC_llvm
view clang-tools-extra/clangd/unittests/SyncAPI.cpp @ 221:79ff65ed7e25
LLVM12 Original
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 15 Jun 2021 19:15:29 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line source
//===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "SyncAPI.h" #include "index/Index.h" namespace clang { namespace clangd { void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, llvm::StringRef Version, WantDiagnostics WantDiags, bool ForceRebuild) { Server.addDocument(File, Contents, Version, WantDiags, ForceRebuild); if (!Server.blockUntilIdleForTest()) llvm_unreachable("not idle after addDocument"); } 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(llvm::Optional<T> &Target) : Target(&Target) { assert(!Target.hasValue()); } 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 llvm::unique_function<void(T)>() && { assert(!Future.valid() && "conversion to callback called multiple times"); Future = Promise.get_future(); return [Promise = std::move(Promise)](T Value) mutable { Promise.set_value(std::make_shared<T>(std::move(Value))); }; } ~CaptureProxy() { if (!Target) return; assert(Future.valid() && "conversion to callback was not called"); assert(!Target->hasValue()); Target->emplace(std::move(*Future.get())); } private: llvm::Optional<T> *Target; // Using shared_ptr to workaround compilation errors with MSVC. // MSVC only allows default-constructible and copyable objects as future<> // arguments. std::promise<std::shared_ptr<T>> Promise; std::future<std::shared_ptr<T>> Future; }; template <typename T> CaptureProxy<T> capture(llvm::Optional<T> &Target) { return CaptureProxy<T>(Target); } } // namespace llvm::Expected<CodeCompleteResult> runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, clangd::CodeCompleteOptions Opts) { llvm::Optional<llvm::Expected<CodeCompleteResult>> Result; Server.codeComplete(File, Pos, Opts, capture(Result)); return std::move(*Result); } llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos) { llvm::Optional<llvm::Expected<SignatureHelp>> Result; Server.signatureHelp(File, Pos, capture(Result)); return std::move(*Result); } llvm::Expected<std::vector<LocatedSymbol>> runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos) { llvm::Optional<llvm::Expected<std::vector<LocatedSymbol>>> Result; Server.locateSymbolAt(File, Pos, capture(Result)); return std::move(*Result); } llvm::Expected<std::vector<DocumentHighlight>> runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos) { llvm::Optional<llvm::Expected<std::vector<DocumentHighlight>>> Result; Server.findDocumentHighlights(File, Pos, capture(Result)); return std::move(*Result); } llvm::Expected<RenameResult> runRename(ClangdServer &Server, PathRef File, Position Pos, llvm::StringRef NewName, const RenameOptions &RenameOpts) { llvm::Optional<llvm::Expected<RenameResult>> Result; Server.rename(File, Pos, NewName, RenameOpts, capture(Result)); return std::move(*Result); } llvm::Expected<RenameResult> runPrepareRename(ClangdServer &Server, PathRef File, Position Pos, llvm::Optional<std::string> NewName, const RenameOptions &RenameOpts) { llvm::Optional<llvm::Expected<RenameResult>> Result; Server.prepareRename(File, Pos, NewName, RenameOpts, capture(Result)); return std::move(*Result); } llvm::Expected<tooling::Replacements> runFormatFile(ClangdServer &Server, PathRef File, llvm::Optional<Range> Rng) { llvm::Optional<llvm::Expected<tooling::Replacements>> Result; Server.formatFile(File, Rng, capture(Result)); return std::move(*Result); } SymbolSlab runFuzzyFind(const SymbolIndex &Index, llvm::StringRef Query) { FuzzyFindRequest Req; Req.Query = std::string(Query); Req.AnyScope = true; return runFuzzyFind(Index, Req); } SymbolSlab runFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req) { SymbolSlab::Builder Builder; Index.fuzzyFind(Req, [&](const Symbol &Sym) { Builder.insert(Sym); }); return std::move(Builder).build(); } RefSlab getRefs(const SymbolIndex &Index, SymbolID ID) { RefsRequest Req; Req.IDs = {ID}; RefSlab::Builder Slab; Index.refs(Req, [&](const Ref &S) { Slab.insert(ID, S); }); return std::move(Slab).build(); } llvm::Expected<std::vector<SelectionRange>> runSemanticRanges(ClangdServer &Server, PathRef File, const std::vector<Position> &Pos) { llvm::Optional<llvm::Expected<std::vector<SelectionRange>>> Result; Server.semanticRanges(File, Pos, capture(Result)); return std::move(*Result); } llvm::Expected<llvm::Optional<clangd::Path>> runSwitchHeaderSource(ClangdServer &Server, PathRef File) { llvm::Optional<llvm::Expected<llvm::Optional<clangd::Path>>> Result; Server.switchSourceHeader(File, capture(Result)); return std::move(*Result); } llvm::Error runCustomAction(ClangdServer &Server, PathRef File, llvm::function_ref<void(InputsAndAST)> Action) { llvm::Error Result = llvm::Error::success(); Notification Done; Server.customAction(File, "Custom", [&](llvm::Expected<InputsAndAST> AST) { if (!AST) Result = AST.takeError(); else Action(*AST); Done.notify(); }); Done.wait(); return Result; } } // namespace clangd } // namespace clang