mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-16 21:58:08 +00:00
Add SymbolRole to SymbolRef and fix $cquery/{base,derived} by ordering definitions before uses
This commit is contained in:
parent
777193d02f
commit
16bf3158c5
@ -65,3 +65,23 @@ enum class StorageClass : uint8_t {
|
||||
};
|
||||
MAKE_REFLECT_TYPE_PROXY(StorageClass,
|
||||
std::underlying_type<StorageClass>::type);
|
||||
|
||||
enum class SymbolRole : uint8_t {
|
||||
Declaration = 1 << 0,
|
||||
Definition = 1 << 1,
|
||||
Reference = 1 << 2,
|
||||
Implicit = 1 << 3,
|
||||
|
||||
ChildOf = 1 << 4,
|
||||
BaseOf = 1 << 5,
|
||||
CalledBy = 1 << 6,
|
||||
};
|
||||
MAKE_REFLECT_TYPE_PROXY(SymbolRole, std::underlying_type<SymbolRole>::type);
|
||||
|
||||
inline uint8_t operator&(SymbolRole lhs, SymbolRole rhs) {
|
||||
return uint8_t(lhs) & uint8_t(rhs);
|
||||
}
|
||||
|
||||
inline SymbolRole operator|(SymbolRole lhs, SymbolRole rhs) {
|
||||
return SymbolRole(uint8_t(lhs) | uint8_t(rhs));
|
||||
}
|
||||
|
@ -23,8 +23,17 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||
|
||||
Out_LocationList out;
|
||||
out.id = request->id;
|
||||
for (const SymbolRef& ref :
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
std::vector<SymbolRef> refs =
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position);
|
||||
// A template definition may be a use of its primary template.
|
||||
// We want to get the definition instead of the use.
|
||||
// Order by |Definition| DESC, range size ASC.
|
||||
std::stable_sort(refs.begin(), refs.end(),
|
||||
[](const SymbolRef& a, const SymbolRef& b) {
|
||||
return (a.role & SymbolRole::Definition) >
|
||||
(b.role & SymbolRole::Definition);
|
||||
});
|
||||
for (const SymbolRef& ref : refs) {
|
||||
if (ref.idx.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->types[ref.idx.idx];
|
||||
if (!type.def)
|
||||
@ -32,11 +41,13 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||
std::vector<QueryLocation> locations =
|
||||
ToQueryLocation(db, type.def->parents);
|
||||
out.result = GetLsLocations(db, working_files, locations);
|
||||
break;
|
||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
||||
std::vector<QueryLocation> locations =
|
||||
ToQueryLocation(db, func.def->base);
|
||||
out.result = GetLsLocations(db, working_files, locations);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QueueManager::WriteStdout(IpcId::CqueryBase, out);
|
||||
|
@ -23,18 +23,29 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
||||
|
||||
Out_LocationList out;
|
||||
out.id = request->id;
|
||||
for (const SymbolRef& ref :
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
std::vector<SymbolRef> refs =
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position);
|
||||
// A template definition may be a use of its primary template.
|
||||
// We want to get the definition instead of the use.
|
||||
// Order by |Definition| DESC, range size ASC.
|
||||
std::stable_sort(refs.begin(), refs.end(),
|
||||
[](const SymbolRef& a, const SymbolRef& b) {
|
||||
return (a.role & SymbolRole::Definition) >
|
||||
(b.role & SymbolRole::Definition);
|
||||
});
|
||||
for (const SymbolRef& ref : refs) {
|
||||
if (ref.idx.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->types[ref.idx.idx];
|
||||
std::vector<QueryLocation> locations =
|
||||
ToQueryLocation(db, type.derived);
|
||||
out.result = GetLsLocations(db, working_files, locations);
|
||||
break;
|
||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
||||
std::vector<QueryLocation> locations =
|
||||
ToQueryLocation(db, func.derived);
|
||||
out.result = GetLsLocations(db, working_files, locations);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QueueManager::WriteStdout(IpcId::CqueryDerived, out);
|
||||
|
26
src/query.cc
26
src/query.cc
@ -219,30 +219,31 @@ QueryFile::Def BuildFileDef(const IdMap& id_map, const IndexFile& indexed) {
|
||||
}();
|
||||
|
||||
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
|
||||
def.outline.push_back(SymbolRef(idx, id_map.ToQuery(range)));
|
||||
def.outline.push_back(
|
||||
SymbolRef(idx, SymbolRole::Declaration, id_map.ToQuery(range)));
|
||||
};
|
||||
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, Range range) {
|
||||
def.all_symbols.push_back(SymbolRef(idx, id_map.ToQuery(range)));
|
||||
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, SymbolRole role,
|
||||
Range range) {
|
||||
def.all_symbols.push_back(SymbolRef(idx, role, id_map.ToQuery(range)));
|
||||
};
|
||||
|
||||
for (const IndexType& type : indexed.types) {
|
||||
if (type.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(type.id),
|
||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Definition,
|
||||
type.def.definition_spelling.value());
|
||||
if (type.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(type.id), type.def.definition_extent.value());
|
||||
for (const Range& use : type.uses)
|
||||
add_all_symbols(id_map.ToSymbol(type.id), use);
|
||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Reference, use);
|
||||
}
|
||||
for (const IndexFunc& func : indexed.funcs) {
|
||||
if (func.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(func.id),
|
||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Definition,
|
||||
func.def.definition_spelling.value());
|
||||
if (func.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(func.id), func.def.definition_extent.value());
|
||||
for (const IndexFunc::Declaration& decl : func.declarations) {
|
||||
// TODO: add more outline info?
|
||||
add_all_symbols(id_map.ToSymbol(func.id), decl.spelling);
|
||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration, decl.spelling);
|
||||
add_outline(id_map.ToSymbol(func.id), decl.spelling);
|
||||
}
|
||||
for (const IndexFuncRef& caller : func.callers) {
|
||||
@ -256,21 +257,22 @@ QueryFile::Def BuildFileDef(const IdMap& id_map, const IndexFile& indexed) {
|
||||
range.start.column--;
|
||||
range.end.column++;
|
||||
}
|
||||
add_all_symbols(id_map.ToSymbol(func.id), range);
|
||||
add_all_symbols(id_map.ToSymbol(func.id),
|
||||
SymbolRole::Implicit | SymbolRole::CalledBy, range);
|
||||
}
|
||||
}
|
||||
for (const IndexVar& var : indexed.vars) {
|
||||
if (var.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(var.id),
|
||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Definition,
|
||||
var.def.definition_spelling.value());
|
||||
if (var.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(var.id), var.def.definition_extent.value());
|
||||
for (const Range& decl : var.declarations) {
|
||||
add_all_symbols(id_map.ToSymbol(var.id), decl);
|
||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
|
||||
add_outline(id_map.ToSymbol(var.id), decl);
|
||||
}
|
||||
for (const Range& use : var.uses)
|
||||
add_all_symbols(id_map.ToSymbol(var.id), use);
|
||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Reference, use);
|
||||
}
|
||||
|
||||
std::sort(def.outline.begin(), def.outline.end(),
|
||||
|
@ -81,10 +81,12 @@ MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
|
||||
|
||||
struct SymbolRef {
|
||||
SymbolIdx idx;
|
||||
SymbolRole role;
|
||||
QueryLocation loc;
|
||||
|
||||
SymbolRef() {} // Do not use, needed for reflect.
|
||||
SymbolRef(SymbolIdx idx, QueryLocation loc) : idx(idx), loc(loc) {}
|
||||
SymbolRef(SymbolIdx idx, SymbolRole role, QueryLocation loc)
|
||||
: idx(idx), role(role), loc(loc) {}
|
||||
|
||||
bool operator==(const SymbolRef& that) const {
|
||||
return idx == that.idx && loc == that.loc;
|
||||
|
@ -488,6 +488,7 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
// TODO Sort only by range length, not |kind| or |idx|
|
||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||
QueryFile* file,
|
||||
lsPosition position) {
|
||||
|
Loading…
Reference in New Issue
Block a user