diff --git a/src/message_handler.cc b/src/message_handler.cc index 722f048a..2d0c7680 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -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, "functionkind; + kind = def->kind; detailed_name = short_name; // Check whether the function name is actually there. diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index f06adffc..a34b360c 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -35,16 +35,14 @@ struct CqueryBaseHandler : BaseMessageHandler { }); 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; } } diff --git a/src/messages/cquery_call_tree.cc b/src/messages/cquery_call_tree.cc index 7bb7260d..e6066c4b 100644 --- a/src/messages/cquery_call_tree.cc +++ b/src/messages/cquery_call_tree.cc @@ -53,15 +53,16 @@ std::vector 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 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 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 result; @@ -107,11 +109,12 @@ std::vector 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); diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/cquery_member_hierarchy.cc index 59cb56d6..9254b004 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/cquery_member_hierarchy.cc @@ -38,17 +38,17 @@ MAKE_REFLECT_STRUCT(Out_CqueryMemberHierarchy, jsonrpc, id, result); std::vector 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 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}; } diff --git a/src/messages/cquery_random.cc b/src/messages/cquery_random.cc index c0963720..500538b0 100644 --- a/src/messages/cquery_random.cc +++ b/src/messages/cquery_random.cc @@ -45,12 +45,12 @@ struct CqueryRandomHandler : BaseMessageHandler { 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(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(i), SymbolKind::Type}); sym2id[syms.back()] = n++; } @@ -77,12 +77,12 @@ struct CqueryRandomHandler : BaseMessageHandler { 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) diff --git a/src/messages/cquery_type_hierarchy_tree.cc b/src/messages/cquery_type_hierarchy_tree.cc index b94c1eea..782465b9 100644 --- a/src/messages/cquery_type_hierarchy_tree.cc +++ b/src/messages/cquery_type_hierarchy_tree.cc @@ -32,14 +32,15 @@ BuildParentInheritanceHierarchyForType(QueryDatabase* db, WorkingFiles* working_files, QueryType& root_type) { std::vector 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 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; diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index f4a32e49..79bde007 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -69,13 +69,14 @@ optional 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 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 BuildAutoImplementForFunction(QueryDatabase* db, optional type_name; optional 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 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 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 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 BuildAutoImplementForFunction(QueryDatabase* db, int dist = func_decl.range.start.line - decl.range.start.line; if (abs(dist) < abs(best_dist)) { optional 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 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 edit = BuildAutoImplementForFunction( diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index b7ccf04a..a785741d 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -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 base_loc = GetDefinitionSpellingOfSymbol( - db, SymbolIdx{func.def->base[0], SymbolKind::Func}); + db, SymbolIdx{def->base[0], SymbolKind::Func}); if (base_loc) { optional 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*/); } diff --git a/src/query.cc b/src/query.cc index a9529c74..5432eee5 100644 --- a/src/query.cc +++ b/src/query.cc @@ -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); } } diff --git a/src/query.h b/src/query.h index 8a852152..8e78c7e1 100644 --- a/src/query.h +++ b/src/query.h @@ -140,14 +140,20 @@ struct QueryType { Usr usr; Maybe> symbol_idx; - optional def; + std::forward_list def; std::vector derived; std::vector instances; std::vector 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> symbol_idx; - optional def; + std::forward_list def; std::vector declarations; std::vector derived; std::vector 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 { diff --git a/src/query_utils.cc b/src/query_utils.cc index a6289aad..14b090de 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -21,16 +21,16 @@ int ComputeRangeSize(const Range& range) { Maybe 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 GetDefinitionSpellingOfSymbol(QueryDatabase* db, return def->spell; break; } - case SymbolKind::File: - break; case SymbolKind::Invalid: assert(false && "unexpected"); break; @@ -50,16 +48,17 @@ Maybe GetDefinitionSpellingOfSymbol(QueryDatabase* db, Maybe 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 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 GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) { Maybe 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 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 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 ToUses(QueryDatabase* db, const std::vector& 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 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 def = type.def->spell; - if (def) - return {*def}; + if (const auto* def = db->GetType(sym).AnyDef()) { + Maybe 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 queue; - EachWithGen(db->funcs, root.def->base, [&](QueryFunc& func) { + EachWithGen(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(db->funcs, func.def->base, [&](QueryFunc& func1) { + if (def) + EachWithGen(db->funcs, def->base, [&](QueryFunc& func1) { queue.push(&func1); }); } @@ -265,11 +261,12 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) { std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, QueryFunc& root) { std::vector callers; - if (!root.def) + const QueryFunc::Def* def = root.AnyDef(); + if (!def) return callers; std::queue queue; - EachWithGen(db->funcs, root.def->base, [&](QueryFunc& func1) { + EachWithGen(db->funcs, def->base, [&](QueryFunc& func1) { queue.push(&func1); }); while (!queue.empty()) { @@ -277,8 +274,8 @@ std::vector GetCallersForAllBaseFunctions(QueryDatabase* db, queue.pop(); AddRange(&callers, func.uses); - if (func.def) - EachWithGen(db->funcs, func.def->base, [&](QueryFunc& func1) { + if (def) + EachWithGen(db->funcs, def->base, [&](QueryFunc& func1) { queue.push(&func1); }); } @@ -453,19 +450,19 @@ optional 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 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;