Change optional<...> Query{Func,Type}::Def to forward_list

This commit is contained in:
Fangrui Song 2018-02-17 23:09:05 -08:00
parent cfdb6bf422
commit 0f03146daa
11 changed files with 175 additions and 159 deletions

View File

@ -117,16 +117,16 @@ void EmitSemanticHighlighting(QueryDatabase* db,
// This switch statement also filters out symbols that are not highlighted.
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (!func.def)
const QueryFunc::Def* def = db->GetFunc(sym).AnyDef();
if (!def)
continue; // applies to for loop
// Don't highlight overloadable operators or implicit lambda ->
// std::function constructor.
std::string_view short_name = func.def->ShortName();
std::string_view short_name = def->ShortName();
if (short_name.compare(0, 8, "operator") == 0 ||
short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
continue; // applies to for loop
kind = func.def->kind;
kind = def->kind;
detailed_name = short_name;
// Check whether the function name is actually there.

View File

@ -35,16 +35,14 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
});
for (SymbolRef sym : syms) {
if (sym.kind == SymbolKind::Type) {
QueryType& type = db->GetType(sym);
if (type.def)
if (const auto* def = db->GetType(sym).AnyDef())
out.result = GetLsLocations(db, working_files,
ToUses(db, type.def->parents));
ToUses(db, def->parents));
break;
} else if (sym.kind == SymbolKind::Func) {
QueryFunc& func = db->GetFunc(sym);
if (func.def)
if (const auto* def = db->GetFunc(sym).AnyDef())
out.result = GetLsLocations(db, working_files,
ToUses(db, func.def->base));
ToUses(db, def->base));
break;
}
}

View File

@ -53,15 +53,16 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
WorkingFiles* working_files,
QueryFuncId root) {
QueryFunc& root_func = db->funcs[root.id];
if (!root_func.def || !root_func.def->spell)
const QueryFunc::Def* def = root_func.AnyDef();
if (!def || !def->spell)
return {};
optional<lsLocation> def_loc =
GetLsLocation(db, working_files, *root_func.def->spell);
GetLsLocation(db, working_files, *def->spell);
if (!def_loc)
return {};
Out_CqueryCallTree::CallEntry entry;
entry.name = root_func.def->ShortName();
entry.name = def->ShortName();
entry.usr = std::to_string(root_func.usr);
entry.location = *def_loc;
entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func);
@ -75,7 +76,8 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
WorkingFiles* working_files,
QueryFuncId root) {
QueryFunc& root_func = db->funcs[root.id];
if (!root_func.def)
const QueryFunc::Def* root_func_def = root_func.AnyDef();
if (!root_func_def)
return {};
std::vector<Out_CqueryCallTree::CallEntry> result;
@ -107,11 +109,12 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
if (caller.kind == SymbolKind::Func) {
QueryFunc& call_func = db->GetFunc(caller);
if (!call_func.def)
const QueryFunc::Def* def = call_func.AnyDef();
if (!def)
return;
Out_CqueryCallTree::CallEntry call_entry;
call_entry.name = call_func.def->ShortName();
call_entry.name = def->ShortName();
call_entry.usr = std::to_string(call_func.usr);
call_entry.location = *call_location;
call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func);

View File

@ -38,17 +38,17 @@ MAKE_REFLECT_STRUCT(Out_CqueryMemberHierarchy, jsonrpc, id, result);
std::vector<Out_CqueryMemberHierarchy::Entry>
BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
QueryType& root_type = db->types[root.id];
if (!root_type.def || !root_type.def->spell)
const auto* root_type = db->types[root.id].AnyDef();
if (!root_type || !root_type->spell)
return {};
optional<lsLocation> def_loc =
GetLsLocation(db, working_files, *root_type.def->spell);
GetLsLocation(db, working_files, *root_type->spell);
if (!def_loc)
return {};
Out_CqueryMemberHierarchy::Entry entry;
entry.type_id = root;
entry.name = root_type.def->ShortName();
entry.name = root_type->ShortName();
entry.location = *def_loc;
return {entry};
}

