hierarchicalDocumentSymbol: support SymbolKind::Function declaration and uniquify by range

Also ensure selectionRange is a subrange of range, otherwise VSCode won't show the item.
Use detailed_name for 'detail'
This commit is contained in:
Fangrui Song 2018-11-16 15:23:26 -08:00
parent 06dff21720
commit b31a1c6b3e
2 changed files with 25 additions and 3 deletions

View File

@ -101,6 +101,9 @@ struct Position {
bool operator<(const Position &o) const { bool operator<(const Position &o) const {
return line != o.line ? line < o.line : character < o.character; return line != o.line ? line < o.line : character < o.character;
} }
bool operator<=(const Position &o) const {
return line != o.line ? line < o.line : character <= o.character;
}
std::string ToString() const; std::string ToString() const;
}; };

View File

@ -137,6 +137,16 @@ template<>
bool Ignore(const QueryVar::Def *def) { bool Ignore(const QueryVar::Def *def) {
return !def || def->is_local(); return !def || def->is_local();
} }
void Uniquify(std::vector<std::unique_ptr<DocumentSymbol>> &cs) {
std::sort(cs.begin(), cs.end(),
[](auto &l, auto &r) { return l->range < r->range; });
cs.erase(std::unique(cs.begin(), cs.end(),
[](auto &l, auto &r) { return l->range == r->range; }),
cs.end());
for (auto &c : cs)
Uniquify(c->children);
}
} // namespace } // namespace
void MessageHandler::textDocument_documentSymbol(Reader &reader, void MessageHandler::textDocument_documentSymbol(Reader &reader,
@ -177,8 +187,13 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
if (auto range = GetLsRange(wfile, sym.range)) { if (auto range = GetLsRange(wfile, sym.range)) {
ds->selectionRange = *range; ds->selectionRange = *range;
ds->range = ds->selectionRange; 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 (sym.extent.Valid())
if (auto range1 = GetLsRange(wfile, sym.extent)) if (auto range1 = GetLsRange(wfile, sym.extent);
range1 && range1->start <= range->start &&
range->end <= range1->end)
ds->range = *range1; ds->range = *range1;
} }
std::vector<const void *> def_ptrs; std::vector<const void *> def_ptrs;
@ -187,7 +202,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
if (!def) if (!def)
return; return;
ds->name = def->Name(false); ds->name = def->Name(false);
ds->detail = def->Name(true); 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; ds->kind = def.kind;
@ -196,6 +211,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
} }
}); });
if (!(param.all || sym.role & Role::Definition || if (!(param.all || sym.role & Role::Definition ||
ds->kind == SymbolKind::Function ||
ds->kind == SymbolKind::Method || ds->kind == SymbolKind::Method ||
ds->kind == SymbolKind::Namespace)) { ds->kind == SymbolKind::Namespace)) {
ds.reset(); ds.reset();
@ -237,8 +253,11 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
} }
std::vector<std::unique_ptr<DocumentSymbol>> result; std::vector<std::unique_ptr<DocumentSymbol>> result;
for (auto &[_, ds] : sym2ds) for (auto &[_, ds] : sym2ds)
if (ds) if (ds) {
Uniquify(ds->children);
result.push_back(std::move(ds)); result.push_back(std::move(ds));
}
Uniquify(result);
reply(result); reply(result);
} else { } else {
std::vector<SymbolInformation> result; std::vector<SymbolInformation> result;