mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-22 16:39:48 +00:00
variable_type -> type; remove parent_{id,kind} (they should be inferred from Def::spell; clean up SymbolIdx, Reference, SymbolRef
This commit is contained in:
parent
0f8734c416
commit
aee79b3617
@ -620,7 +620,7 @@ void SetVarDetail(IndexVar* var,
|
|||||||
if (!is_enum_member)
|
if (!is_enum_member)
|
||||||
db->Resolve(var_type.value())->instances.push_back(var->id);
|
db->Resolve(var_type.value())->instances.push_back(var->id);
|
||||||
|
|
||||||
def.variable_type = *var_type;
|
def.type = *var_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,7 +658,7 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
const int IndexFile::kMajorVersion = 12;
|
const int IndexFile::kMajorVersion = 12;
|
||||||
const int IndexFile::kMinorVersion = 0;
|
const int IndexFile::kMinorVersion = 1;
|
||||||
|
|
||||||
IndexFile::IndexFile(const std::string& path, const std::string& contents)
|
IndexFile::IndexFile(const std::string& path, const std::string& contents)
|
||||||
: id_cache(path), path(path), file_contents(contents) {}
|
: id_cache(path), path(path), file_contents(contents) {}
|
||||||
@ -1553,7 +1553,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// the function declaration is encountered since we won't receive ParmDecl
|
// the function declaration is encountered since we won't receive ParmDecl
|
||||||
// declarations for unnamed parameters.
|
// declarations for unnamed parameters.
|
||||||
// TODO: See if we can remove this function call.
|
// TODO: See if we can remove this function call.
|
||||||
AddDeclTypeUsages(db, decl_cursor, var->def.variable_type,
|
AddDeclTypeUsages(db, decl_cursor, var->def.type,
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
// We don't need to assign declaring type multiple times if this variable
|
// We don't need to assign declaring type multiple times if this variable
|
||||||
@ -1563,18 +1563,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
switch (GetSymbolKind(decl->semanticContainer->cursor.kind)) {
|
switch (GetSymbolKind(decl->semanticContainer->cursor.kind)) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Func: {
|
|
||||||
IndexFuncId parent_func_id =
|
|
||||||
db->ToFuncId(decl->semanticContainer->cursor);
|
|
||||||
var->def.parent_kind = SymbolKind::Func;
|
|
||||||
var->def.parent_id = Id<void>(parent_func_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
IndexTypeId parent_type_id =
|
IndexTypeId parent_type_id =
|
||||||
db->ToTypeId(decl->semanticContainer->cursor);
|
db->ToTypeId(decl->semanticContainer->cursor);
|
||||||
var->def.parent_kind = SymbolKind::Type;
|
|
||||||
var->def.parent_id = Id<void>(parent_type_id);
|
|
||||||
db->Resolve(parent_type_id)->def.vars.push_back(var_id);
|
db->Resolve(parent_type_id)->def.vars.push_back(var_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,23 @@ using IndexVarId = Id<IndexVar>;
|
|||||||
|
|
||||||
struct IdCache;
|
struct IdCache;
|
||||||
|
|
||||||
|
struct SymbolIdx {
|
||||||
|
Id<void> id;
|
||||||
|
SymbolKind kind;
|
||||||
|
|
||||||
|
bool operator==(const SymbolIdx& o) const {
|
||||||
|
return id == o.id && kind == o.kind;
|
||||||
|
}
|
||||||
|
bool operator!=(const SymbolIdx& o) const { return !(*this == o); }
|
||||||
|
bool operator<(const SymbolIdx& o) const {
|
||||||
|
if (id != o.id)
|
||||||
|
return id < o.id;
|
||||||
|
return kind < o.kind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(SymbolIdx, kind, id);
|
||||||
|
MAKE_HASHABLE(SymbolIdx, t.kind, t.id);
|
||||||
|
|
||||||
struct Reference {
|
struct Reference {
|
||||||
Range range;
|
Range range;
|
||||||
Id<void> id;
|
Id<void> id;
|
||||||
@ -96,6 +113,7 @@ struct Reference {
|
|||||||
Role role;
|
Role role;
|
||||||
|
|
||||||
bool HasValue() const { return range.HasValue(); }
|
bool HasValue() const { return range.HasValue(); }
|
||||||
|
operator SymbolIdx() const { return {id, kind}; }
|
||||||
std::tuple<Range, Id<void>, SymbolKind, Role> ToTuple() const {
|
std::tuple<Range, Id<void>, SymbolKind, Role> ToTuple() const {
|
||||||
return std::make_tuple(range, id, kind, role);
|
return std::make_tuple(range, id, kind, role);
|
||||||
}
|
}
|
||||||
@ -107,34 +125,15 @@ struct Reference {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SymbolIdx {
|
|
||||||
RawId idx;
|
|
||||||
SymbolKind kind;
|
|
||||||
|
|
||||||
bool operator==(const SymbolIdx& o) const {
|
|
||||||
return kind == o.kind && idx == o.idx;
|
|
||||||
}
|
|
||||||
bool operator!=(const SymbolIdx& o) const { return !(*this == o); }
|
|
||||||
bool operator<(const SymbolIdx& o) const {
|
|
||||||
if (kind != o.kind)
|
|
||||||
return kind < o.kind;
|
|
||||||
return idx < o.idx;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
|
|
||||||
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
|
|
||||||
|
|
||||||
// |id,kind| refer to the referenced entity.
|
// |id,kind| refer to the referenced entity.
|
||||||
struct SymbolRef : Reference {
|
struct SymbolRef : Reference {
|
||||||
SymbolRef() = default;
|
SymbolRef() = default;
|
||||||
SymbolRef(Range range, Id<void> id, SymbolKind kind, Role role)
|
SymbolRef(Range range, Id<void> id, SymbolKind kind, Role role)
|
||||||
: Reference{range, id, kind, role} {}
|
: Reference{range, id, kind, role} {}
|
||||||
SymbolRef(Reference ref) : Reference(ref) {}
|
SymbolRef(Reference ref) : Reference(ref) {}
|
||||||
|
// FIXME Remove
|
||||||
SymbolRef(SymbolIdx si)
|
SymbolRef(SymbolIdx si)
|
||||||
: Reference{Range(), Id<void>(si.idx), si.kind, Role::None} {}
|
: Reference{Range(), si.id, si.kind, Role::None} {}
|
||||||
|
|
||||||
RawId Idx() const { return RawId(id); }
|
|
||||||
operator SymbolIdx() const { return SymbolIdx{Idx(), kind}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical
|
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical
|
||||||
@ -378,13 +377,11 @@ struct VarDefDefinitionData {
|
|||||||
|
|
||||||
typename F::FileId file;
|
typename F::FileId file;
|
||||||
// Type of the variable.
|
// Type of the variable.
|
||||||
Maybe<typename F::TypeId> variable_type;
|
Maybe<typename F::TypeId> type;
|
||||||
|
|
||||||
// Function/type which declares this one.
|
// Function/type which declares this one.
|
||||||
Maybe<Id<void>> parent_id;
|
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
SymbolKind parent_kind = SymbolKind::Invalid;
|
|
||||||
|
|
||||||
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
ClangSymbolKind kind = ClangSymbolKind::Unknown;
|
||||||
// Note a variable may have instances of both |None| and |Extern|
|
// Note a variable may have instances of both |None| and |Extern|
|
||||||
@ -398,16 +395,12 @@ struct VarDefDefinitionData {
|
|||||||
bool is_macro() const { return kind == ClangSymbolKind::Macro; }
|
bool is_macro() const { return kind == ClangSymbolKind::Macro; }
|
||||||
|
|
||||||
bool operator==(const VarDefDefinitionData& o) const {
|
bool operator==(const VarDefDefinitionData& o) const {
|
||||||
return detailed_name == o.detailed_name &&
|
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||||
spell == o.spell &&
|
extent == o.extent && type == o.type &&
|
||||||
extent == o.extent &&
|
kind == o.kind && storage == o.storage && hover == o.hover &&
|
||||||
variable_type == o.variable_type && parent_id == o.parent_id &&
|
comments == o.comments;
|
||||||
parent_kind == o.parent_kind && kind == o.kind &&
|
|
||||||
storage == o.storage && hover == o.hover && comments == o.comments;
|
|
||||||
}
|
|
||||||
bool operator!=(const VarDefDefinitionData& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
}
|
||||||
|
bool operator!=(const VarDefDefinitionData& o) const { return !(*this == o); }
|
||||||
|
|
||||||
std::string_view ShortName() const {
|
std::string_view ShortName() const {
|
||||||
return std::string_view(detailed_name.c_str() + short_name_offset,
|
return std::string_view(detailed_name.c_str() + short_name_offset,
|
||||||
@ -426,9 +419,7 @@ void Reflect(TVisitor& visitor, VarDefDefinitionData<Family>& value) {
|
|||||||
REFLECT_MEMBER(spell);
|
REFLECT_MEMBER(spell);
|
||||||
REFLECT_MEMBER(extent);
|
REFLECT_MEMBER(extent);
|
||||||
REFLECT_MEMBER(file);
|
REFLECT_MEMBER(file);
|
||||||
REFLECT_MEMBER(variable_type);
|
REFLECT_MEMBER(type);
|
||||||
REFLECT_MEMBER(parent_id);
|
|
||||||
REFLECT_MEMBER(parent_kind);
|
|
||||||
REFLECT_MEMBER(kind);
|
REFLECT_MEMBER(kind);
|
||||||
REFLECT_MEMBER(storage);
|
REFLECT_MEMBER(storage);
|
||||||
REFLECT_MEMBER_END();
|
REFLECT_MEMBER_END();
|
||||||
|
@ -151,7 +151,6 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
|||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (!var.def)
|
if (!var.def)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
parent_kind = var.def->parent_kind;
|
|
||||||
kind = var.def->kind;
|
kind = var.def->kind;
|
||||||
storage = var.def->storage;
|
storage = var.def->storage;
|
||||||
detailed_name = var.def->ShortName();
|
detailed_name = var.def->ShortName();
|
||||||
@ -171,8 +170,7 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
|||||||
|
|
||||||
optional<lsRange> loc = GetLsRange(working_file, sym.range);
|
optional<lsRange> loc = GetLsRange(working_file, sym.range);
|
||||||
if (loc) {
|
if (loc) {
|
||||||
auto key = SymbolIdx{RawId(sym.id), sym.kind};
|
auto it = grouped_symbols.find(sym);
|
||||||
auto it = grouped_symbols.find(key);
|
|
||||||
if (it != grouped_symbols.end()) {
|
if (it != grouped_symbols.end()) {
|
||||||
it->second.ranges.push_back(*loc);
|
it->second.ranges.push_back(*loc);
|
||||||
} else {
|
} else {
|
||||||
@ -183,7 +181,7 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
|||||||
symbol.kind = kind;
|
symbol.kind = kind;
|
||||||
symbol.storage = storage;
|
symbol.storage = storage;
|
||||||
symbol.ranges.push_back(*loc);
|
symbol.ranges.push_back(*loc);
|
||||||
grouped_symbols[key] = symbol;
|
grouped_symbols[sym] = symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ struct CqueryCallTreeInitialHandler
|
|||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (sym.kind == SymbolKind::Func) {
|
if (sym.kind == SymbolKind::Func) {
|
||||||
out.result =
|
out.result =
|
||||||
BuildInitialCallTree(db, working_files, QueryFuncId(sym.Idx()));
|
BuildInitialCallTree(db, working_files, QueryFuncId(sym.id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ struct Ipc_CqueryMemberHierarchyExpand
|
|||||||
: public RequestMessage<Ipc_CqueryMemberHierarchyExpand> {
|
: public RequestMessage<Ipc_CqueryMemberHierarchyExpand> {
|
||||||
const static IpcId kIpcId = IpcId::CqueryMemberHierarchyExpand;
|
const static IpcId kIpcId = IpcId::CqueryMemberHierarchyExpand;
|
||||||
struct Params {
|
struct Params {
|
||||||
size_t type_id;
|
QueryTypeId type_id;
|
||||||
};
|
};
|
||||||
Params params;
|
Params params;
|
||||||
};
|
};
|
||||||
@ -27,8 +27,7 @@ struct Out_CqueryMemberHierarchy
|
|||||||
: public lsOutMessage<Out_CqueryMemberHierarchy> {
|
: public lsOutMessage<Out_CqueryMemberHierarchy> {
|
||||||
struct Entry {
|
struct Entry {
|
||||||
std::string_view name;
|
std::string_view name;
|
||||||
// FIXME Usr
|
QueryTypeId type_id;
|
||||||
RawId type_id;
|
|
||||||
lsLocation location;
|
lsLocation location;
|
||||||
};
|
};
|
||||||
lsRequestId id;
|
lsRequestId id;
|
||||||
@ -48,7 +47,7 @@ BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
Out_CqueryMemberHierarchy::Entry entry;
|
Out_CqueryMemberHierarchy::Entry entry;
|
||||||
entry.type_id = root.id;
|
entry.type_id = root;
|
||||||
entry.name = root_type.def->ShortName();
|
entry.name = root_type.def->ShortName();
|
||||||
entry.location = *def_loc;
|
entry.location = *def_loc;
|
||||||
return {entry};
|
return {entry};
|
||||||
@ -64,9 +63,7 @@ ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
|
|||||||
EachWithGen(db->vars, root_type.def->vars, [&](QueryVar& var) {
|
EachWithGen(db->vars, root_type.def->vars, [&](QueryVar& var) {
|
||||||
Out_CqueryMemberHierarchy::Entry entry;
|
Out_CqueryMemberHierarchy::Entry entry;
|
||||||
entry.name = var.def->ShortName();
|
entry.name = var.def->ShortName();
|
||||||
// FIXME WithGen
|
entry.type_id = var.def->type ? *var.def->type : QueryTypeId();
|
||||||
entry.type_id =
|
|
||||||
var.def->variable_type ? var.def->variable_type->id : RawId(-1);
|
|
||||||
if (var.def->spell) {
|
if (var.def->spell) {
|
||||||
optional<lsLocation> loc =
|
optional<lsLocation> loc =
|
||||||
GetLsLocation(db, working_files, *var.def->spell);
|
GetLsLocation(db, working_files, *var.def->spell);
|
||||||
@ -95,13 +92,13 @@ struct CqueryMemberHierarchyInitialHandler
|
|||||||
for (const SymbolRef& sym :
|
for (const 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::Type) {
|
||||||
out.result = BuildInitial(db, working_files, QueryTypeId(sym.Idx()));
|
out.result = BuildInitial(db, working_files, QueryTypeId(sym.id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sym.kind == SymbolKind::Var) {
|
if (sym.kind == SymbolKind::Var) {
|
||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (var.def && var.def->variable_type)
|
if (var.def && var.def->type)
|
||||||
out.result = BuildInitial(db, working_files, *var.def->variable_type);
|
out.result = BuildInitial(db, working_files, *var.def->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,9 +114,8 @@ struct CqueryMemberHierarchyExpandHandler
|
|||||||
Out_CqueryMemberHierarchy out;
|
Out_CqueryMemberHierarchy out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
// |ExpandNode| uses -1 to indicate invalid |type_id|.
|
// |ExpandNode| uses -1 to indicate invalid |type_id|.
|
||||||
if (request->params.type_id != size_t(-1))
|
if (request->params.type_id.HasValue())
|
||||||
out.result =
|
out.result = ExpandNode(db, working_files, request->params.type_id);
|
||||||
ExpandNode(db, working_files, QueryTypeId(request->params.type_id));
|
|
||||||
|
|
||||||
QueueManager::WriteStdout(IpcId::CqueryMemberHierarchyExpand, out);
|
QueueManager::WriteStdout(IpcId::CqueryMemberHierarchyExpand, out);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ void Add(const std::unordered_map<SymbolIdx, int>& sym2id,
|
|||||||
int n,
|
int n,
|
||||||
double w = 1) {
|
double w = 1) {
|
||||||
for (Id<Q> id : ids) {
|
for (Id<Q> id : ids) {
|
||||||
auto it = sym2id.find(SymbolIdx{RawId(id), Kind<Q>::value});
|
auto it = sym2id.find(SymbolIdx{id, Kind<Q>::value});
|
||||||
if (it != sym2id.end())
|
if (it != sym2id.end())
|
||||||
adj[it->second][n] += w;
|
adj[it->second][n] += w;
|
||||||
}
|
}
|
||||||
@ -47,24 +47,24 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
|||||||
|
|
||||||
for (RawId i = 0; i < db->funcs.size(); i++)
|
for (RawId i = 0; i < db->funcs.size(); i++)
|
||||||
if (db->funcs[i].def) {
|
if (db->funcs[i].def) {
|
||||||
syms.push_back(SymbolIdx{i, SymbolKind::Func});
|
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Func});
|
||||||
sym2id[syms.back()] = n++;
|
sym2id[syms.back()] = n++;
|
||||||
}
|
}
|
||||||
for (RawId i = 0; i < db->types.size(); i++)
|
for (RawId i = 0; i < db->types.size(); i++)
|
||||||
if (db->types[i].def) {
|
if (db->types[i].def) {
|
||||||
syms.push_back(SymbolIdx{i, SymbolKind::Type});
|
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Type});
|
||||||
sym2id[syms.back()] = n++;
|
sym2id[syms.back()] = n++;
|
||||||
}
|
}
|
||||||
for (RawId i = 0; i < db->vars.size(); i++)
|
for (RawId i = 0; i < db->vars.size(); i++)
|
||||||
if (db->vars[i].def) {
|
if (db->vars[i].def) {
|
||||||
syms.push_back(SymbolIdx{i, SymbolKind::Var});
|
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Var});
|
||||||
sym2id[syms.back()] = n++;
|
sym2id[syms.back()] = n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unordered_map<int, double>> adj(n);
|
std::vector<std::unordered_map<int, double>> adj(n);
|
||||||
auto add = [&](const std::vector<Use>& uses, double w) {
|
auto add = [&](const std::vector<Use>& uses, double w) {
|
||||||
for (Use use : uses) {
|
for (Use use : uses) {
|
||||||
auto it = sym2id.find(SymbolIdx{RawId(use.id), use.kind});
|
auto it = sym2id.find(use);
|
||||||
if (it != sym2id.end())
|
if (it != sym2id.end())
|
||||||
adj[it->second][n] += w;
|
adj[it->second][n] += w;
|
||||||
}
|
}
|
||||||
|
@ -25,19 +25,19 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
|||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
for (SymbolRef sym :
|
for (SymbolRef sym :
|
||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
RawId idx = sym.Idx();
|
Id<void> id = sym.id;
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (!var.def || !var.def->variable_type)
|
if (!var.def || !var.def->type)
|
||||||
continue;
|
continue;
|
||||||
idx = var.def->variable_type->id;
|
id = *var.def->type;
|
||||||
}
|
}
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[idx];
|
QueryType& type = db->types[id.id];
|
||||||
out.result =
|
out.result =
|
||||||
GetLsLocations(db, working_files, ToUses(db, type.instances));
|
GetLsLocations(db, working_files, ToUses(db, type.instances));
|
||||||
break;
|
break;
|
||||||
|
@ -32,10 +32,9 @@ std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
|
|||||||
std::vector<Use> ret =
|
std::vector<Use> ret =
|
||||||
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||||
QueryVar& var = db->GetVar(sym);
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (var.def && var.def->variable_type) {
|
if (var.def && var.def->type) {
|
||||||
std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
|
std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
|
||||||
db, SymbolRef(Range(), Id<void>(var.def->variable_type->id),
|
db, SymbolIdx{*var.def->type, SymbolKind::Type});
|
||||||
SymbolKind::Type, Role::None));
|
|
||||||
ret.insert(ret.end(), types.begin(), types.end());
|
ret.insert(ret.end(), types.begin(), types.end());
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -9,7 +9,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
|||||||
SymbolRef sym) {
|
SymbolRef sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[sym.Idx()];
|
QueryType& type = db->GetType(sym);
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return {type.def->comments,
|
return {type.def->comments,
|
||||||
!type.def->hover.empty()
|
!type.def->hover.empty()
|
||||||
@ -18,7 +18,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc& func = db->funcs[sym.Idx()];
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
if (func.def)
|
if (func.def)
|
||||||
return {func.def->comments,
|
return {func.def->comments,
|
||||||
!func.def->hover.empty()
|
!func.def->hover.empty()
|
||||||
@ -27,7 +27,7 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[sym.Idx()];
|
QueryVar& var = db->GetVar(sym);
|
||||||
if (var.def)
|
if (var.def)
|
||||||
return {var.def->comments,
|
return {var.def->comments,
|
||||||
!var.def->hover.empty()
|
!var.def->hover.empty()
|
||||||
|
38
src/query.cc
38
src/query.cc
@ -95,25 +95,7 @@ optional<QueryVar::Def> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
|
|||||||
result.file = id_map.primary_file;
|
result.file = id_map.primary_file;
|
||||||
result.spell = id_map.ToQuery(var.spell);
|
result.spell = id_map.ToQuery(var.spell);
|
||||||
result.extent = id_map.ToQuery(var.extent);
|
result.extent = id_map.ToQuery(var.extent);
|
||||||
result.variable_type = id_map.ToQuery(var.variable_type);
|
result.type = id_map.ToQuery(var.type);
|
||||||
if (result.parent_id)
|
|
||||||
switch (var.parent_kind) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case SymbolKind::File:
|
|
||||||
result.parent_id = Id<void>(id_map.primary_file);
|
|
||||||
break;
|
|
||||||
case SymbolKind::Func:
|
|
||||||
result.parent_id = Id<void>(id_map.ToQuery(IndexFuncId(*var.parent_id)));
|
|
||||||
break;
|
|
||||||
case SymbolKind::Type:
|
|
||||||
result.parent_id = Id<void>(id_map.ToQuery(IndexTypeId(*var.parent_id)));
|
|
||||||
break;
|
|
||||||
case SymbolKind::Var:
|
|
||||||
result.parent_id = Id<void>(id_map.ToQuery(IndexVarId(*var.parent_id)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result.parent_kind = var.parent_kind;
|
|
||||||
result.kind = var.kind;
|
result.kind = var.kind;
|
||||||
result.storage = var.storage;
|
result.storage = var.storage;
|
||||||
return result;
|
return result;
|
||||||
@ -871,8 +853,7 @@ void QueryDatabase::ImportOrUpdate(
|
|||||||
QueryFile& existing = files[it->second.id];
|
QueryFile& existing = files[it->second.id];
|
||||||
|
|
||||||
existing.def = def.value;
|
existing.def = def.value;
|
||||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::File,
|
UpdateSymbols(&existing.symbol_idx, SymbolKind::File, it->second);
|
||||||
it->second.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,8 +874,7 @@ void QueryDatabase::ImportOrUpdate(
|
|||||||
if (!(existing.def && existing.def->spell &&
|
if (!(existing.def && existing.def->spell &&
|
||||||
!def.value.spell)) {
|
!def.value.spell)) {
|
||||||
existing.def = std::move(def.value);
|
existing.def = std::move(def.value);
|
||||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type,
|
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, it->second);
|
||||||
it->second.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -916,8 +896,7 @@ void QueryDatabase::ImportOrUpdate(
|
|||||||
if (!(existing.def && existing.def->spell &&
|
if (!(existing.def && existing.def->spell &&
|
||||||
!def.value.spell)) {
|
!def.value.spell)) {
|
||||||
existing.def = std::move(def.value);
|
existing.def = std::move(def.value);
|
||||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func,
|
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, it->second);
|
||||||
it->second.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -939,15 +918,14 @@ void QueryDatabase::ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates) {
|
|||||||
!def.value.spell)) {
|
!def.value.spell)) {
|
||||||
existing.def = std::move(def.value);
|
existing.def = std::move(def.value);
|
||||||
if (!def.value.is_local())
|
if (!def.value.is_local())
|
||||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var,
|
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second);
|
||||||
it->second.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueryDatabase::UpdateSymbols(Maybe<Id<void>>* symbol_idx,
|
void QueryDatabase::UpdateSymbols(Maybe<Id<void>>* symbol_idx,
|
||||||
SymbolKind kind,
|
SymbolKind kind,
|
||||||
RawId idx) {
|
Id<void> idx) {
|
||||||
if (!symbol_idx->has_value()) {
|
if (!symbol_idx->has_value()) {
|
||||||
*symbol_idx = Id<void>(symbols.size());
|
*symbol_idx = Id<void>(symbols.size());
|
||||||
symbols.push_back(SymbolIdx{idx, kind});
|
symbols.push_back(SymbolIdx{idx, kind});
|
||||||
@ -955,7 +933,7 @@ void QueryDatabase::UpdateSymbols(Maybe<Id<void>>* symbol_idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
||||||
RawId idx = symbols[symbol_idx].idx;
|
RawId idx = symbols[symbol_idx].id.id;
|
||||||
switch (symbols[symbol_idx].kind) {
|
switch (symbols[symbol_idx].kind) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -980,7 +958,7 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const {
|
std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const {
|
||||||
RawId idx = symbols[symbol_idx].idx;
|
RawId idx = symbols[symbol_idx].id.id;
|
||||||
switch (symbols[symbol_idx].kind) {
|
switch (symbols[symbol_idx].kind) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
12
src/query.h
12
src/query.h
@ -280,7 +280,7 @@ struct QueryDatabase {
|
|||||||
void ImportOrUpdate(std::vector<QueryType::DefUpdate>&& updates);
|
void ImportOrUpdate(std::vector<QueryType::DefUpdate>&& updates);
|
||||||
void ImportOrUpdate(std::vector<QueryFunc::DefUpdate>&& updates);
|
void ImportOrUpdate(std::vector<QueryFunc::DefUpdate>&& updates);
|
||||||
void ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates);
|
void ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates);
|
||||||
void UpdateSymbols(Maybe<Id<void>>* symbol_idx, SymbolKind kind, RawId idx);
|
void UpdateSymbols(Maybe<Id<void>>* symbol_idx, SymbolKind kind, Id<void> idx);
|
||||||
std::string_view GetSymbolDetailedName(RawId symbol_idx) const;
|
std::string_view GetSymbolDetailedName(RawId symbol_idx) const;
|
||||||
std::string_view GetSymbolShortName(RawId symbol_idx) const;
|
std::string_view GetSymbolShortName(RawId symbol_idx) const;
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ struct QueryDatabase {
|
|||||||
Maybe<QueryFuncId> GetQueryFuncIdFromUsr(Usr usr);
|
Maybe<QueryFuncId> GetQueryFuncIdFromUsr(Usr usr);
|
||||||
Maybe<QueryVarId> GetQueryVarIdFromUsr(Usr usr);
|
Maybe<QueryVarId> GetQueryVarIdFromUsr(Usr usr);
|
||||||
|
|
||||||
QueryFileId GetFileId(Reference ref) {
|
QueryFileId GetFileId(SymbolIdx ref) {
|
||||||
switch (ref.kind) {
|
switch (ref.kind) {
|
||||||
case SymbolKind::Invalid:
|
case SymbolKind::Invalid:
|
||||||
break;
|
break;
|
||||||
@ -317,16 +317,16 @@ struct QueryDatabase {
|
|||||||
}
|
}
|
||||||
return QueryFileId();
|
return QueryFileId();
|
||||||
}
|
}
|
||||||
QueryFile& GetFile(Reference ref) {
|
QueryFile& GetFile(SymbolIdx ref) {
|
||||||
return files[ref.id.id];
|
return files[ref.id.id];
|
||||||
}
|
}
|
||||||
QueryFunc& GetFunc(Reference ref) {
|
QueryFunc& GetFunc(SymbolIdx ref) {
|
||||||
return funcs[ref.id.id];
|
return funcs[ref.id.id];
|
||||||
}
|
}
|
||||||
QueryType& GetType(Reference ref) {
|
QueryType& GetType(SymbolIdx ref) {
|
||||||
return types[ref.id.id];
|
return types[ref.id.id];
|
||||||
}
|
}
|
||||||
QueryVar& GetVar(Reference ref) {
|
QueryVar& GetVar(SymbolIdx ref) {
|
||||||
return vars[ref.id.id];
|
return vars[ref.id.id];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym) {
|
SymbolIdx sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
@ -56,7 +56,7 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolRef sym) {
|
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
@ -77,7 +77,8 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolRef sym) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
return Use(Reference(sym));
|
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
||||||
|
Role::None);
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
break;
|
break;
|
||||||
@ -87,7 +88,7 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolRef sym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym) {
|
SymbolIdx sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->GetType(sym);
|
QueryType& type = db->GetType(sym);
|
||||||
@ -110,7 +111,7 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
return QueryFileId(sym.Idx());
|
return QueryFileId(sym.id);
|
||||||
case SymbolKind::Invalid: {
|
case SymbolKind::Invalid: {
|
||||||
assert(false && "unexpected");
|
assert(false && "unexpected");
|
||||||
break;
|
break;
|
||||||
@ -159,29 +160,28 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym,
|
SymbolIdx sym,
|
||||||
bool include_decl) {
|
bool include_decl) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[sym.Idx()];
|
QueryType& type = db->GetType(sym);
|
||||||
std::vector<Use> ret = type.uses;
|
std::vector<Use> ret = type.uses;
|
||||||
if (include_decl && type.def && type.def->spell)
|
if (include_decl && type.def && type.def->spell)
|
||||||
ret.push_back(*type.def->spell);
|
ret.push_back(*type.def->spell);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
// TODO: the vector allocation could be avoided.
|
QueryFunc& func = db->GetFunc(sym);
|
||||||
QueryFunc& func = db->funcs[sym.Idx()];
|
|
||||||
std::vector<Use> ret = func.uses;
|
std::vector<Use> ret = func.uses;
|
||||||
if (include_decl) {
|
if (include_decl) {
|
||||||
AddRange(&ret, func.declarations);
|
|
||||||
if (func.def && func.def->spell)
|
if (func.def && func.def->spell)
|
||||||
ret.push_back(*func.def->spell);
|
ret.push_back(*func.def->spell);
|
||||||
|
AddRange(&ret, func.declarations);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[sym.Idx()];
|
QueryVar& var = db->GetVar(sym);
|
||||||
std::vector<Use> ret = var.uses;
|
std::vector<Use> ret = var.uses;
|
||||||
if (include_decl) {
|
if (include_decl) {
|
||||||
if (var.def && var.def->spell)
|
if (var.def && var.def->spell)
|
||||||
@ -200,7 +200,7 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
|||||||
|
|
||||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
SymbolRef sym) {
|
SymbolIdx sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
// Returning the definition spelling of a type is a hack (and is why the
|
// Returning the definition spelling of a type is a hack (and is why the
|
||||||
@ -447,11 +447,11 @@ std::vector<lsLocation> GetLsLocations(
|
|||||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolRef sym,
|
SymbolIdx sym,
|
||||||
bool use_short_name) {
|
bool use_short_name) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::File: {
|
case SymbolKind::File: {
|
||||||
QueryFile& file = db->files[sym.Idx()];
|
QueryFile& file = db->GetFile(sym);
|
||||||
if (!file.def)
|
if (!file.def)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -568,7 +568,7 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|||||||
int t = static_cast<int>(a.kind) - static_cast<int>(b.kind);
|
int t = static_cast<int>(a.kind) - static_cast<int>(b.kind);
|
||||||
if (t)
|
if (t)
|
||||||
return t > 0;
|
return t > 0;
|
||||||
return a.Idx() < b.Idx();
|
return a.id < b.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
return symbols;
|
return symbols;
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
QueryFuncId id);
|
QueryFuncId id);
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym);
|
SymbolIdx sym);
|
||||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolRef sym);
|
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym);
|
||||||
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym);
|
SymbolIdx sym);
|
||||||
|
|
||||||
std::vector<Use> ToUses(QueryDatabase* db,
|
std::vector<Use> ToUses(QueryDatabase* db,
|
||||||
const std::vector<QueryFuncId>& ids);
|
const std::vector<QueryFuncId>& ids);
|
||||||
@ -23,11 +23,11 @@ std::vector<Use> ToUses(QueryDatabase* db,
|
|||||||
const std::vector<QueryVarId>& ids);
|
const std::vector<QueryVarId>& ids);
|
||||||
|
|
||||||
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
|
||||||
SymbolRef sym,
|
SymbolIdx sym,
|
||||||
bool include_decl);
|
bool include_decl);
|
||||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
SymbolRef sym);
|
SymbolIdx sym);
|
||||||
|
|
||||||
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
|
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
|
||||||
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||||
@ -55,7 +55,7 @@ std::vector<lsLocation> GetLsLocations(QueryDatabase* db,
|
|||||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolRef sym,
|
SymbolIdx sym,
|
||||||
bool use_short_name);
|
bool use_short_name);
|
||||||
|
|
||||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||||
|
@ -252,10 +252,8 @@ void Reflect(TVisitor& visitor, IndexVar& value) {
|
|||||||
REFLECT_MEMBER2("declarations", value.declarations);
|
REFLECT_MEMBER2("declarations", value.declarations);
|
||||||
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("variable_type", value.def.variable_type);
|
REFLECT_MEMBER2("type", value.def.type);
|
||||||
REFLECT_MEMBER2("uses", value.uses);
|
REFLECT_MEMBER2("uses", value.uses);
|
||||||
REFLECT_MEMBER2("parent_id", value.def.parent_id);
|
|
||||||
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
|
|
||||||
REFLECT_MEMBER2("kind", value.def.kind);
|
REFLECT_MEMBER2("kind", value.def.kind);
|
||||||
REFLECT_MEMBER2("storage", value.def.storage);
|
REFLECT_MEMBER2("storage", value.def.storage);
|
||||||
REFLECT_MEMBER_END();
|
REFLECT_MEMBER_END();
|
||||||
|
Loading…
Reference in New Issue
Block a user