clang-tools  9.0.0
SyncAPI.cpp
Go to the documentation of this file.
1 //===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- 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 #include "SyncAPI.h"
10 #include "index/Index.h"
11 
12 namespace clang {
13 namespace clangd {
14 
16  llvm::StringRef Contents, WantDiagnostics WantDiags) {
17  Server.addDocument(File, Contents, WantDiags);
18  if (!Server.blockUntilIdleForTest())
19  llvm_unreachable("not idle after addDocument");
20 }
21 
22 namespace {
23 /// A helper that waits for async callbacks to fire and exposes their result in
24 /// the output variable. Intended to be used in the following way:
25 /// T Result;
26 /// someAsyncFunc(Param1, Param2, /*Callback=*/capture(Result));
27 template <typename T> struct CaptureProxy {
28  CaptureProxy(llvm::Optional<T> &Target) : Target(&Target) {
29  assert(!Target.hasValue());
30  }
31 
32  CaptureProxy(const CaptureProxy &) = delete;
33  CaptureProxy &operator=(const CaptureProxy &) = delete;
34  // We need move ctor to return a value from the 'capture' helper.
35  CaptureProxy(CaptureProxy &&Other) : Target(Other.Target) {
36  Other.Target = nullptr;
37  }
38  CaptureProxy &operator=(CaptureProxy &&) = delete;
39 
40  operator llvm::unique_function<void(T)>() && {
41  assert(!Future.valid() && "conversion to callback called multiple times");
42  Future = Promise.get_future();
43  return Bind(
44  [](std::promise<std::shared_ptr<T>> Promise, T Value) {
45  Promise.set_value(std::make_shared<T>(std::move(Value)));
46  },
47  std::move(Promise));
48  }
49 
50  ~CaptureProxy() {
51  if (!Target)
52  return;
53  assert(Future.valid() && "conversion to callback was not called");
54  assert(!Target->hasValue());
55  Target->emplace(std::move(*Future.get()));
56  }
57 
58 private:
59  llvm::Optional<T> *Target;
60  // Using shared_ptr to workaround compilation errors with MSVC.
61  // MSVC only allows default-construcitble and copyable objects as future<>
62  // arguments.
63  std::promise<std::shared_ptr<T>> Promise;
64  std::future<std::shared_ptr<T>> Future;
65 };
66 
67 template <typename T> CaptureProxy<T> capture(llvm::Optional<T> &Target) {
68  return CaptureProxy<T>(Target);
69 }
70 } // namespace
71 
72 llvm::Expected<CodeCompleteResult>
75  llvm::Optional<llvm::Expected<CodeCompleteResult>> Result;
76  Server.codeComplete(File, Pos, Opts, capture(Result));
77  return std::move(*Result);
78 }
79 
80 llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server,
81  PathRef File, Position Pos) {
82  llvm::Optional<llvm::Expected<SignatureHelp>> Result;
83  Server.signatureHelp(File, Pos, capture(Result));
84  return std::move(*Result);
85 }
86 
87 llvm::Expected<std::vector<LocatedSymbol>>
89  llvm::Optional<llvm::Expected<std::vector<LocatedSymbol>>> Result;
90  Server.locateSymbolAt(File, Pos, capture(Result));
91  return std::move(*Result);
92 }
93 
94 llvm::Expected<std::vector<DocumentHighlight>>
96  llvm::Optional<llvm::Expected<std::vector<DocumentHighlight>>> Result;
97  Server.findDocumentHighlights(File, Pos, capture(Result));
98  return std::move(*Result);
99 }
100 
101 llvm::Expected<std::vector<TextEdit>> runRename(ClangdServer &Server,
102  PathRef File, Position Pos,
103  llvm::StringRef NewName) {
104  llvm::Optional<llvm::Expected<std::vector<TextEdit>>> Result;
105  Server.rename(File, Pos, NewName, /*WantFormat=*/true, capture(Result));
106  return std::move(*Result);
107 }
108 
110  llvm::Optional<std::string> Result;
111  Server.dumpAST(File, capture(Result));
112  return std::move(*Result);
113 }
114 
115 llvm::Expected<std::vector<SymbolInformation>>
116 runWorkspaceSymbols(ClangdServer &Server, llvm::StringRef Query, int Limit) {
117  llvm::Optional<llvm::Expected<std::vector<SymbolInformation>>> Result;
118  Server.workspaceSymbols(Query, Limit, capture(Result));
119  return std::move(*Result);
120 }
121 
122 llvm::Expected<std::vector<DocumentSymbol>>
124  llvm::Optional<llvm::Expected<std::vector<DocumentSymbol>>> Result;
125  Server.documentSymbols(File, capture(Result));
126  return std::move(*Result);
127 }
128 
129 SymbolSlab runFuzzyFind(const SymbolIndex &Index, llvm::StringRef Query) {
130  FuzzyFindRequest Req;
131  Req.Query = Query;
132  Req.AnyScope = true;
133  return runFuzzyFind(Index, Req);
134 }
135 
138  Index.fuzzyFind(Req, [&](const Symbol &Sym) { Builder.insert(Sym); });
139  return std::move(Builder).build();
140 }
141 
143  RefsRequest Req;
144  Req.IDs = {ID};
145  RefSlab::Builder Slab;
146  Index.refs(Req, [&](const Ref &S) { Slab.insert(ID, S); });
147  return std::move(Slab).build();
148 }
149 
150 } // namespace clangd
151 } // namespace clang
int Limit
WantDiagnostics
Determines whether diagnostics should be generated for a file snapshot.
Definition: TUScheduler.h:43
void rename(PathRef File, Position Pos, llvm::StringRef NewName, bool WantFormat, Callback< std::vector< TextEdit >> CB)
Rename all occurrences of the symbol at the Pos in File to NewName.
An immutable symbol container that stores a set of symbols.
Definition: Symbol.h:177
llvm::DenseSet< SymbolID > IDs
Definition: Index.h:68
void addDocument(PathRef File, StringRef Contents, WantDiagnostics WD=WantDiagnostics::Auto)
Add a File to the list of tracked C++ files or update the contents if File is already tracked...
bool AnyScope
If set to true, allow symbols from any scope.
Definition: Index.h:39
llvm::StringRef Contents
void codeComplete(PathRef File, Position Pos, const clangd::CodeCompleteOptions &Opts, Callback< CodeCompleteResult > CB)
Run code completion for File at Pos.
llvm::Expected< CodeCompleteResult > runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, clangd::CodeCompleteOptions Opts)
Definition: SyncAPI.cpp:73
std::string runDumpAST(ClangdServer &Server, PathRef File)
Definition: SyncAPI.cpp:109
An efficient structure of storing large set of symbol references in memory.
Definition: Ref.h:69
llvm::Expected< SignatureHelp > runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:80
llvm::Expected< std::vector< DocumentSymbol > > runDocumentSymbols(ClangdServer &Server, PathRef File)
Definition: SyncAPI.cpp:123
llvm::Expected< std::vector< LocatedSymbol > > runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:88
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
Definition: Index.h:85
Represents a symbol occurrence in the source file.
Definition: Ref.h:52
virtual bool fuzzyFind(const FuzzyFindRequest &Req, llvm::function_ref< void(const Symbol &)> Callback) const =0
Matches symbols in the index fuzzily and applies Callback on each matched symbol before returning...
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
Definition: Symbol.cpp:50
LLVM_NODISCARD bool blockUntilIdleForTest(llvm::Optional< double > TimeoutSeconds=10)
void findDocumentHighlights(PathRef File, Position Pos, Callback< std::vector< DocumentHighlight >> CB)
Get document highlights for a given position.
SymbolSlab::Builder is a mutable container that can &#39;freeze&#39; to SymbolSlab.
Definition: Symbol.h:199
ForwardBinder< Func, Args... > Bind(Func F, Args &&... As)
Creates an object that stores a callable (F) and first arguments to the callable (As) and allows to c...
Definition: Function.h:81
SymbolSlab runFuzzyFind(const SymbolIndex &Index, llvm::StringRef Query)
Definition: SyncAPI.cpp:129
std::string Query
A query string for the fuzzy find.
Definition: Index.h:29
virtual void refs(const RefsRequest &Req, llvm::function_ref< void(const Ref &)> Callback) const =0
Finds all occurrences (e.g.
void dumpAST(PathRef File, llvm::unique_function< void(std::string)> Callback)
Only for testing purposes.
void documentSymbols(StringRef File, Callback< std::vector< DocumentSymbol >> CB)
Retrieve the symbols within the specified file.
RefSlab::Builder is a mutable container that can &#39;freeze&#39; to RefSlab.
Definition: Ref.h:93
CodeCompletionBuilder Builder
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Expected< std::vector< SymbolInformation > > runWorkspaceSymbols(ClangdServer &Server, llvm::StringRef Query, int Limit)
Definition: SyncAPI.cpp:116
ClangdServer Server
llvm::Expected< std::vector< DocumentHighlight > > runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:95
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: Rename.cpp:36
void insert(const SymbolID &ID, const Ref &S)
Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
Definition: Ref.cpp:34
void locateSymbolAt(PathRef File, Position Pos, Callback< std::vector< LocatedSymbol >> CB)
Find declaration/definition locations of symbol at a specified position.
Manages a collection of source files and derived data (ASTs, indexes), and provides language-aware fe...
Definition: ClangdServer.h:79
llvm::Expected< std::vector< TextEdit > > runRename(ClangdServer &Server, PathRef File, Position Pos, llvm::StringRef NewName)
Definition: SyncAPI.cpp:101
void workspaceSymbols(StringRef Query, int Limit, Callback< std::vector< SymbolInformation >> CB)
Retrieve the top symbols from the workspace matching a query.
void signatureHelp(PathRef File, Position Pos, Callback< SignatureHelp > CB)
Provide signature help for File at Pos.
RefSlab getRefs(const SymbolIndex &Index, SymbolID ID)
Definition: SyncAPI.cpp:142
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags)
Definition: SyncAPI.cpp:15
const SymbolIndex * Index
Definition: Dexp.cpp:84