mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 15:45:08 +00:00
Add excludeRole to documentSymbol and override declaration's range/selectionRange with definition's
This commit is contained in:
parent
478f849ada
commit
5d27ac9f34
@ -95,13 +95,15 @@ void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct DocumentSymbolParam : TextDocumentParam {
|
struct DocumentSymbolParam : TextDocumentParam {
|
||||||
// false: outline; true: all symbols
|
// Include sym if `!(sym.role & excludeRole)`.
|
||||||
bool all = false;
|
Role excludeRole = Role((int)Role::All - (int)Role::Definition -
|
||||||
|
(int)Role::Declaration - (int)Role::Dynamic);
|
||||||
// If >= 0, return Range[] instead of SymbolInformation[] to reduce output.
|
// If >= 0, return Range[] instead of SymbolInformation[] to reduce output.
|
||||||
int startLine = -1;
|
int startLine = -1;
|
||||||
int endLine = -1;
|
int endLine = -1;
|
||||||
};
|
};
|
||||||
REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine);
|
REFLECT_STRUCT(DocumentSymbolParam, textDocument, excludeRole, startLine,
|
||||||
|
endLine);
|
||||||
|
|
||||||
struct DocumentSymbol {
|
struct DocumentSymbol {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -149,18 +151,22 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
|
|||||||
|
|
||||||
int file_id;
|
int file_id;
|
||||||
auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id);
|
auto [file, wf] = FindOrFail(param.textDocument.uri.GetPath(), reply, &file_id);
|
||||||
if (!wf) {
|
if (!wf)
|
||||||
return;
|
return;
|
||||||
}
|
auto Allows = [&](SymbolRef sym) {
|
||||||
|
return !(sym.role & param.excludeRole);
|
||||||
|
};
|
||||||
|
|
||||||
if (param.startLine >= 0) {
|
if (param.startLine >= 0) {
|
||||||
std::vector<lsRange> result;
|
std::vector<lsRange> result;
|
||||||
for (auto [sym, refcnt] : file->symbol2refcnt)
|
for (auto [sym, refcnt] : file->symbol2refcnt) {
|
||||||
if (refcnt > 0 && (param.all || sym.extent.Valid()) &&
|
if (refcnt <= 0 || !Allows(sym) ||
|
||||||
param.startLine <= sym.range.start.line &&
|
!(param.startLine <= sym.range.start.line &&
|
||||||
sym.range.start.line <= param.endLine)
|
sym.range.start.line <= param.endLine))
|
||||||
if (auto loc = GetLsLocation(db, wfiles, sym, file_id))
|
continue;
|
||||||
result.push_back(loc->range);
|
if (auto loc = GetLsLocation(db, wfiles, sym, file_id))
|
||||||
|
result.push_back(loc->range);
|
||||||
|
}
|
||||||
std::sort(result.begin(), result.end());
|
std::sort(result.begin(), result.end());
|
||||||
reply(result);
|
reply(result);
|
||||||
} else if (g_config->client.hierarchicalDocumentSymbolSupport) {
|
} else if (g_config->client.hierarchicalDocumentSymbolSupport) {
|
||||||
@ -171,22 +177,26 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
|
|||||||
if (refcnt <= 0 || !sym.extent.Valid())
|
if (refcnt <= 0 || !sym.extent.Valid())
|
||||||
continue;
|
continue;
|
||||||
auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind});
|
auto r = sym2ds.try_emplace(SymbolIdx{sym.usr, sym.kind});
|
||||||
|
auto &ds = r.first->second;
|
||||||
|
if (!ds || sym.role & Role::Definition) {
|
||||||
|
if (!ds)
|
||||||
|
ds = std::make_unique<DocumentSymbol>();
|
||||||
|
if (auto range = GetLsRange(wf, sym.range)) {
|
||||||
|
ds->selectionRange = *range;
|
||||||
|
ds->range = ds->selectionRange;
|
||||||
|
// For a macro expansion, M(name), we may use `M` for extent and
|
||||||
|
// `name` for spell, do the check as selectionRange must be a subrange
|
||||||
|
// of range.
|
||||||
|
if (sym.extent.Valid())
|
||||||
|
if (auto range1 = GetLsRange(wf, sym.extent);
|
||||||
|
range1 && range1->Includes(*range))
|
||||||
|
ds->range = *range1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!r.second)
|
if (!r.second)
|
||||||
continue;
|
continue;
|
||||||
auto &ds = r.first->second;
|
|
||||||
ds = std::make_unique<DocumentSymbol>();
|
|
||||||
if (auto range = GetLsRange(wf, sym.range)) {
|
|
||||||
ds->selectionRange = *range;
|
|
||||||
ds->range = ds->selectionRange;
|
|
||||||
// For a macro expansion, M(name), we may use `M` for extent and `name`
|
|
||||||
// for spell, do the check as selectionRange must be a subrange of
|
|
||||||
// range.
|
|
||||||
if (sym.extent.Valid())
|
|
||||||
if (auto range1 = GetLsRange(wf, sym.extent);
|
|
||||||
range1 && range1->Includes(*range))
|
|
||||||
ds->range = *range1;
|
|
||||||
}
|
|
||||||
std::vector<const void *> def_ptrs;
|
std::vector<const void *> def_ptrs;
|
||||||
|
SymbolKind kind = SymbolKind::Unknown;
|
||||||
WithEntity(db, sym, [&](const auto &entity) {
|
WithEntity(db, sym, [&](const auto &entity) {
|
||||||
auto *def = entity.AnyDef();
|
auto *def = entity.AnyDef();
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -195,20 +205,14 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
|
|||||||
ds->detail = def->detailed_name;
|
ds->detail = def->detailed_name;
|
||||||
for (auto &def : entity.def)
|
for (auto &def : entity.def)
|
||||||
if (def.file_id == file_id && !Ignore(&def)) {
|
if (def.file_id == file_id && !Ignore(&def)) {
|
||||||
ds->kind = def.kind;
|
kind = ds->kind = def.kind;
|
||||||
if (def.spell || def.kind == SymbolKind::Namespace)
|
def_ptrs.push_back(&def);
|
||||||
def_ptrs.push_back(&def);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!(param.all || sym.role & Role::Definition ||
|
if (def_ptrs.empty() || !(kind == SymbolKind::Namespace || Allows(sym))) {
|
||||||
ds->kind == SymbolKind::Function ||
|
|
||||||
ds->kind == SymbolKind::Method ||
|
|
||||||
ds->kind == SymbolKind::Namespace)) {
|
|
||||||
ds.reset();
|
ds.reset();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (def_ptrs.empty())
|
|
||||||
continue;
|
|
||||||
if (sym.kind == Kind::Func)
|
if (sym.kind == Kind::Func)
|
||||||
funcs.emplace_back(std::move(def_ptrs), ds.get());
|
funcs.emplace_back(std::move(def_ptrs), ds.get());
|
||||||
else if (sym.kind == Kind::Type)
|
else if (sym.kind == Kind::Type)
|
||||||
@ -252,8 +256,7 @@ void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
|
|||||||
} else {
|
} else {
|
||||||
std::vector<SymbolInformation> result;
|
std::vector<SymbolInformation> result;
|
||||||
for (auto [sym, refcnt] : file->symbol2refcnt) {
|
for (auto [sym, refcnt] : file->symbol2refcnt) {
|
||||||
if (refcnt <= 0 || !sym.extent.Valid() ||
|
if (refcnt <= 0 || !Allows(sym))
|
||||||
!(param.all || sym.role & Role::Definition))
|
|
||||||
continue;
|
continue;
|
||||||
if (std::optional<SymbolInformation> info =
|
if (std::optional<SymbolInformation> info =
|
||||||
GetSymbolInfo(db, sym, false)) {
|
GetSymbolInfo(db, sym, false)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user