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