mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Support textDocument/declaration & LocationLink
textDocument/{declaration,definition,typeDefinition} return either LocationLink[] or Location[] Add an initialization option client.linkSupport . When it is false, ccls will return Location[] disregarding client's linkSupport. `struct LocationLink` does not include originSelectionRange as it is wasteful.
This commit is contained in:
parent
e3133bea90
commit
49ae9e8912
@ -73,6 +73,8 @@ struct Config {
|
||||
struct ClientCapability {
|
||||
// TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport
|
||||
bool hierarchicalDocumentSymbolSupport = true;
|
||||
// TextDocumentClientCapabilities.definition.linkSupport
|
||||
bool linkSupport = true;
|
||||
// TextDocumentClientCapabilities.completion.completionItem.snippetSupport
|
||||
bool snippetSupport = true;
|
||||
} client;
|
||||
@ -248,30 +250,28 @@ struct Config {
|
||||
} xref;
|
||||
};
|
||||
REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings,
|
||||
resourceDir);
|
||||
resourceDir);
|
||||
REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport,
|
||||
snippetSupport);
|
||||
linkSupport, snippetSupport);
|
||||
REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||
REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize,
|
||||
suffixWhitelist, whitelist);
|
||||
suffixWhitelist, whitelist);
|
||||
REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel,
|
||||
dropOldRequests, duplicateOptional, filterAndSort, include,
|
||||
maxNum);
|
||||
dropOldRequests, duplicateOptional, filterAndSort, include,
|
||||
maxNum);
|
||||
REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave,
|
||||
spellChecking, whitelist)
|
||||
REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist,
|
||||
whitelist)
|
||||
spellChecking, whitelist)
|
||||
REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist)
|
||||
REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist,
|
||||
initialWhitelist, multiVersion, multiVersionBlacklist,
|
||||
multiVersionWhitelist, onChange, threads, trackDependency,
|
||||
whitelist);
|
||||
initialWhitelist, multiVersion, multiVersionBlacklist,
|
||||
multiVersionWhitelist, onChange, threads, trackDependency,
|
||||
whitelist);
|
||||
REFLECT_STRUCT(Config::Session, maxNum);
|
||||
REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||
REFLECT_STRUCT(Config::Xref, maxNum);
|
||||
REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
||||
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
||||
clang, client, codeLens, completion, diagnostics, highlight,
|
||||
index, session, workspaceSymbol, xref);
|
||||
REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory,
|
||||
cacheDirectory, cacheFormat, clang, client, codeLens, completion,
|
||||
diagnostics, highlight, index, session, workspaceSymbol, xref);
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
|
@ -48,10 +48,6 @@ DocumentUri DocumentUri::FromPath(const std::string &path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DocumentUri::operator==(const DocumentUri &other) const {
|
||||
return raw_uri == other.raw_uri;
|
||||
}
|
||||
|
||||
void DocumentUri::SetPath(const std::string &path) {
|
||||
// file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests
|
||||
raw_uri = path;
|
||||
|
25
src/lsp.hh
25
src/lsp.hh
@ -60,7 +60,8 @@ constexpr char window_showMessage[] = "window/showMessage";
|
||||
struct DocumentUri {
|
||||
static DocumentUri FromPath(const std::string &path);
|
||||
|
||||
bool operator==(const DocumentUri &other) const;
|
||||
bool operator==(const DocumentUri &o) const { return raw_uri == o.raw_uri; }
|
||||
bool operator<(const DocumentUri &o) const { return raw_uri < o.raw_uri; }
|
||||
|
||||
void SetPath(const std::string &path);
|
||||
std::string GetPath() const;
|
||||
@ -107,8 +108,26 @@ struct Location {
|
||||
return uri == o.uri && range == o.range;
|
||||
}
|
||||
bool operator<(const Location &o) const {
|
||||
return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri
|
||||
: range < o.range;
|
||||
return !(uri == o.uri) ? uri < o.uri : range < o.range;
|
||||
}
|
||||
};
|
||||
|
||||
struct LocationLink {
|
||||
std::string targetUri;
|
||||
lsRange targetRange;
|
||||
lsRange targetSelectionRange;
|
||||
explicit operator bool() const { return targetUri.size(); }
|
||||
explicit operator Location() && {
|
||||
return {DocumentUri{std::move(targetUri)}, targetSelectionRange};
|
||||
}
|
||||
bool operator==(const LocationLink &o) const {
|
||||
return targetUri == o.targetUri &&
|
||||
targetSelectionRange == o.targetSelectionRange;
|
||||
}
|
||||
bool operator<(const LocationLink &o) const {
|
||||
return !(targetUri == o.targetUri)
|
||||
? targetUri < o.targetUri
|
||||
: targetSelectionRange < o.targetSelectionRange;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -104,6 +104,21 @@ void ReplyOnce::NotReady(bool file) {
|
||||
Error(ErrorCode::InternalError, "not indexed");
|
||||
}
|
||||
|
||||
void ReplyOnce::ReplyLocationLink(std::vector<LocationLink> &result) {
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
if (result.size() > g_config->xref.maxNum)
|
||||
result.resize(g_config->xref.maxNum);
|
||||
if (g_config->client.linkSupport) {
|
||||
(*this)(result);
|
||||
} else {
|
||||
std::vector<Location> result1;
|
||||
for (auto &loc : result)
|
||||
result1.emplace_back(std::move(loc));
|
||||
(*this)(result1);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageHandler::Bind(const char *method,
|
||||
void (MessageHandler::*handler)(JsonReader &)) {
|
||||
method2notification[method] = [this, handler](JsonReader &reader) {
|
||||
@ -143,6 +158,7 @@ void MessageHandler::Bind(const char *method,
|
||||
}
|
||||
|
||||
MessageHandler::MessageHandler() {
|
||||
// clang-format off
|
||||
Bind("$ccls/call", &MessageHandler::ccls_call);
|
||||
Bind("$ccls/fileInfo", &MessageHandler::ccls_fileInfo);
|
||||
Bind("$ccls/info", &MessageHandler::ccls_info);
|
||||
@ -157,39 +173,31 @@ MessageHandler::MessageHandler() {
|
||||
Bind("textDocument/codeAction", &MessageHandler::textDocument_codeAction);
|
||||
Bind("textDocument/codeLens", &MessageHandler::textDocument_codeLens);
|
||||
Bind("textDocument/completion", &MessageHandler::textDocument_completion);
|
||||
Bind("textDocument/declaration", &MessageHandler::textDocument_declaration);
|
||||
Bind("textDocument/definition", &MessageHandler::textDocument_definition);
|
||||
Bind("textDocument/didChange", &MessageHandler::textDocument_didChange);
|
||||
Bind("textDocument/didClose", &MessageHandler::textDocument_didClose);
|
||||
Bind("textDocument/didOpen", &MessageHandler::textDocument_didOpen);
|
||||
Bind("textDocument/didSave", &MessageHandler::textDocument_didSave);
|
||||
Bind("textDocument/documentHighlight",
|
||||
&MessageHandler::textDocument_documentHighlight);
|
||||
Bind("textDocument/documentHighlight", &MessageHandler::textDocument_documentHighlight);
|
||||
Bind("textDocument/documentLink", &MessageHandler::textDocument_documentLink);
|
||||
Bind("textDocument/documentSymbol",
|
||||
&MessageHandler::textDocument_documentSymbol);
|
||||
Bind("textDocument/documentSymbol", &MessageHandler::textDocument_documentSymbol);
|
||||
Bind("textDocument/foldingRange", &MessageHandler::textDocument_foldingRange);
|
||||
Bind("textDocument/formatting", &MessageHandler::textDocument_formatting);
|
||||
Bind("textDocument/hover", &MessageHandler::textDocument_hover);
|
||||
Bind("textDocument/implementation",
|
||||
&MessageHandler::textDocument_implementation);
|
||||
Bind("textDocument/onTypeFormatting",
|
||||
&MessageHandler::textDocument_onTypeFormatting);
|
||||
Bind("textDocument/rangeFormatting",
|
||||
&MessageHandler::textDocument_rangeFormatting);
|
||||
Bind("textDocument/implementation", &MessageHandler::textDocument_implementation);
|
||||
Bind("textDocument/onTypeFormatting", &MessageHandler::textDocument_onTypeFormatting);
|
||||
Bind("textDocument/rangeFormatting", &MessageHandler::textDocument_rangeFormatting);
|
||||
Bind("textDocument/references", &MessageHandler::textDocument_references);
|
||||
Bind("textDocument/rename", &MessageHandler::textDocument_rename);
|
||||
Bind("textDocument/signatureHelp",
|
||||
&MessageHandler::textDocument_signatureHelp);
|
||||
Bind("textDocument/typeDefinition",
|
||||
&MessageHandler::textDocument_typeDefinition);
|
||||
Bind("workspace/didChangeConfiguration",
|
||||
&MessageHandler::workspace_didChangeConfiguration);
|
||||
Bind("workspace/didChangeWatchedFiles",
|
||||
&MessageHandler::workspace_didChangeWatchedFiles);
|
||||
Bind("workspace/didChangeWorkspaceFolders",
|
||||
&MessageHandler::workspace_didChangeWorkspaceFolders);
|
||||
Bind("textDocument/signatureHelp", &MessageHandler::textDocument_signatureHelp);
|
||||
Bind("textDocument/typeDefinition", &MessageHandler::textDocument_typeDefinition);
|
||||
Bind("workspace/didChangeConfiguration", &MessageHandler::workspace_didChangeConfiguration);
|
||||
Bind("workspace/didChangeWatchedFiles", &MessageHandler::workspace_didChangeWatchedFiles);
|
||||
Bind("workspace/didChangeWorkspaceFolders", &MessageHandler::workspace_didChangeWorkspaceFolders);
|
||||
Bind("workspace/executeCommand", &MessageHandler::workspace_executeCommand);
|
||||
Bind("workspace/symbol", &MessageHandler::workspace_symbol);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void MessageHandler::Run(InMessage &msg) {
|
||||
|
@ -177,6 +177,7 @@ REFLECT_STRUCT(ResponseError, code, message);
|
||||
REFLECT_STRUCT(Position, line, character);
|
||||
REFLECT_STRUCT(lsRange, start, end);
|
||||
REFLECT_STRUCT(Location, uri, range);
|
||||
REFLECT_STRUCT(LocationLink, targetUri, targetRange, targetSelectionRange);
|
||||
REFLECT_UNDERLYING_B(SymbolKind);
|
||||
REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
||||
REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
||||
@ -198,6 +199,7 @@ struct ReplyOnce {
|
||||
pipeline::ReplyError(id, [&](JsonWriter &w) { Reflect(w, err); });
|
||||
}
|
||||
void NotReady(bool file);
|
||||
void ReplyLocationLink(std::vector<LocationLink> &result);
|
||||
};
|
||||
|
||||
struct MessageHandler {
|
||||
@ -240,6 +242,7 @@ private:
|
||||
void textDocument_codeAction(CodeActionParam &, ReplyOnce &);
|
||||
void textDocument_codeLens(TextDocumentParam &, ReplyOnce &);
|
||||
void textDocument_completion(CompletionParam &, ReplyOnce &);
|
||||
void textDocument_declaration(TextDocumentPositionParam &, ReplyOnce &);
|
||||
void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &);
|
||||
void textDocument_didChange(TextDocumentDidChangeParam &);
|
||||
void textDocument_didClose(TextDocumentParam &);
|
||||
|
@ -39,12 +39,14 @@ void MessageHandler::ccls_vars(JsonReader &reader, ReplyOnce &reply) {
|
||||
usr = def->type;
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Kind::Type:
|
||||
result = GetLsLocations(
|
||||
db, wfiles,
|
||||
GetVarDeclarations(db, db->Type(usr).instances, param.kind));
|
||||
case Kind::Type: {
|
||||
for (DeclRef dr :
|
||||
GetVarDeclarations(db, db->Type(usr).instances, param.kind))
|
||||
if (auto loc = GetLocationLink(db, wfiles, dr))
|
||||
result.push_back(Location(std::move(loc)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
reply(result);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ struct ServerCap {
|
||||
struct SignatureHelpOptions {
|
||||
std::vector<const char *> triggerCharacters = {"(", ","};
|
||||
} signatureHelpProvider;
|
||||
bool declarationProvider = true;
|
||||
bool definitionProvider = true;
|
||||
bool typeDefinitionProvider = true;
|
||||
bool implementationProvider = true;
|
||||
@ -109,7 +110,7 @@ REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported,
|
||||
changeNotifications);
|
||||
REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders);
|
||||
REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider,
|
||||
signatureHelpProvider, definitionProvider,
|
||||
signatureHelpProvider, declarationProvider, definitionProvider,
|
||||
implementationProvider, typeDefinitionProvider,
|
||||
referencesProvider, documentHighlightProvider,
|
||||
documentSymbolProvider, workspaceSymbolProvider,
|
||||
@ -161,6 +162,11 @@ struct TextDocumentClientCap {
|
||||
} completionItem;
|
||||
} completion;
|
||||
|
||||
// Ignore declaration, implementation, typeDefinition
|
||||
struct LinkSupport {
|
||||
bool linkSupport = false;
|
||||
} definition;
|
||||
|
||||
struct DocumentSymbol {
|
||||
bool hierarchicalDocumentSymbolSupport = false;
|
||||
} documentSymbol;
|
||||
@ -171,7 +177,8 @@ REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
||||
REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
|
||||
REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
||||
hierarchicalDocumentSymbolSupport);
|
||||
REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol);
|
||||
REFLECT_STRUCT(TextDocumentClientCap::LinkSupport, linkSupport);
|
||||
REFLECT_STRUCT(TextDocumentClientCap, completion, definition, documentSymbol);
|
||||
|
||||
struct ClientCap {
|
||||
WorkspaceClientCap workspace;
|
||||
@ -272,11 +279,13 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) {
|
||||
|
||||
// Client capabilities
|
||||
const auto &capabilities = param.capabilities;
|
||||
g_config->client.snippetSupport &=
|
||||
capabilities.textDocument.completion.completionItem.snippetSupport;
|
||||
g_config->client.hierarchicalDocumentSymbolSupport &=
|
||||
capabilities.textDocument.documentSymbol
|
||||
.hierarchicalDocumentSymbolSupport;
|
||||
g_config->client.linkSupport &=
|
||||
capabilities.textDocument.definition.linkSupport;
|
||||
g_config->client.snippetSupport &=
|
||||
capabilities.textDocument.completion.completionItem.snippetSupport;
|
||||
|
||||
// Ensure there is a resource directory.
|
||||
if (g_config->clang.resourceDir.empty())
|
||||
|
@ -33,6 +33,27 @@ std::vector<DeclRef> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void MessageHandler::textDocument_declaration(TextDocumentPositionParam ¶m,
|
||||
ReplyOnce &reply) {
|
||||
int file_id;
|
||||
QueryFile *file = FindFile(param.textDocument.uri.GetPath(), &file_id);
|
||||
WorkingFile *wf = file ? wfiles->GetFile(file->def->path) : nullptr;
|
||||
if (!wf) {
|
||||
reply.NotReady(file);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<LocationLink> result;
|
||||
Position &ls_pos = param.position;
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position))
|
||||
for (DeclRef dr : GetNonDefDeclarations(db, sym))
|
||||
if (!(dr.file_id == file_id &&
|
||||
dr.range.Contains(ls_pos.line, ls_pos.character)))
|
||||
if (auto loc = GetLocationLink(db, wfiles, dr))
|
||||
result.push_back(loc);
|
||||
reply.ReplyLocationLink(result);
|
||||
}
|
||||
|
||||
void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m,
|
||||
ReplyOnce &reply) {
|
||||
int file_id;
|
||||
@ -43,54 +64,52 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m,
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Location> result;
|
||||
Maybe<Use> on_def;
|
||||
std::vector<LocationLink> result;
|
||||
Maybe<DeclRef> on_def;
|
||||
Position &ls_pos = param.position;
|
||||
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, ls_pos, true)) {
|
||||
// Special cases which are handled:
|
||||
// - symbol has declaration but no definition (ie, pure virtual)
|
||||
// - goto declaration while in definition of recursive type
|
||||
std::vector<Use> uses;
|
||||
std::vector<DeclRef> drs;
|
||||
EachEntityDef(db, sym, [&](const auto &def) {
|
||||
if (def.spell) {
|
||||
Use spell = *def.spell;
|
||||
DeclRef spell = *def.spell;
|
||||
if (spell.file_id == file_id &&
|
||||
spell.range.Contains(ls_pos.line, ls_pos.character)) {
|
||||
on_def = spell;
|
||||
uses.clear();
|
||||
drs.clear();
|
||||
return false;
|
||||
}
|
||||
uses.push_back(spell);
|
||||
drs.push_back(spell);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// |uses| is empty if on a declaration/definition, otherwise it includes
|
||||
// all declarations/definitions.
|
||||
if (uses.empty()) {
|
||||
for (Use use : GetNonDefDeclarationTargets(db, sym))
|
||||
if (!(use.file_id == file_id &&
|
||||
use.range.Contains(ls_pos.line, ls_pos.character)))
|
||||
uses.push_back(use);
|
||||
if (drs.empty()) {
|
||||
for (DeclRef dr : GetNonDefDeclarationTargets(db, sym))
|
||||
if (!(dr.file_id == file_id &&
|
||||
dr.range.Contains(ls_pos.line, ls_pos.character)))
|
||||
drs.push_back(dr);
|
||||
// There is no declaration but the cursor is on a definition.
|
||||
if (uses.empty() && on_def)
|
||||
uses.push_back(*on_def);
|
||||
if (drs.empty() && on_def)
|
||||
drs.push_back(*on_def);
|
||||
}
|
||||
auto locs = GetLsLocations(db, wfiles, uses);
|
||||
result.insert(result.end(), locs.begin(), locs.end());
|
||||
for (DeclRef dr : drs)
|
||||
if (auto loc = GetLocationLink(db, wfiles, dr))
|
||||
result.push_back(loc);
|
||||
}
|
||||
|
||||
if (result.size()) {
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
} else {
|
||||
if (result.empty()) {
|
||||
Maybe<Range> range;
|
||||
// Check #include
|
||||
for (const IndexInclude &include : file->def->includes) {
|
||||
if (include.line == ls_pos.line) {
|
||||
result.push_back(
|
||||
Location{DocumentUri::FromPath(include.resolved_path)});
|
||||
{DocumentUri::FromPath(include.resolved_path).raw_uri});
|
||||
range = {{0, 0}, {0, 0}};
|
||||
break;
|
||||
}
|
||||
@ -148,13 +167,13 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam ¶m,
|
||||
if (best_sym.kind != Kind::Invalid) {
|
||||
Maybe<DeclRef> dr = GetDefinitionSpell(db, best_sym);
|
||||
assert(dr);
|
||||
if (auto loc = GetLsLocation(db, wfiles, *dr))
|
||||
result.push_back(*loc);
|
||||
if (auto loc = GetLocationLink(db, wfiles, *dr))
|
||||
result.push_back(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reply(result);
|
||||
reply.ReplyLocationLink(result);
|
||||
}
|
||||
|
||||
void MessageHandler::textDocument_typeDefinition(
|
||||
@ -166,17 +185,16 @@ void MessageHandler::textDocument_typeDefinition(
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Location> result;
|
||||
std::vector<LocationLink> result;
|
||||
auto Add = [&](const QueryType &type) {
|
||||
for (const auto &def : type.def)
|
||||
if (def.spell) {
|
||||
if (auto ls_loc = GetLsLocation(db, wfiles, *def.spell))
|
||||
result.push_back(*ls_loc);
|
||||
}
|
||||
if (def.spell)
|
||||
if (auto loc = GetLocationLink(db, wfiles, *def.spell))
|
||||
result.push_back(loc);
|
||||
if (result.empty())
|
||||
for (const DeclRef &dr : type.declarations)
|
||||
if (auto ls_loc = GetLsLocation(db, wfiles, dr))
|
||||
result.push_back(*ls_loc);
|
||||
if (auto loc = GetLocationLink(db, wfiles, dr))
|
||||
result.push_back(loc);
|
||||
};
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wf, file, param.position)) {
|
||||
switch (sym.kind) {
|
||||
@ -199,8 +217,6 @@ void MessageHandler::textDocument_typeDefinition(
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
reply(result);
|
||||
reply.ReplyLocationLink(result);
|
||||
}
|
||||
} // namespace ccls
|
||||
|
29
src/query.cc
29
src/query.cc
@ -520,9 +520,9 @@ std::vector<Use> GetFuncDeclarations(DB *db, const std::vector<Usr> &usrs) {
|
||||
std::vector<Use> GetTypeDeclarations(DB *db, const std::vector<Usr> &usrs) {
|
||||
return GetDeclarations(db->type_usr, db->types, usrs);
|
||||
}
|
||||
std::vector<Use> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
|
||||
unsigned kind) {
|
||||
std::vector<Use> ret;
|
||||
std::vector<DeclRef> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
|
||||
unsigned kind) {
|
||||
std::vector<DeclRef> ret;
|
||||
ret.reserve(usrs.size());
|
||||
for (Usr usr : usrs) {
|
||||
QueryVar &var = db->Var(usr);
|
||||
@ -669,17 +669,18 @@ std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles,
|
||||
return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id});
|
||||
}
|
||||
|
||||
std::vector<Location> GetLsLocations(DB *db, WorkingFiles *wfiles,
|
||||
const std::vector<Use> &uses) {
|
||||
std::vector<Location> ret;
|
||||
for (Use use : uses)
|
||||
if (auto loc = GetLsLocation(db, wfiles, use))
|
||||
ret.push_back(*loc);
|
||||
std::sort(ret.begin(), ret.end());
|
||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||
if (ret.size() > g_config->xref.maxNum)
|
||||
ret.resize(g_config->xref.maxNum);
|
||||
return ret;
|
||||
LocationLink GetLocationLink(DB *db, WorkingFiles *wfiles, DeclRef dr) {
|
||||
std::string path;
|
||||
DocumentUri uri = GetLsDocumentUri(db, dr.file_id, &path);
|
||||
if (auto range = GetLsRange(wfiles->GetFile(path), dr.range))
|
||||
if (auto extent = GetLsRange(wfiles->GetFile(path), dr.extent)) {
|
||||
LocationLink ret;
|
||||
ret.targetUri = uri.raw_uri;
|
||||
ret.targetSelectionRange = *range;
|
||||
ret.targetRange = extent->Includes(*range) ? *extent : *range;
|
||||
return ret;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) {
|
||||
|
@ -189,7 +189,7 @@ Maybe<DeclRef> GetDefinitionSpell(DB *db, SymbolIdx sym);
|
||||
// for each id.
|
||||
std::vector<Use> GetFuncDeclarations(DB *, const std::vector<Usr> &);
|
||||
std::vector<Use> GetTypeDeclarations(DB *, const std::vector<Usr> &);
|
||||
std::vector<Use> GetVarDeclarations(DB *, const std::vector<Usr> &, unsigned);
|
||||
std::vector<DeclRef> GetVarDeclarations(DB *, const std::vector<Usr> &, unsigned);
|
||||
|
||||
// Get non-defining declarations.
|
||||
std::vector<DeclRef> &GetNonDefDeclarations(DB *db, SymbolIdx sym);
|
||||
@ -204,8 +204,8 @@ DocumentUri GetLsDocumentUri(DB *db, int file_id);
|
||||
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles, Use use);
|
||||
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles,
|
||||
SymbolRef sym, int file_id);
|
||||
std::vector<Location> GetLsLocations(DB *db, WorkingFiles *wfiles,
|
||||
const std::vector<Use> &uses);
|
||||
LocationLink GetLocationLink(DB *db, WorkingFiles *wfiles, DeclRef dr);
|
||||
|
||||
// Returns a symbol. The symbol will *NOT* have a location assigned.
|
||||
std::optional<SymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
|
||||
bool detailed);
|
||||
|
Loading…
Reference in New Issue
Block a user