21 #include "clang/Index/IndexSymbol.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/FormatVariadic.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/StringSaver.h"
35 using llvm::sys::path::append;
36 using llvm::sys::path::convert_to_slash;
37 using llvm::sys::path::is_absolute;
38 using llvm::sys::path::replace_path_prefix;
39 using llvm::sys::path::Style;
43 template <
typename IDRange>
44 llvm::Expected<llvm::DenseSet<SymbolID>> getIDs(IDRange IDs) {
45 llvm::DenseSet<SymbolID> Result;
46 for (
const auto &
ID : IDs) {
49 return SID.takeError();
58 llvm::StringRef LocalIndexRoot)
60 llvm::StringRef PosixSeparator = get_separator(Style::posix);
61 if (!RemoteIndexRoot.empty()) {
62 assert(is_absolute(RemoteIndexRoot));
63 this->RemoteIndexRoot = convert_to_slash(RemoteIndexRoot, Style::windows);
64 llvm::StringRef
Path(this->RemoteIndexRoot);
65 if (!is_separator(this->RemoteIndexRoot.back(), Style::posix))
66 this->RemoteIndexRoot += PosixSeparator;
68 if (!LocalIndexRoot.empty()) {
69 assert(is_absolute(LocalIndexRoot));
70 this->LocalIndexRoot = convert_to_slash(LocalIndexRoot, Style::windows);
71 llvm::StringRef
Path(this->LocalIndexRoot);
72 if (!is_separator(this->LocalIndexRoot.back(), Style::posix))
73 this->LocalIndexRoot += PosixSeparator;
75 assert(!RemoteIndexRoot.empty() || !LocalIndexRoot.empty());
78 llvm::Expected<clangd::LookupRequest>
81 auto IDs = getIDs(
Message->ids());
83 return IDs.takeError();
84 Req.
IDs = std::move(*IDs);
88 llvm::Expected<clangd::FuzzyFindRequest>
90 assert(!RemoteIndexRoot.empty());
92 Result.Query =
Message->query();
93 for (
const auto &Scope :
Message->scopes())
94 Result.Scopes.push_back(Scope);
95 Result.AnyScope =
Message->any_scope();
97 Result.Limit =
Message->limit();
98 Result.RestrictForCodeCompletion =
Message->restricted_for_code_completion();
99 for (
const auto &
Path :
Message->proximity_paths()) {
100 llvm::SmallString<256> LocalPath = llvm::StringRef(RemoteIndexRoot);
101 append(LocalPath,
Path);
104 llvm::sys::path::native(LocalPath);
105 Result.ProximityPaths.push_back(std::string(LocalPath));
107 for (
const auto &
Type :
Message->preferred_types())
108 Result.ProximityPaths.push_back(
Type);
112 llvm::Expected<clangd::RefsRequest>
115 auto IDs = getIDs(
Message->ids());
117 return IDs.takeError();
118 Req.
IDs = std::move(*IDs);
129 llvm::Expected<clangd::RelationsRequest>
132 auto IDs = getIDs(
Message->subjects());
134 return IDs.takeError();
137 return error(
"RelationsRequest requires RelationKind predicate.");
146 return error(
"Missing info or declaration.");
150 return ID.takeError();
154 Result.Scope =
Message.scope();
155 if (
Message.has_definition()) {
164 Result.References =
Message.references();
167 Result.Signature =
Message.signature();
168 Result.TemplateSpecializationArgs =
Message.template_specialization_args();
169 Result.CompletionSnippetSuffix =
Message.completion_snippet_suffix();
170 Result.Documentation =
Message.documentation();
171 Result.ReturnType =
Message.return_type();
173 for (
const auto &Header :
Message.headers()) {
175 if (!SerializedHeader)
176 return SerializedHeader.takeError();
177 Result.IncludeHeaders.push_back(*SerializedHeader);
185 return error(
"Missing location.");
195 llvm::Expected<std::pair<clangd::SymbolID, clangd::Symbol>>
199 return SubjectID.takeError();
201 return error(
"Missing Object.");
204 return Object.takeError();
205 return std::make_pair(*SubjectID, *
Object);
216 assert(!LocalIndexRoot.empty());
218 RPCRequest.set_query(From.
Query);
219 for (
const auto &Scope : From.
Scopes)
220 RPCRequest.add_scopes(Scope);
221 RPCRequest.set_any_scope(From.
AnyScope);
223 RPCRequest.set_limit(*From.
Limit);
226 llvm::SmallString<256> RelativePath = llvm::StringRef(
Path);
227 if (replace_path_prefix(RelativePath, LocalIndexRoot,
""))
228 RPCRequest.add_proximity_paths(
229 convert_to_slash(RelativePath, Style::windows));
232 RPCRequest.add_preferred_types(
Type);
238 for (
const auto &
ID : From.
IDs)
239 RPCRequest.add_ids(
ID.str());
240 RPCRequest.set_filter(
static_cast<uint32_t
>(From.
Filter));
242 RPCRequest.set_limit(*From.
Limit);
250 RPCRequest.add_subjects(
ID.str());
251 RPCRequest.set_predicate(
static_cast<uint32_t
>(From.
Predicate));
253 RPCRequest.set_limit(*From.
Limit);
259 Result.set_id(From.
ID.
str());
261 Result.set_name(From.
Name.str());
268 Result.set_scope(From.
Scope.str());
272 *Result.mutable_canonical_declaration() = *
Declaration;
274 Result.set_signature(From.
Signature.str());
275 Result.set_template_specialization_args(
279 Result.set_return_type(From.
ReturnType.str());
280 Result.set_type(From.
Type.str());
284 return Serialized.takeError();
285 auto *NextHeader = Result.add_headers();
286 *NextHeader = *Serialized;
288 Result.set_flags(
static_cast<uint32_t
>(From.
Flags));
294 Result.set_kind(
static_cast<uint32_t
>(From.
Kind));
298 *Result.mutable_location() = *
Location;
305 *Result.mutable_subject_id() = Subject.
str();
307 if (!SerializedObject)
308 return SerializedObject.takeError();
309 *Result.mutable_object() = *SerializedObject;
313 llvm::Expected<std::string>
315 assert(!LocalIndexRoot.empty());
316 assert(RelativePath == convert_to_slash(RelativePath));
317 if (RelativePath.empty())
318 return error(
"Empty relative path.");
319 if (is_absolute(RelativePath, Style::posix))
320 return error(
"RelativePath '{0}' is absolute.", RelativePath);
321 llvm::SmallString<256> FullPath = llvm::StringRef(LocalIndexRoot);
322 append(FullPath, RelativePath);
324 return Result.toString();
328 assert(!RemoteIndexRoot.empty());
331 return ParsedURI.takeError();
332 if (ParsedURI->scheme() !=
"file")
333 return error(
"Can not use URI schemes other than file, given: '{0}'.",
URI);
334 llvm::SmallString<256> Result = ParsedURI->body();
335 llvm::StringRef
Path(Result);
337 if (is_absolute(
Path.substr(1), Style::windows))
338 Result =
Path.drop_front();
339 if (!replace_path_prefix(Result, RemoteIndexRoot,
""))
340 return error(
"File path '{0}' doesn't start with '{1}'.", Result.str(),
342 assert(Result == convert_to_slash(Result, Style::windows));
343 return std::string(Result);
349 Result.setColumn(
static_cast<uint32_t
>(
Message.column()));
350 Result.setLine(
static_cast<uint32_t
>(
Message.line()));
356 remote::Position Result;
357 Result.set_column(
Position.column());
365 Result.SubKind =
static_cast<clang::index::SymbolSubKind
>(
Message.subkind());
366 Result.Lang =
static_cast<clang::index::SymbolLanguage
>(
Message.language());
368 static_cast<clang::index::SymbolPropertySet
>(
Message.properties());
374 Result.set_kind(
static_cast<uint32_t
>(
Info.Kind));
375 Result.set_subkind(
static_cast<uint32_t
>(
Info.SubKind));
376 Result.set_language(
static_cast<uint32_t
>(
Info.Lang));
377 Result.set_properties(
static_cast<uint32_t
>(
Info.Properties));
381 llvm::Expected<clangd::SymbolLocation>
386 return URIString.takeError();
387 Location.FileURI = Strings.save(*URIString).begin();
393 llvm::Expected<SymbolLocation>
395 remote::SymbolLocation Result;
398 return RelativePath.takeError();
399 *Result.mutable_file_path() = *RelativePath;
406 const clangd::Symbol::IncludeHeaderWithReferences &IncludeHeader) {
407 HeaderWithReferences Result;
408 Result.set_references(IncludeHeader.References);
409 Result.set_supported_directives(IncludeHeader.SupportedDirectives);
410 const std::string Header = IncludeHeader.IncludeHeader.str();
412 Result.set_header(Header);
417 return RelativePath.takeError();
418 Result.set_header(*RelativePath);
422 llvm::Expected<clangd::Symbol::IncludeHeaderWithReferences>
424 std::string Header =
Message.header();
428 return URIString.takeError();
431 auto Directives = clangd::Symbol::IncludeDirective::Include;
432 if (
Message.has_supported_directives())
434 Message.supported_directives());
435 return clangd::Symbol::IncludeHeaderWithReferences{
436 Strings.save(Header),
Message.references(), Directives};