View File

@ -45,12 +45,12 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
int n = 0;
for (RawId i = 0; i < db->funcs.size(); i++)
if (db->funcs[i].def) {
if (db->funcs[i].AnyDef()) {
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Func});
sym2id[syms.back()] = n++;
}
for (RawId i = 0; i < db->types.size(); i++)
if (db->types[i].def) {
if (db->types[i].AnyDef()) {
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Type});
sym2id[syms.back()] = n++;
}
@ -77,12 +77,12 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
n++;
}
for (QueryType& type : db->types)
if (type.AnyDef()) {
if (const auto* def = type.AnyDef()) {
add(type.uses, 1);
Add(sym2id, adj, type.instances, n);
Add(sym2id, adj, type.def->funcs, n);
Add(sym2id, adj, type.def->types, n);
Add(sym2id, adj, type.def->vars, n);
Add(sym2id, adj, def->funcs, n);
Add(sym2id, adj, def->types, n);
Add(sym2id, adj, def->vars, n);
n++;
}
for (QueryVar& var : db->vars)

View File

@ -32,14 +32,15 @@ BuildParentInheritanceHierarchyForType(QueryDatabase* db,
WorkingFiles* working_files,
QueryType& root_type) {
std::vector<Out_CqueryTypeHierarchyTree::TypeEntry> parent_entries;
parent_entries.reserve(root_type.def->parents.size());
const QueryType::Def* def = root_type.AnyDef();
parent_entries.reserve(def->parents.size());
EachWithGen(db->types, root_type.def->parents, [&](QueryType& parent_type) {
EachWithGen(db->types, def->parents, [&](QueryType& parent_type) {
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
parent_entry.name = parent_type.def->detailed_name.c_str();
if (parent_type.def->spell)
parent_entry.location = GetLsLocation(
db, working_files, *parent_type.def->spell);
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);
@ -54,12 +55,12 @@ BuildInheritanceHierarchyForType(QueryDatabase* db,
WorkingFiles* working_files,
QueryType& root_type) {
Out_CqueryTypeHierarchyTree::TypeEntry entry;
const QueryType::Def* def = root_type.AnyDef();
// Name and location.
entry.name = root_type.def->detailed_name;
if (root_type.def->spell)
entry.location =
GetLsLocation(db, working_files, *root_type.def->spell);
entry.name = def->detailed_name;
if (def->spell)
entry.location = GetLsLocation(db, working_files, *def->spell);
entry.children.reserve(root_type.derived.size());
@ -90,20 +91,20 @@ BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
std::vector<Out_CqueryTypeHierarchyTree::TypeEntry> entries;
QueryFunc& root_func = db->funcs[root.id];
if (!root_func.def || root_func.def->base.empty())
const QueryFunc::Def* def = root_func.AnyDef();
if (!def || def->base.empty())
return {};
// FIXME WithGen
for (auto parent_id : root_func.def->base) {
for (auto parent_id : def->base) {
QueryFunc& parent_func = db->funcs[parent_id.id];
if (!parent_func.def)
const QueryFunc::Def* def1 = parent_func.AnyDef();
if (!def1)
continue;
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
parent_entry.name = parent_func.def->detailed_name;
if (parent_func.def->spell)
parent_entry.location = GetLsLocation(
db, working_files, *parent_func.def->spell);
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);
@ -118,16 +119,17 @@ BuildInheritanceHierarchyForFunc(QueryDatabase* db,
WorkingFiles* working_files,
QueryFuncId root_id) {
QueryFunc& root_func = db->funcs[root_id.id];
if (!root_func.def)
const QueryFunc::Def* def = root_func.AnyDef();
if (!def)
return nullopt;
Out_CqueryTypeHierarchyTree::TypeEntry entry;
// Name and location.
entry.name = root_func.def->detailed_name;
if (root_func.def->spell)
entry.name = def->detailed_name;
if (def->spell)
entry.location =
GetLsLocation(db, working_files, *root_func.def->spell);
GetLsLocation(db, working_files, *def->spell);
entry.children.reserve(root_func.derived.size());
@ -169,7 +171,7 @@ struct CqueryTypeHierarchyTreeHandler
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (sym.kind == SymbolKind::Type) {
QueryType& type = db->GetType(sym);
if (type.def)
if (type.AnyDef())
out.result =
BuildInheritanceHierarchyForType(db, working_files, type);
break;

View File

@ -69,13 +69,14 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
for (SymbolRef sym : file->def->outline) {
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
// Note: we ignore the definition if it is in the same file (ie,
// possibly a header).
if (func.def && func.def->extent) {
QueryFileId t = func.def->extent->file;
if (t != file_id)
return t;
if (const auto* def = db->GetFunc(sym).AnyDef()) {
// Note: we ignore the definition if it is in the same file (ie,
// possibly a header).
if (def->extent) {
QueryFileId t = def->extent->file;
if (t != file_id)
return t;
}
}
break;
}
@ -149,7 +150,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
QueryFileId decl_file_id,
QueryFileId impl_file_id,
QueryFunc& func) {
assert(func.def);
const QueryFunc::Def* def = func.AnyDef();
assert(def);
for (Use decl : func.declarations) {
if (decl.file != decl_file_id)
continue;
@ -160,12 +162,12 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
optional<std::string> type_name;
optional<lsPosition> same_file_insert_end;
if (func.def->declaring_type) {
QueryType& declaring_type = db->types[func.def->declaring_type->id];
if (declaring_type.def) {
type_name = std::string(declaring_type.def->ShortName());
optional<lsRange> ls_type_extent = GetLsRange(
working_file, declaring_type.def->extent->range);
if (def->declaring_type) {
QueryType& declaring_type = db->types[def->declaring_type->id];
if (const auto* def1 = declaring_type.AnyDef()) {
type_name = std::string(def1->ShortName());
optional<lsRange> ls_type_extent =
GetLsRange(working_file, def1->extent->range);
if (ls_type_extent) {
same_file_insert_end = ls_type_extent->end;
same_file_insert_end->character += 1; // move past semicolon.
@ -201,7 +203,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
switch (sym.kind) {
case SymbolKind::Func: {
QueryFunc& sym_func = db->GetFunc(sym);
if (!sym_func.def || !sym_func.def->extent)
const QueryFunc::Def* def1 = sym_func.AnyDef();
if (!def1 || !def1->extent)
break;
for (Use func_decl : sym_func.declarations) {
@ -209,7 +212,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
int dist = func_decl.range.start.line - decl.range.start.line;
if (abs(dist) < abs(best_dist)) {
optional<lsLocation> def_loc = GetLsLocation(
db, working_files, *sym_func.def->extent);
db, working_files, *def1->extent);
if (!def_loc)
continue;
@ -347,7 +350,8 @@ struct TextDocumentCodeActionHandler
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (!type.def)
const QueryType::Def* def = type.AnyDef();
if (!def)
break;
int num_edits = 0;
@ -355,8 +359,9 @@ struct TextDocumentCodeActionHandler
// Get implementation file.
Out_TextDocumentCodeAction::Command command;
EachWithGen(db->funcs, type.def->funcs, [&](QueryFunc& func_def) {
if (func_def.def->extent)
EachWithGen(db->funcs, def->funcs, [&](QueryFunc& func_def) {
const QueryFunc::Def* def1 = func_def.AnyDef();
if (def1->extent)
return;
EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/);
optional<lsTextEdit> edit = BuildAutoImplementForFunction(
@ -390,7 +395,7 @@ struct TextDocumentCodeActionHandler
command.arguments.textDocumentUri = *impl_uri;
command.title = "Auto-Implement " + std::to_string(num_edits) +
" methods on " + std::string(type.def->ShortName());
" methods on " + std::string(def->ShortName());
command.command = "cquery._autoImplement";
out.result.push_back(command);
break;
@ -398,14 +403,15 @@ struct TextDocumentCodeActionHandler
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (!func.def || func.def->extent)
const QueryFunc::Def* def = func.AnyDef();
if (!def || def->extent)
break;
EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/);
// Get implementation file.
Out_TextDocumentCodeAction::Command command;
command.title = "Auto-Implement " + std::string(func.def->ShortName());
command.title = "Auto-Implement " + std::string(def->ShortName());
command.command = "cquery._autoImplement";
command.arguments.textDocumentUri = *impl_uri;
optional<lsTextEdit> edit = BuildAutoImplementForFunction(

View File

@ -155,9 +155,8 @@ struct TextDocumentCodeLensHandler
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (!type.def)
continue;
if (type.def->kind == ClangSymbolKind::Namespace)
const QueryType::Def* def = type.AnyDef();
if (!def || def->kind == ClangSymbolKind::Namespace)
continue;
AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0),
type.uses, true /*force_display*/);
@ -169,7 +168,8 @@ struct TextDocumentCodeLensHandler
}
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (!func.def)
const QueryFunc::Def* def = func.AnyDef();
if (!def)
continue;
int16_t offset = 0;
@ -215,9 +215,9 @@ struct TextDocumentCodeLensHandler
ToUses(db, func.derived), false /*force_display*/);
// "Base"
if (func.def->base.size() == 1) {
if (def->base.size() == 1) {
Maybe<Use> base_loc = GetDefinitionSpellingOfSymbol(
db, SymbolIdx{func.def->base[0], SymbolKind::Func});
db, SymbolIdx{def->base[0], SymbolKind::Func});
if (base_loc) {
optional<lsLocation> ls_base =
GetLsLocation(db, working_files, *base_loc);
@ -239,7 +239,7 @@ struct TextDocumentCodeLensHandler
}
} else {
AddCodeLens("base", "base", &common, OffsetStartColumn(sym, 1),
ToUses(db, func.def->base),
ToUses(db, def->base),
false /*force_display*/);
}

View File

@ -752,8 +752,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryType& type = types[usr_to_type[usr].id];
if (type.symbol_idx)
symbols[type.symbol_idx->id].kind = SymbolKind::Invalid;
//type.def = QueryType::Def();
type.def = nullopt;
type.def.clear();
}
break;
}
@ -762,8 +761,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryFunc& func = funcs[usr_to_func[usr].id];
if (func.symbol_idx)
symbols[func.symbol_idx->id].kind = SymbolKind::Invalid;
//func.def = QueryFunc::Def();
func.def = nullopt;
func.def.clear();
}
break;
}
@ -851,9 +849,9 @@ void QueryDatabase::ImportOrUpdate(
QueryType& existing = types[it->second.id];
// Keep the existing definition if it is higher quality.
if (!(existing.def && existing.def->spell &&
!def.value.spell)) {
existing.def = std::move(def.value);
if (!(existing.AnyDef() && existing.AnyDef()->spell &&
!def.value.spell)) {
existing.def.push_front(std::move(def.value));
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, it->second);
}
}
@ -873,9 +871,9 @@ void QueryDatabase::ImportOrUpdate(
QueryFunc& existing = funcs[it->second.id];
// Keep the existing definition if it is higher quality.
if (!(existing.def && existing.def->spell &&
if (!(existing.AnyDef() && existing.AnyDef()->spell &&
!def.value.spell)) {
existing.def = std::move(def.value);
existing.def.push_front(std::move(def.value));
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, it->second);
}
}

View File

@ -140,14 +140,20 @@ struct QueryType {
Usr usr;
Maybe<Id<void>> symbol_idx;
optional<Def> def;
std::forward_list<Def> def;
std::vector<QueryTypeId> derived;
std::vector<QueryVarId> instances;
std::vector<Use> uses;
explicit QueryType(const Usr& usr) : usr(usr) {}
const Def* AnyDef() const { return def ? &*def : nullptr; }
Def* AnyDef() { return def ? &*def : nullptr; }
const Def* AnyDef() const {
if (def.empty()) return nullptr;
return &def.front();
}
Def* AnyDef() {
if (def.empty()) return nullptr;
return &def.front();
}
};
struct QueryFunc {
@ -159,14 +165,20 @@ struct QueryFunc {
Usr usr;
Maybe<Id<void>> symbol_idx;
optional<Def> def;
std::forward_list<Def> def;
std::vector<Use> declarations;
std::vector<QueryFuncId> derived;
std::vector<Use> uses;
explicit QueryFunc(const Usr& usr) : usr(usr) {}
const Def* AnyDef() const { return def ? &*def : nullptr; }
Def* AnyDef() { return def ? &*def : nullptr; }
const Def* AnyDef() const {
if (def.empty()) return nullptr;
return &def.front();
}
Def* AnyDef() {
if (def.empty()) return nullptr;
return &def.front();
}
};
struct QueryVar {

View File

@ -21,16 +21,16 @@ int ComputeRangeSize(const Range& range) {
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
SymbolIdx sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (type.def)
return type.def->spell;
case SymbolKind::File:
break;
case SymbolKind::Func: {
if (const auto* def = db->GetFunc(sym).AnyDef())
return def->spell;
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (func.def)
return func.def->spell;
case SymbolKind::Type: {
if (const auto* def = db->GetType(sym).AnyDef())
return def->spell;
break;
}
case SymbolKind::Var: {
@ -39,8 +39,6 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
return def->spell;
break;
}
case SymbolKind::File:
break;
case SymbolKind::Invalid:
assert(false && "unexpected");
break;
@ -50,16 +48,17 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (type.def)
return type.def->extent;
case SymbolKind::File:
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
Role::None, QueryFileId(sym.id));
case SymbolKind::Func: {
if (const auto* def = db->GetFunc(sym).AnyDef())
return def->extent;
break;
}
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (func.def)
return func.def->extent;
case SymbolKind::Type: {
if (const auto* def = db->GetType(sym).AnyDef())
return def->extent;
break;
}
case SymbolKind::Var: {
@ -68,9 +67,6 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
return def->extent;
break;
}
case SymbolKind::File:
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
Role::None, QueryFileId(sym.id));
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
@ -82,28 +78,26 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
SymbolIdx sym) {
switch (sym.kind) {
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (type.def)
return type.def->file;
break;
}
case SymbolKind::File:
return QueryFileId(sym.id);
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (!func.declarations.empty())
return func.declarations[0].file;
if (func.def)
return func.def->file;
break;
}
case SymbolKind::Var: {
const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (def)
if (const auto* def = func.AnyDef())
return def->file;
break;
}
case SymbolKind::Type: {
if (const auto* def = db->GetType(sym).AnyDef())
return def->file;
break;
}
case SymbolKind::Var: {
if (const auto* def = db->GetVar(sym).AnyDef())
return def->file;
break;
}
case SymbolKind::File:
return QueryFileId(sym.id);
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
@ -118,8 +112,9 @@ std::vector<Use> ToUses(QueryDatabase* db,
ret.reserve(ids.size());
for (auto id : ids) {
QueryFunc& func = db->funcs[id.id];
if (func.def && func.def->spell)
ret.push_back(*func.def->spell);
const QueryFunc::Def* def = func.AnyDef();
if (def && def->spell)
ret.push_back(*def->spell);
else if (func.declarations.size())
ret.push_back(func.declarations[0]);
}
@ -132,8 +127,9 @@ std::vector<Use> ToUses(QueryDatabase* db,
ret.reserve(ids.size());
for (auto id : ids) {
QueryType& type = db->types[id.id];
if (type.def && type.def->spell)
ret.push_back(*type.def->spell);
const QueryType::Def* def = type.AnyDef();
if (def && def->spell)
ret.push_back(*def->spell);
}
return ret;
}
@ -143,7 +139,7 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
ret.reserve(ids.size());
for (auto id : ids) {
QueryVar& var = db->vars[id.id];
QueryVar::Def* def = var.AnyDef();
const QueryVar::Def* def = var.AnyDef();
if (def && def->spell)
ret.push_back(*def->spell);
else if (var.declarations.size())
@ -205,11 +201,10 @@ std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
// function has the postfix `ForGotoDefintion`, but it lets the user
// jump to the start of a type if clicking goto-definition on the same
// type from within the type definition.
QueryType& type = db->GetType(sym);
if (type.def) {
Maybe<Use> def = type.def->spell;
if (def)
return {*def};
if (const auto* def = db->GetType(sym).AnyDef()) {
Maybe<Use> spell = def->spell;
if (spell)
return {*spell};
}
break;
}
@ -228,10 +223,11 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
// Check self.
if (!root.uses.empty())
return true;
const QueryFunc::Def* def = root.AnyDef();
// Check for base calls.
std::queue<QueryFunc*> queue;
EachWithGen<QueryFunc>(db->funcs, root.def->base, [&](QueryFunc& func) {
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func) {
queue.push(&func);
});
while (!queue.empty()) {
@ -239,8 +235,8 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
queue.pop();
if (!func.uses.empty())
return true;
if (func.def)
EachWithGen<QueryFunc>(db->funcs, func.def->base, [&](QueryFunc& func1) {
if (def)
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
queue.push(&func1);
});
}
@ -265,11 +261,12 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
QueryFunc& root) {
std::vector<Use> callers;
if (!root.def)
const QueryFunc::Def* def = root.AnyDef();
if (!def)
return callers;
std::queue<QueryFunc*> queue;
EachWithGen<QueryFunc>(db->funcs, root.def->base, [&](QueryFunc& func1) {
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
queue.push(&func1);
});
while (!queue.empty()) {
@ -277,8 +274,8 @@ std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
queue.pop();
AddRange(&callers, func.uses);
if (func.def)
EachWithGen<QueryFunc>(db->funcs, func.def->base, [&](QueryFunc& func1) {
if (def)
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
queue.push(&func1);
});
}
@ -453,19 +450,19 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info;
}
case SymbolKind::Type: {
QueryType& type = db->GetType(sym);
if (!type.def)
const QueryType::Def* def = db->GetType(sym).AnyDef();
if (!def)
break;
lsSymbolInformation info;
if (use_short_name)
info.name = type.def->ShortName();
info.name = def->ShortName();
else
info.name = type.def->detailed_name;
if (type.def->detailed_name.c_str() != type.def->ShortName())
info.containerName = type.def->detailed_name;
info.name = def->detailed_name;
if (def->detailed_name.c_str() != def->ShortName())
info.containerName = def->detailed_name;
// TODO ClangSymbolKind -> lsSymbolKind
switch (type.def->kind) {
switch (def->kind) {
default:
info.kind = lsSymbolKind::Class;
break;
@ -476,17 +473,17 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info;
}
case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym);
if (!func.def)
const QueryFunc::Def* def = db->GetFunc(sym).AnyDef();
if (!def)
break;
lsSymbolInformation info;
if (use_short_name)
info.name = func.def->ShortName();
info.name = def->ShortName();
else
info.name = func.def->detailed_name;
info.containerName = func.def->detailed_name;
switch (func.def->kind) {
info.name = def->detailed_name;
info.containerName = def->detailed_name;
switch (def->kind) {
default:
info.kind = lsSymbolKind::Function;
break;