diff --git a/src/message_handler.cc b/src/message_handler.cc index 27999882..722f048a 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -148,20 +148,18 @@ void EmitSemanticHighlighting(QueryDatabase* db, break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (!var.def) - continue; // applies to for loop - kind = var.def->kind; - storage = var.def->storage; - detailed_name = var.def->ShortName(); + if (const QueryVar::Def* def = db->GetVar(sym).AnyDef()) { + kind = def->kind; + storage = def->storage; + detailed_name = def->ShortName(); + } break; } case SymbolKind::Type: { - QueryType& type = db->GetType(sym); - if (!type.def) - continue; // applies to for loop - kind = type.def->kind; - detailed_name = type.def->detailed_name; + if (const QueryType::Def* def = db->GetType(sym).AnyDef()) { + kind = def->kind; + detailed_name = def->detailed_name; + } break; } default: diff --git a/src/messages/cquery_member_hierarchy.cc b/src/messages/cquery_member_hierarchy.cc index 0f0322e0..59cb56d6 100644 --- a/src/messages/cquery_member_hierarchy.cc +++ b/src/messages/cquery_member_hierarchy.cc @@ -56,17 +56,19 @@ BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { std::vector ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { QueryType& root_type = db->types[root.id]; - if (!root_type.def) + const QueryType::Def* def = root_type.AnyDef(); + if (!def) return {}; std::vector ret; - EachWithGen(db->vars, root_type.def->vars, [&](QueryVar& var) { + EachWithGen(db->vars, def->vars, [&](QueryVar& var) { + const QueryVar::Def* def1 = var.AnyDef(); Out_CqueryMemberHierarchy::Entry entry; - entry.name = var.def->ShortName(); - entry.type_id = var.def->type ? *var.def->type : QueryTypeId(); - if (var.def->spell) { + entry.name = def1->ShortName(); + entry.type_id = def1->type ? *def1->type : QueryTypeId(); + if (def->spell) { optional loc = - GetLsLocation(db, working_files, *var.def->spell); + GetLsLocation(db, working_files, *def1->spell); // TODO invalid location if (loc) entry.location = *loc; @@ -96,9 +98,9 @@ struct CqueryMemberHierarchyInitialHandler break; } if (sym.kind == SymbolKind::Var) { - QueryVar& var = db->GetVar(sym); - if (var.def && var.def->type) - out.result = BuildInitial(db, working_files, *var.def->type); + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def && def->type) + out.result = BuildInitial(db, working_files, *def->type); break; } } diff --git a/src/messages/cquery_random.cc b/src/messages/cquery_random.cc index e4664591..c0963720 100644 --- a/src/messages/cquery_random.cc +++ b/src/messages/cquery_random.cc @@ -55,7 +55,7 @@ struct CqueryRandomHandler : BaseMessageHandler { sym2id[syms.back()] = n++; } for (RawId i = 0; i < db->vars.size(); i++) - if (db->vars[i].def) { + if (db->vars[i].AnyDef()) { syms.push_back(SymbolIdx{Id(i), SymbolKind::Var}); sym2id[syms.back()] = n++; } @@ -70,14 +70,14 @@ struct CqueryRandomHandler : BaseMessageHandler { }; n = 0; for (QueryFunc& func : db->funcs) - if (func.def) { + if (func.AnyDef()) { add(func.declarations, kDeclWeight); add(func.uses, 1); Add(sym2id, adj, func.derived, n); n++; } for (QueryType& type : db->types) - if (type.def) { + if (type.AnyDef()) { add(type.uses, 1); Add(sym2id, adj, type.instances, n); Add(sym2id, adj, type.def->funcs, n); @@ -86,7 +86,7 @@ struct CqueryRandomHandler : BaseMessageHandler { n++; } for (QueryVar& var : db->vars) - if (var.def) { + if (var.AnyDef()) { add(var.declarations, kDeclWeight); add(var.uses, 1); n++; diff --git a/src/messages/cquery_vars.cc b/src/messages/cquery_vars.cc index d36eca86..68fab4c5 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/cquery_vars.cc @@ -30,10 +30,10 @@ struct CqueryVarsHandler : BaseMessageHandler { default: break; case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (!var.def || !var.def->type) + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (!def || !def->type) continue; - id = *var.def->type; + id = *def->type; } // fallthrough case SymbolKind::Type: { diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index f7f0d6dc..f4a32e49 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -80,11 +80,11 @@ optional GetImplementationFile(QueryDatabase* db, break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); // Note: we ignore the definition if it is in the same file (ie, // possibly a header). - if (var.def && var.def->extent) { - QueryFileId t = var.def->extent->file; + if (def && def->extent) { + QueryFileId t = def->extent->file; if (t != file_id) return t; } diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index dfcb9727..b7ccf04a 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -247,16 +247,14 @@ struct TextDocumentCodeLensHandler } case SymbolKind::Var: { QueryVar& var = db->GetVar(sym); - if (!var.def) - continue; - - if (var.def->is_local() && !config->codeLensOnLocalVariables) + const QueryVar::Def* def = var.AnyDef(); + if (!def || (def->is_local() && !config->codeLensOnLocalVariables)) continue; bool force_display = true; // Do not show 0 refs on macro with no uses, as it is most likely // a header guard. - if (var.def->is_macro()) + if (def->is_macro()) force_display = false; AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0), diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index ff9e8b24..b46e590f 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -37,10 +37,10 @@ std::vector GetGotoDefinitionTargets(QueryDatabase* db, case SymbolKind::Var: { std::vector ret = GetDeclarationsOfSymbolForGotoDefinition(db, sym); - QueryVar& var = db->GetVar(sym); - if (var.def && var.def->type) { + QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def && def->type) { std::vector types = GetDeclarationsOfSymbolForGotoDefinition( - db, SymbolIdx{*var.def->type, SymbolKind::Type}); + db, SymbolIdx{*def->type, SymbolKind::Type}); ret.insert(ret.end(), types.begin(), types.end()); } return ret; diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 6d7b1961..9af5f077 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -9,30 +9,27 @@ std::pair GetCommentsAndHover( SymbolRef sym) { switch (sym.kind) { case SymbolKind::Type: { - QueryType& type = db->GetType(sym); - if (type.def) - return {type.def->comments, - !type.def->hover.empty() - ? std::string_view(type.def->hover) - : std::string_view(type.def->detailed_name)}; + if (const auto* def = db->GetType(sym).AnyDef()) { + return {def->comments, !def->hover.empty() + ? std::string_view(def->hover) + : std::string_view(def->detailed_name)}; + } break; } case SymbolKind::Func: { - QueryFunc& func = db->GetFunc(sym); - if (func.def) - return {func.def->comments, - !func.def->hover.empty() - ? std::string_view(func.def->hover) - : std::string_view(func.def->detailed_name)}; + if (const auto* def = db->GetFunc(sym).AnyDef()) { + return {def->comments, !def->hover.empty() + ? std::string_view(def->hover) + : std::string_view(def->detailed_name)}; + } break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (var.def) - return {var.def->comments, - !var.def->hover.empty() - ? std::string_view(var.def->hover) - : std::string_view(var.def->detailed_name)}; + if (const auto* def = db->GetVar(sym).AnyDef()) { + return {def->comments, !def->hover.empty() + ? std::string_view(def->hover) + : std::string_view(def->detailed_name)}; + } break; } case SymbolKind::File: diff --git a/src/query.cc b/src/query.cc index f985c41d..a9529c74 100644 --- a/src/query.cc +++ b/src/query.cc @@ -772,8 +772,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, QueryVar& var = vars[usr_to_var[usr].id]; if (var.symbol_idx) symbols[var.symbol_idx->id].kind = SymbolKind::Invalid; - //var.def = QueryVar::Def(); - var.def = nullopt; + var.def.clear(); } break; } @@ -895,10 +894,10 @@ void QueryDatabase::ImportOrUpdate(std::vector&& updates) { QueryVar& existing = vars[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); - if (!def.value.is_local()) + existing.def.push_front(std::move(def.value)); + if (!existing.def.front().is_local()) UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second); } } @@ -924,19 +923,19 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const { return files[idx].def->path; break; case SymbolKind::Func: - if (funcs[idx].def) { - auto& def = funcs[idx].def; + if (const auto* def = funcs[idx].AnyDef()) { + // Assume the part after short_name is not needed. return std::string_view(def->detailed_name) .substr(0, def->short_name_offset + def->short_name_size); } break; case SymbolKind::Type: - if (types[idx].def) - return types[idx].def->detailed_name; + if (const auto* def = types[idx].AnyDef()) + return def->detailed_name; break; case SymbolKind::Var: - if (vars[idx].def) - return vars[idx].def->detailed_name; + if (const auto* def = vars[idx].AnyDef()) + return def->detailed_name; break; } return ""; @@ -952,16 +951,16 @@ std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const { return files[idx].def->path; break; case SymbolKind::Func: - if (funcs[idx].def) - return funcs[idx].def->ShortName(); + if (const auto* def = funcs[idx].AnyDef()) + return def->ShortName(); break; case SymbolKind::Type: - if (types[idx].def) - return types[idx].def->ShortName(); + if (const auto* def = types[idx].AnyDef()) + return def->ShortName(); break; case SymbolKind::Var: - if (vars[idx].def) - return vars[idx].def->ShortName(); + if (const auto* def = vars[idx].AnyDef()) + return def->ShortName(); break; } return ""; diff --git a/src/query.h b/src/query.h index 75f5b084..8a852152 100644 --- a/src/query.h +++ b/src/query.h @@ -5,6 +5,7 @@ #include +#include #include struct QueryFile; @@ -145,6 +146,8 @@ struct QueryType { std::vector uses; explicit QueryType(const Usr& usr) : usr(usr) {} + const Def* AnyDef() const { return def ? &*def : nullptr; } + Def* AnyDef() { return def ? &*def : nullptr; } }; struct QueryFunc { @@ -162,6 +165,8 @@ struct QueryFunc { std::vector uses; explicit QueryFunc(const Usr& usr) : usr(usr) {} + const Def* AnyDef() const { return def ? &*def : nullptr; } + Def* AnyDef() { return def ? &*def : nullptr; } }; struct QueryVar { @@ -172,11 +177,19 @@ struct QueryVar { Usr usr; Maybe> symbol_idx; - optional def; + std::forward_list def; std::vector declarations; std::vector uses; explicit QueryVar(const Usr& usr) : usr(usr) {} + const Def* AnyDef() const { + if (def.empty()) return nullptr; + return &def.front(); + } + Def* AnyDef() { + if (def.empty()) return nullptr; + return &def.front(); + } }; struct IndexUpdate { @@ -297,21 +310,21 @@ struct QueryDatabase { case SymbolKind::File: return QueryFileId(ref.id); case SymbolKind::Func: { - QueryFunc& file = funcs[ref.id.id]; - if (file.def) - return file.def->file; + const QueryFunc::Def* def = funcs[ref.id.id].AnyDef(); + if (def) + return def->file; break; } case SymbolKind::Type: { - QueryType& type = types[ref.id.id]; - if (type.def) - return type.def->file; + const QueryType::Def* def = types[ref.id.id].AnyDef(); + if (def) + return def->file; break; } case SymbolKind::Var: { - QueryVar& var = vars[ref.id.id]; - if (var.def) - return var.def->file; + const QueryVar::Def* def = vars[ref.id.id].AnyDef(); + if (def) + return def->file; break; } } diff --git a/src/query_utils.cc b/src/query_utils.cc index f30a87b0..a6289aad 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -34,9 +34,9 @@ Maybe GetDefinitionSpellingOfSymbol(QueryDatabase* db, break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (var.def) - return var.def->spell; + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def) + return def->spell; break; } case SymbolKind::File: @@ -63,9 +63,9 @@ Maybe GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) { break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (var.def) - return var.def->extent; + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def) + return def->extent; break; } case SymbolKind::File: @@ -97,9 +97,9 @@ Maybe GetDeclarationFileForSymbol(QueryDatabase* db, break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (var.def) - return var.def->file; + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (def) + return def->file; break; } case SymbolKind::File: @@ -143,8 +143,9 @@ std::vector ToUses(QueryDatabase* db, const std::vector& ids) { ret.reserve(ids.size()); for (auto id : ids) { QueryVar& var = db->vars[id.id]; - if (var.def && var.def->spell) - ret.push_back(*var.def->spell); + QueryVar::Def* def = var.AnyDef(); + if (def && def->spell) + ret.push_back(*def->spell); else if (var.declarations.size()) ret.push_back(var.declarations[0]); } @@ -158,16 +159,20 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, case SymbolKind::Type: { QueryType& type = db->GetType(sym); std::vector ret = type.uses; - if (include_decl && type.def && type.def->spell) - ret.push_back(*type.def->spell); + if (include_decl) { + const QueryType::Def* def = type.AnyDef(); + if (def && def->spell) + ret.push_back(*def->spell); + } return ret; } case SymbolKind::Func: { QueryFunc& func = db->GetFunc(sym); std::vector ret = func.uses; if (include_decl) { - 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); AddRange(&ret, func.declarations); } return ret; @@ -176,8 +181,9 @@ std::vector GetUsesOfSymbol(QueryDatabase* db, QueryVar& var = db->GetVar(sym); std::vector ret = var.uses; if (include_decl) { - if (var.def && var.def->spell) - ret.push_back(*var.def->spell); + const QueryVar::Def* def = var.AnyDef(); + if (def && def->spell) + ret.push_back(*def->spell); ret.insert(ret.end(), var.declarations.begin(), var.declarations.end()); } return ret; @@ -393,21 +399,21 @@ optional GetLsLocationEx(QueryDatabase* db, default: break; case SymbolKind::Func: { - QueryFunc& func = db->GetFunc(use); - if (func.def) - ret.containerName = std::string_view(func.def->detailed_name); + const QueryFunc::Def* def = db->GetFunc(use).AnyDef(); + if (def) + ret.containerName = std::string_view(def->detailed_name); break; } case SymbolKind::Type: { - QueryType& type = db->GetType(use); - if (type.def) - ret.containerName = std::string_view(type.def->detailed_name); + const QueryType::Def* def = db->GetType(use).AnyDef(); + if (def) + ret.containerName = std::string_view(def->detailed_name); break; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(use); - if (var.def) - ret.containerName = std::string_view(var.def->detailed_name); + const QueryVar::Def* def = db->GetVar(use).AnyDef(); + if (def) + ret.containerName = std::string_view(def->detailed_name); break; } } @@ -492,17 +498,17 @@ optional GetSymbolInfo(QueryDatabase* db, return info; } case SymbolKind::Var: { - QueryVar& var = db->GetVar(sym); - if (!var.def) + const QueryVar::Def* def = db->GetVar(sym).AnyDef(); + if (!def) break; lsSymbolInformation info; if (use_short_name) - info.name = var.def->ShortName(); + info.name = def->ShortName(); else - info.name = var.def->detailed_name; - info.containerName = var.def->detailed_name; - switch (var.def->kind) { + info.name = def->detailed_name; + info.containerName = def->detailed_name; + switch (def->kind) { default: info.kind = lsSymbolKind::Variable; break; diff --git a/src/query_utils.h b/src/query_utils.h index 8f865541..eefaa0cf 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -69,15 +69,15 @@ void EachWithGen(std::vector& collection, Id x, Fn fn) { Q& obj = collection[x.id]; // FIXME Deprecate optional def // if (obj.gen == x.gen && obj.def) - if (obj.def) + if (obj.AnyDef()) fn(obj); } template -void EachWithGen(std::vector& collection, std::vector>& ids, Fn fn) { +void EachWithGen(std::vector& collection, const std::vector>& ids, Fn fn) { for (Id x : ids) { Q& obj = collection[x.id]; - if (obj.def) // FIXME Deprecate optional def + if (obj.AnyDef()) fn(obj); } }