mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Rename *DefDefinitionData::{base,parents} to bases and add inheritanceHierarchy{Initial,Expand}
This commit is contained in:
parent
dc18f04759
commit
95797be730
@ -342,11 +342,12 @@ void LaunchStdinLoop(Config* config,
|
||||
case IpcId::WorkspaceSymbol:
|
||||
case IpcId::CqueryFileInfo:
|
||||
case IpcId::CqueryFreshenIndex:
|
||||
case IpcId::CqueryInheritanceHierarchy:
|
||||
case IpcId::CqueryCallHierarchyInitial:
|
||||
case IpcId::CqueryCallHierarchyExpand:
|
||||
case IpcId::CqueryCallTreeInitial:
|
||||
case IpcId::CqueryCallTreeExpand:
|
||||
case IpcId::CqueryInheritanceHierarchyInitial:
|
||||
case IpcId::CqueryInheritanceHierarchyExpand:
|
||||
case IpcId::CqueryMemberHierarchyInitial:
|
||||
case IpcId::CqueryMemberHierarchyExpand:
|
||||
case IpcId::CqueryVars:
|
||||
|
@ -687,7 +687,7 @@ void OnIndexReference_Function(IndexFile* db,
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
const int IndexFile::kMajorVersion = 14;
|
||||
const int IndexFile::kMajorVersion = 15;
|
||||
const int IndexFile::kMinorVersion = 0;
|
||||
|
||||
IndexFile::IndexFile(const std::string& path, const std::string& contents)
|
||||
@ -1531,7 +1531,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
db->Resolve(parent_id)->derived.push_back(ns_id);
|
||||
// |ns| may be invalidated.
|
||||
ns = db->Resolve(ns_id);
|
||||
ns->def.parents.push_back(parent_id);
|
||||
ns->def.bases.push_back(parent_id);
|
||||
}
|
||||
}
|
||||
AddUse(db, ns->uses, spell, lex_parent);
|
||||
@ -1744,7 +1744,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
IndexFunc* parent_def = db->Resolve(parent_id);
|
||||
func = db->Resolve(func_id); // ToFuncId invalidated func_def
|
||||
|
||||
func->def.base.push_back(parent_id);
|
||||
func->def.bases.push_back(parent_id);
|
||||
parent_def->derived.push_back(func_id);
|
||||
}
|
||||
|
||||
@ -1887,7 +1887,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
SetUse(db, origin_cursor.get_extent(), origin_lex, Role::None);
|
||||
}
|
||||
origin->derived.push_back(type_id);
|
||||
type->def.parents.push_back(origin_id);
|
||||
type->def.bases.push_back(origin_id);
|
||||
}
|
||||
// fallthrough
|
||||
case CXIdxEntity_Template: {
|
||||
@ -1923,7 +1923,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
if (parent_type_id) {
|
||||
IndexType* parent_type_def = db->Resolve(parent_type_id.value());
|
||||
parent_type_def->derived.push_back(type_id);
|
||||
type->def.parents.push_back(*parent_type_id);
|
||||
type->def.bases.push_back(*parent_type_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ struct TypeDefDefinitionData {
|
||||
Maybe<Use> extent;
|
||||
|
||||
// Immediate parent types.
|
||||
std::vector<typename F::TypeId> parents;
|
||||
std::vector<typename F::TypeId> bases;
|
||||
|
||||
// Types, functions, and variables defined in this type.
|
||||
std::vector<typename F::TypeId> types;
|
||||
@ -181,7 +181,7 @@ struct TypeDefDefinitionData {
|
||||
bool operator==(const TypeDefDefinitionData& o) const {
|
||||
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||
extent == o.extent && alias_of == o.alias_of &&
|
||||
parents == o.parents && types == o.types && funcs == o.funcs &&
|
||||
bases == o.bases && types == o.types && funcs == o.funcs &&
|
||||
vars == o.vars && kind == o.kind && hover == o.hover &&
|
||||
comments == o.comments;
|
||||
}
|
||||
@ -193,6 +193,10 @@ struct TypeDefDefinitionData {
|
||||
return std::string_view(detailed_name.c_str() + short_name_offset,
|
||||
short_name_size);
|
||||
}
|
||||
// Used by cquery_inheritance_hierarchy.cc:Expand generic lambda
|
||||
std::string_view DetailedName(bool) const {
|
||||
return detailed_name;
|
||||
}
|
||||
};
|
||||
template <typename TVisitor, typename Family>
|
||||
void Reflect(TVisitor& visitor, TypeDefDefinitionData<Family>& value) {
|
||||
@ -207,7 +211,7 @@ void Reflect(TVisitor& visitor, TypeDefDefinitionData<Family>& value) {
|
||||
REFLECT_MEMBER(extent);
|
||||
REFLECT_MEMBER(file);
|
||||
REFLECT_MEMBER(alias_of);
|
||||
REFLECT_MEMBER(parents);
|
||||
REFLECT_MEMBER(bases);
|
||||
REFLECT_MEMBER(types);
|
||||
REFLECT_MEMBER(funcs);
|
||||
REFLECT_MEMBER(vars);
|
||||
@ -250,7 +254,7 @@ struct FuncDefDefinitionData {
|
||||
Maybe<Use> extent;
|
||||
|
||||
// Method this method overrides.
|
||||
std::vector<typename F::FuncId> base;
|
||||
std::vector<typename F::FuncId> bases;
|
||||
|
||||
// Local variables defined in this function.
|
||||
std::vector<typename F::VarId> locals;
|
||||
@ -269,7 +273,7 @@ struct FuncDefDefinitionData {
|
||||
bool operator==(const FuncDefDefinitionData& o) const {
|
||||
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||
extent == o.extent && declaring_type == o.declaring_type &&
|
||||
base == o.base && locals == o.locals && callees == o.callees &&
|
||||
bases == o.bases && locals == o.locals && callees == o.callees &&
|
||||
kind == o.kind && storage == o.storage && hover == o.hover &&
|
||||
comments == o.comments;
|
||||
}
|
||||
@ -281,6 +285,12 @@ struct FuncDefDefinitionData {
|
||||
return std::string_view(detailed_name.c_str() + short_name_offset,
|
||||
short_name_size);
|
||||
}
|
||||
std::string_view DetailedName(bool params) const {
|
||||
if (params)
|
||||
return detailed_name;
|
||||
return std::string_view(detailed_name)
|
||||
.substr(0, short_name_offset + short_name_size);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TVisitor, typename Family>
|
||||
@ -297,7 +307,7 @@ void Reflect(TVisitor& visitor, FuncDefDefinitionData<Family>& value) {
|
||||
REFLECT_MEMBER(extent);
|
||||
REFLECT_MEMBER(file);
|
||||
REFLECT_MEMBER(declaring_type);
|
||||
REFLECT_MEMBER(base);
|
||||
REFLECT_MEMBER(bases);
|
||||
REFLECT_MEMBER(locals);
|
||||
REFLECT_MEMBER(callees);
|
||||
REFLECT_MEMBER_END();
|
||||
|
@ -70,8 +70,6 @@ const char* IpcIdToString(IpcId id) {
|
||||
return "$cquery/fileInfo";
|
||||
case IpcId::CqueryFreshenIndex:
|
||||
return "$cquery/freshenIndex";
|
||||
case IpcId::CqueryInheritanceHierarchy:
|
||||
return "$cquery/inheritanceHierarchy";
|
||||
case IpcId::CqueryCallHierarchyInitial:
|
||||
return "$cquery/callHierarchyInitial";
|
||||
case IpcId::CqueryCallHierarchyExpand:
|
||||
@ -80,6 +78,10 @@ const char* IpcIdToString(IpcId id) {
|
||||
return "$cquery/callTreeInitial";
|
||||
case IpcId::CqueryCallTreeExpand:
|
||||
return "$cquery/callTreeExpand";
|
||||
case IpcId::CqueryInheritanceHierarchyInitial:
|
||||
return "$cquery/inheritanceHierarchyInitial";
|
||||
case IpcId::CqueryInheritanceHierarchyExpand:
|
||||
return "$cquery/inheritanceHierarchyExpand";
|
||||
case IpcId::CqueryMemberHierarchyInitial:
|
||||
return "$cquery/memberHierarchyInitial";
|
||||
case IpcId::CqueryMemberHierarchyExpand:
|
||||
|
@ -48,11 +48,12 @@ enum class IpcId : int {
|
||||
CqueryFileInfo,
|
||||
CqueryFreshenIndex,
|
||||
// Messages used in tree views.
|
||||
CqueryInheritanceHierarchy,
|
||||
CqueryCallHierarchyInitial,
|
||||
CqueryCallHierarchyExpand,
|
||||
CqueryCallTreeInitial,
|
||||
CqueryCallTreeExpand,
|
||||
CqueryInheritanceHierarchyInitial,
|
||||
CqueryInheritanceHierarchyExpand,
|
||||
CqueryMemberHierarchyInitial,
|
||||
CqueryMemberHierarchyExpand,
|
||||
// These are like DocumentReferences but show different types of data.
|
||||
|
@ -28,13 +28,13 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, GetDeclarations(db, def->parents),
|
||||
GetLsLocationExs(db, working_files, GetDeclarations(db, def->bases),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
} else if (sym.kind == SymbolKind::Func) {
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, GetDeclarations(db, def->base),
|
||||
GetLsLocationExs(db, working_files, GetDeclarations(db, def->bases),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ void Expand(MessageHandler* m,
|
||||
const QueryFunc& func1 = *stack.back();
|
||||
stack.pop_back();
|
||||
if (auto* def1 = func1.AnyDef()) {
|
||||
EachDefinedEntity(m->db->funcs, def1->base, [&](QueryFunc& func2) {
|
||||
EachDefinedEntity(m->db->funcs, def1->bases, [&](QueryFunc& func2) {
|
||||
if (!seen.count(func2.usr)) {
|
||||
seen.insert(func2.usr);
|
||||
stack.push_back(&func2);
|
||||
|
@ -3,187 +3,200 @@
|
||||
#include "queue_manager.h"
|
||||
|
||||
namespace {
|
||||
struct Ipc_CqueryInheritanceHierarchy
|
||||
: public RequestMessage<Ipc_CqueryInheritanceHierarchy> {
|
||||
const static IpcId kIpcId = IpcId::CqueryInheritanceHierarchy;
|
||||
lsTextDocumentPositionParams params;
|
||||
struct Ipc_CqueryInheritanceHierarchyInitial
|
||||
: public RequestMessage<Ipc_CqueryInheritanceHierarchyInitial> {
|
||||
const static IpcId kIpcId = IpcId::CqueryInheritanceHierarchyInitial;
|
||||
struct Params {
|
||||
lsTextDocumentIdentifier textDocument;
|
||||
lsPosition position;
|
||||
// true: derived classes/functions; false: base classes/functions
|
||||
bool derived = false;
|
||||
bool detailedName = false;
|
||||
int levels = 1;
|
||||
};
|
||||
Params params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchy, id, params);
|
||||
REGISTER_IPC_MESSAGE(Ipc_CqueryInheritanceHierarchy);
|
||||
|
||||
MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchyInitial::Params,
|
||||
textDocument,
|
||||
position,
|
||||
derived,
|
||||
detailedName,
|
||||
levels);
|
||||
MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchyInitial, id, params);
|
||||
REGISTER_IPC_MESSAGE(Ipc_CqueryInheritanceHierarchyInitial);
|
||||
|
||||
struct Ipc_CqueryInheritanceHierarchyExpand
|
||||
: public RequestMessage<Ipc_CqueryInheritanceHierarchyExpand> {
|
||||
const static IpcId kIpcId = IpcId::CqueryInheritanceHierarchyExpand;
|
||||
struct Params {
|
||||
Maybe<Id<void>> id;
|
||||
SymbolKind kind = SymbolKind::Invalid;
|
||||
bool derived = false;
|
||||
bool detailedName = false;
|
||||
int levels = 1;
|
||||
};
|
||||
Params params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchyExpand::Params,
|
||||
id,
|
||||
kind,
|
||||
derived,
|
||||
detailedName,
|
||||
levels);
|
||||
MAKE_REFLECT_STRUCT(Ipc_CqueryInheritanceHierarchyExpand, id, params);
|
||||
REGISTER_IPC_MESSAGE(Ipc_CqueryInheritanceHierarchyExpand);
|
||||
|
||||
struct Out_CqueryInheritanceHierarchy
|
||||
: public lsOutMessage<Out_CqueryInheritanceHierarchy> {
|
||||
struct TypeEntry {
|
||||
struct Entry {
|
||||
Id<void> id;
|
||||
SymbolKind kind;
|
||||
std::string_view name;
|
||||
optional<lsLocation> location;
|
||||
std::vector<TypeEntry> children;
|
||||
lsLocation location;
|
||||
// For unexpanded nodes, this is an upper bound because some entities may be
|
||||
// undefined. If it is 0, there are no members.
|
||||
int numChildren;
|
||||
// Empty if the |levels| limit is reached.
|
||||
std::vector<Entry> children;
|
||||
};
|
||||
lsRequestId id;
|
||||
optional<TypeEntry> result;
|
||||
optional<Entry> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_CqueryInheritanceHierarchy::TypeEntry,
|
||||
MAKE_REFLECT_STRUCT(Out_CqueryInheritanceHierarchy::Entry,
|
||||
id,
|
||||
kind,
|
||||
name,
|
||||
location,
|
||||
numChildren,
|
||||
children);
|
||||
MAKE_REFLECT_STRUCT(Out_CqueryInheritanceHierarchy, jsonrpc, id, result);
|
||||
|
||||
std::vector<Out_CqueryInheritanceHierarchy::TypeEntry>
|
||||
BuildParentInheritanceHierarchyForType(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryType& root_type) {
|
||||
std::vector<Out_CqueryInheritanceHierarchy::TypeEntry> parent_entries;
|
||||
const QueryType::Def* def = root_type.AnyDef();
|
||||
parent_entries.reserve(def->parents.size());
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CqueryInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool detailed_name,
|
||||
int levels);
|
||||
|
||||
EachDefinedEntity(db->types, def->parents, [&](QueryType& parent_type) {
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry parent_entry;
|
||||
const QueryType::Def* def1 = parent_type.AnyDef();
|
||||
parent_entry.name = def1->detailed_name.c_str();
|
||||
if (def1->spell)
|
||||
parent_entry.location = GetLsLocation(db, working_files, *def1->spell);
|
||||
parent_entry.children =
|
||||
BuildParentInheritanceHierarchyForType(db, working_files, parent_type);
|
||||
|
||||
parent_entries.push_back(parent_entry);
|
||||
});
|
||||
|
||||
return parent_entries;
|
||||
template <typename Q>
|
||||
bool ExpandHelper(MessageHandler* m,
|
||||
Out_CqueryInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool detailed_name,
|
||||
int levels,
|
||||
Q& entity) {
|
||||
const auto* def = entity.AnyDef();
|
||||
if (!def) {
|
||||
entry->numChildren = 0;
|
||||
return false;
|
||||
}
|
||||
if (detailed_name)
|
||||
entry->name = def->DetailedName(false);
|
||||
else
|
||||
entry->name = def->ShortName();
|
||||
if (def->spell) {
|
||||
if (optional<lsLocation> loc =
|
||||
GetLsLocation(m->db, m->working_files, *def->spell))
|
||||
entry->location = *loc;
|
||||
}
|
||||
if (derived) {
|
||||
entry->numChildren = int(entity.derived.size());
|
||||
if (levels > 0) {
|
||||
for (auto id : entity.derived) {
|
||||
Out_CqueryInheritanceHierarchy::Entry entry1;
|
||||
entry1.id = id;
|
||||
entry1.kind = entry->kind;
|
||||
if (Expand(m, &entry1, derived, detailed_name, levels - 1))
|
||||
entry->children.push_back(std::move(entry1));
|
||||
}
|
||||
entry->numChildren = int(entry->children.size());
|
||||
}
|
||||
} else {
|
||||
entry->numChildren = int(def->bases.size());
|
||||
if (levels > 0) {
|
||||
for (auto id : def->bases) {
|
||||
Out_CqueryInheritanceHierarchy::Entry entry1;
|
||||
entry1.id = id;
|
||||
entry1.kind = entry->kind;
|
||||
if (Expand(m, &entry1, derived, detailed_name, levels - 1))
|
||||
entry->children.push_back(std::move(entry1));
|
||||
}
|
||||
entry->numChildren = int(entry->children.size());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
optional<Out_CqueryInheritanceHierarchy::TypeEntry>
|
||||
BuildInheritanceHierarchyForType(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryType& root_type) {
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry entry;
|
||||
const QueryType::Def* def = root_type.AnyDef();
|
||||
|
||||
// Name and location.
|
||||
entry.name = def->detailed_name;
|
||||
if (def->spell)
|
||||
entry.location = GetLsLocation(db, working_files, *def->spell);
|
||||
|
||||
entry.children.reserve(root_type.derived.size());
|
||||
|
||||
// Base types.
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry base;
|
||||
base.name = "[[Base]]";
|
||||
base.location = entry.location;
|
||||
base.children =
|
||||
BuildParentInheritanceHierarchyForType(db, working_files, root_type);
|
||||
if (!base.children.empty())
|
||||
entry.children.push_back(base);
|
||||
|
||||
// Add derived.
|
||||
EachDefinedEntity(db->types, root_type.derived, [&](QueryType& type) {
|
||||
auto derived_entry =
|
||||
BuildInheritanceHierarchyForType(db, working_files, type);
|
||||
if (derived_entry)
|
||||
entry.children.push_back(*derived_entry);
|
||||
});
|
||||
|
||||
return entry;
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CqueryInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool detailed_name,
|
||||
int levels) {
|
||||
if (entry->kind == SymbolKind::Func)
|
||||
return ExpandHelper(m, entry, derived, detailed_name, levels,
|
||||
m->db->funcs[entry->id.id]);
|
||||
else
|
||||
return ExpandHelper(m, entry, derived, detailed_name, levels,
|
||||
m->db->types[entry->id.id]);
|
||||
}
|
||||
|
||||
std::vector<Out_CqueryInheritanceHierarchy::TypeEntry>
|
||||
BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryFuncId root) {
|
||||
std::vector<Out_CqueryInheritanceHierarchy::TypeEntry> entries;
|
||||
|
||||
QueryFunc& root_func = db->funcs[root.id];
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def || def->base.empty())
|
||||
return {};
|
||||
|
||||
for (auto parent_id : def->base) {
|
||||
QueryFunc& parent_func = db->funcs[parent_id.id];
|
||||
const QueryFunc::Def* def1 = parent_func.AnyDef();
|
||||
if (!def1)
|
||||
continue;
|
||||
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry parent_entry;
|
||||
parent_entry.name = def1->detailed_name;
|
||||
if (def1->spell)
|
||||
parent_entry.location = GetLsLocation(db, working_files, *def1->spell);
|
||||
parent_entry.children =
|
||||
BuildParentInheritanceHierarchyForFunc(db, working_files, parent_id);
|
||||
|
||||
entries.push_back(parent_entry);
|
||||
struct CqueryInheritanceHierarchyInitialHandler
|
||||
: BaseMessageHandler<Ipc_CqueryInheritanceHierarchyInitial> {
|
||||
optional<Out_CqueryInheritanceHierarchy::Entry>
|
||||
BuildInitial(SymbolRef sym, bool derived, bool detailed_name, int levels) {
|
||||
Out_CqueryInheritanceHierarchy::Entry entry;
|
||||
entry.id = sym.id;
|
||||
entry.kind = sym.kind;
|
||||
Expand(this, &entry, derived, detailed_name, levels);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
optional<Out_CqueryInheritanceHierarchy::TypeEntry>
|
||||
BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryFuncId root_id) {
|
||||
QueryFunc& root_func = db->funcs[root_id.id];
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def)
|
||||
return nullopt;
|
||||
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry entry;
|
||||
|
||||
// Name and location.
|
||||
entry.name = def->detailed_name;
|
||||
if (def->spell)
|
||||
entry.location = GetLsLocation(db, working_files, *def->spell);
|
||||
|
||||
entry.children.reserve(root_func.derived.size());
|
||||
|
||||
// Base types.
|
||||
Out_CqueryInheritanceHierarchy::TypeEntry base;
|
||||
base.name = "[[Base]]";
|
||||
base.location = entry.location;
|
||||
base.children =
|
||||
BuildParentInheritanceHierarchyForFunc(db, working_files, root_id);
|
||||
if (!base.children.empty())
|
||||
entry.children.push_back(base);
|
||||
|
||||
// Add derived.
|
||||
for (auto derived : root_func.derived) {
|
||||
auto derived_entry =
|
||||
BuildInheritanceHierarchyForFunc(db, working_files, derived);
|
||||
if (derived_entry)
|
||||
entry.children.push_back(*derived_entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
struct CqueryInheritanceHierarchyHandler
|
||||
: BaseMessageHandler<Ipc_CqueryInheritanceHierarchy> {
|
||||
void Run(Ipc_CqueryInheritanceHierarchy* request) override {
|
||||
void Run(Ipc_CqueryInheritanceHierarchyInitial* request) override {
|
||||
const auto& params = request->params;
|
||||
QueryFile* file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file))
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
|
||||
WorkingFile* working_file =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
Out_CqueryInheritanceHierarchy out;
|
||||
out.id = request->id;
|
||||
|
||||
for (const SymbolRef& sym :
|
||||
for (SymbolRef sym :
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.AnyDef())
|
||||
out.result =
|
||||
BuildInheritanceHierarchyForType(db, working_files, type);
|
||||
break;
|
||||
}
|
||||
if (sym.kind == SymbolKind::Func) {
|
||||
out.result = BuildInheritanceHierarchyForFunc(db, working_files,
|
||||
QueryFuncId(sym.id));
|
||||
if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) {
|
||||
out.result = BuildInitial(sym, params.derived, params.detailedName,
|
||||
params.levels);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QueueManager::WriteStdout(IpcId::CqueryInheritanceHierarchy, out);
|
||||
QueueManager::WriteStdout(IpcId::CqueryInheritanceHierarchyInitial, out);
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(CqueryInheritanceHierarchyHandler);
|
||||
REGISTER_MESSAGE_HANDLER(CqueryInheritanceHierarchyInitialHandler);
|
||||
|
||||
struct CqueryInheritanceHierarchyExpandHandler
|
||||
: BaseMessageHandler<Ipc_CqueryInheritanceHierarchyExpand> {
|
||||
void Run(Ipc_CqueryInheritanceHierarchyExpand* request) override {
|
||||
const auto& params = request->params;
|
||||
Out_CqueryInheritanceHierarchy out;
|
||||
out.id = request->id;
|
||||
if (params.id) {
|
||||
Out_CqueryInheritanceHierarchy::Entry entry;
|
||||
entry.id = *params.id;
|
||||
entry.kind = params.kind;
|
||||
if (((entry.kind == SymbolKind::Func && entry.id.id < db->funcs.size()) ||
|
||||
(entry.kind == SymbolKind::Type &&
|
||||
entry.id.id < db->types.size())) &&
|
||||
Expand(this, &entry, params.derived, params.detailedName,
|
||||
params.levels))
|
||||
out.result = std::move(entry);
|
||||
}
|
||||
|
||||
QueueManager::WriteStdout(IpcId::CqueryInheritanceHierarchyExpand, out);
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(CqueryInheritanceHierarchyExpandHandler);
|
||||
} // namespace
|
||||
|
@ -91,7 +91,9 @@ void Expand(MessageHandler* m,
|
||||
case CXType_Double: entry->name = "double"; break;
|
||||
case CXType_LongDouble: entry->name = "long double"; break;
|
||||
case CXType_Float128: entry->name = "__float128"; break;
|
||||
#if CINDEX_VERSION_MINOR >= 43
|
||||
case CXType_Half: entry->name = "_Float16"; break;
|
||||
#endif
|
||||
case CXType_NullPtr: entry->name = "nullptr"; break;
|
||||
// clang-format on
|
||||
}
|
||||
@ -104,24 +106,26 @@ void Expand(MessageHandler* m,
|
||||
entry->name = def->detailed_name;
|
||||
else
|
||||
entry->name = def->ShortName();
|
||||
if (def->spell) {
|
||||
if (optional<lsLocation> loc =
|
||||
GetLsLocation(m->db, m->working_files, *def->spell))
|
||||
entry->location = *loc;
|
||||
}
|
||||
entry->numChildren = int(def->vars.size());
|
||||
if (levels > 0) {
|
||||
EachDefinedEntity(m->db->vars, def->vars, [&](QueryVar& var) {
|
||||
const QueryVar::Def* def1 = var.AnyDef();
|
||||
Out_CqueryMemberHierarchy::Entry entry1;
|
||||
entry1.id = def1->type ? *def1->type : QueryTypeId();
|
||||
if (detailed_name)
|
||||
entry1.fieldName = def1->DetailedName(false);
|
||||
else
|
||||
entry1.fieldName = std::string(def1->ShortName());
|
||||
Expand(m, &entry1, detailed_name, levels - 1);
|
||||
entry->children.push_back(std::move(entry1));
|
||||
});
|
||||
const QueryVar::Def* def1 = var.AnyDef();
|
||||
if (!def1)
|
||||
return;
|
||||
Out_CqueryMemberHierarchy::Entry entry1;
|
||||
entry1.id = def1->type ? *def1->type : QueryTypeId();
|
||||
if (detailed_name)
|
||||
entry1.fieldName = def1->DetailedName(false);
|
||||
else
|
||||
entry1.fieldName = std::string(def1->ShortName());
|
||||
if (def1->spell) {
|
||||
if (optional<lsLocation> loc =
|
||||
GetLsLocation(m->db, m->working_files, *def1->spell))
|
||||
entry1.location = *loc;
|
||||
}
|
||||
Expand(m, &entry1, detailed_name, levels - 1);
|
||||
entry->children.push_back(std::move(entry1));
|
||||
});
|
||||
entry->numChildren = int(entry->children.size());
|
||||
}
|
||||
}
|
||||
@ -137,6 +141,11 @@ struct CqueryMemberHierarchyInitialHandler
|
||||
|
||||
Out_CqueryMemberHierarchy::Entry entry;
|
||||
entry.id = root_id;
|
||||
if (def->spell) {
|
||||
if (optional<lsLocation> loc =
|
||||
GetLsLocation(db, working_files, *def->spell))
|
||||
entry.location = *loc;
|
||||
}
|
||||
Expand(this, &entry, detailed_name, levels);
|
||||
return entry;
|
||||
}
|
||||
|
@ -213,9 +213,9 @@ struct TextDocumentCodeLensHandler
|
||||
GetDeclarations(db, func.derived), false /*force_display*/);
|
||||
|
||||
// "Base"
|
||||
if (def->base.size() == 1) {
|
||||
if (def->bases.size() == 1) {
|
||||
Maybe<Use> base_loc = GetDefinitionSpell(
|
||||
db, SymbolIdx{def->base[0], SymbolKind::Func});
|
||||
db, SymbolIdx{def->bases[0], SymbolKind::Func});
|
||||
if (base_loc) {
|
||||
optional<lsLocation> ls_base =
|
||||
GetLsLocation(db, working_files, *base_loc);
|
||||
@ -237,7 +237,7 @@ struct TextDocumentCodeLensHandler
|
||||
}
|
||||
} else {
|
||||
AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1),
|
||||
GetDeclarations(db, def->base), false /*force_display*/);
|
||||
GetDeclarations(db, def->bases), false /*force_display*/);
|
||||
}
|
||||
|
||||
break;
|
||||
|
11
src/query.cc
11
src/query.cc
@ -57,7 +57,7 @@ optional<QueryType::Def> ToQuery(const IdMap& id_map,
|
||||
result.spell = id_map.ToQuery(type.spell);
|
||||
result.extent = id_map.ToQuery(type.extent);
|
||||
result.alias_of = id_map.ToQuery(type.alias_of);
|
||||
result.parents = id_map.ToQuery(type.parents);
|
||||
result.bases = id_map.ToQuery(type.bases);
|
||||
result.types = id_map.ToQuery(type.types);
|
||||
result.funcs = id_map.ToQuery(type.funcs);
|
||||
result.vars = id_map.ToQuery(type.vars);
|
||||
@ -83,7 +83,7 @@ optional<QueryFunc::Def> ToQuery(const IdMap& id_map,
|
||||
result.spell = id_map.ToQuery(func.spell);
|
||||
result.extent = id_map.ToQuery(func.extent);
|
||||
result.declaring_type = id_map.ToQuery(func.declaring_type);
|
||||
result.base = id_map.ToQuery(func.base);
|
||||
result.bases = id_map.ToQuery(func.bases);
|
||||
result.locals = id_map.ToQuery(func.locals);
|
||||
result.callees = id_map.ToQuery(func.callees);
|
||||
return result;
|
||||
@ -947,11 +947,8 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
||||
return files[idx].def->path;
|
||||
break;
|
||||
case SymbolKind::Func:
|
||||
if (const auto* def = funcs[idx].AnyDef()) {
|
||||
// Assume the part after short_name is not needed.
|
||||
return std::string_view(def->detailed_name)
|
||||
.substr(0, def->short_name_offset + def->short_name_size);
|
||||
}
|
||||
if (const auto* def = funcs[idx].AnyDef())
|
||||
return def->DetailedName(false);
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
if (const auto* def = types[idx].AnyDef())
|
||||
|
@ -127,7 +127,7 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
if (!func.uses.empty())
|
||||
return true;
|
||||
if (auto* def = func.AnyDef()) {
|
||||
EachDefinedEntity(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
EachDefinedEntity(db->funcs, def->bases, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
stack.push(&func1);
|
||||
@ -156,7 +156,7 @@ std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
stack.pop();
|
||||
AddRange(&callers, func.uses);
|
||||
if (auto* def = func.AnyDef()) {
|
||||
EachDefinedEntity(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
EachDefinedEntity(db->funcs, def->bases, [&](QueryFunc& func1) {
|
||||
if (!seen.count(func1.usr)) {
|
||||
seen.insert(func1.usr);
|
||||
stack.push(&func1);
|
||||
|
@ -219,7 +219,7 @@ void Reflect(TVisitor& visitor, IndexType& value) {
|
||||
REFLECT_MEMBER2("spell", value.def.spell);
|
||||
REFLECT_MEMBER2("extent", value.def.extent);
|
||||
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
||||
REFLECT_MEMBER2("parents", value.def.parents);
|
||||
REFLECT_MEMBER2("bases", value.def.bases);
|
||||
REFLECT_MEMBER2("derived", value.derived);
|
||||
REFLECT_MEMBER2("types", value.def.types);
|
||||
REFLECT_MEMBER2("funcs", value.def.funcs);
|
||||
@ -243,7 +243,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) {
|
||||
REFLECT_MEMBER2("spell", value.def.spell);
|
||||
REFLECT_MEMBER2("extent", value.def.extent);
|
||||
REFLECT_MEMBER2("declaring_type", value.def.declaring_type);
|
||||
REFLECT_MEMBER2("base", value.def.base);
|
||||
REFLECT_MEMBER2("bases", value.def.bases);
|
||||
REFLECT_MEMBER2("derived", value.derived);
|
||||
REFLECT_MEMBER2("locals", value.def.locals);
|
||||
REFLECT_MEMBER2("uses", value.uses);
|
||||
|
Loading…
Reference in New Issue
Block a user