#pragma once #include "query.h" #include "working_files.h" #include Maybe GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym); Maybe GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym); Maybe GetDeclarationFileForSymbol(QueryDatabase* db, SymbolIdx sym); // Get defining declaration (if exists) or an arbitrary declaration (otherwise) for each id. std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); std::vector GetDeclarations(QueryDatabase* db, const std::vector& ids); // Get non-defining declarations. std::vector GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym); std::vector GetUsesForAllBases(QueryDatabase* db, QueryFunc& root); std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root); optional GetLsPosition(WorkingFile* working_file, const Position& position); optional GetLsRange(WorkingFile* working_file, const Range& location); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id, std::string* path); lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id); optional GetLsLocation(QueryDatabase* db, WorkingFiles* working_files, Use use); optional GetLsLocationEx(QueryDatabase* db, WorkingFiles* working_files, Use use, bool container); std::vector GetLsLocationExs(QueryDatabase* db, WorkingFiles* working_files, const std::vector& refs, bool container, int limit); // Returns a symbol. The symbol will have *NOT* have a location assigned. optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, SymbolIdx sym, bool use_short_name); std::vector FindSymbolsAtLocation(WorkingFile* working_file, QueryFile* file, lsPosition position); template void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { switch (sym.kind) { case SymbolKind::Invalid: case SymbolKind::File: break; case SymbolKind::Func: fn(db->GetFunc(sym)); break; case SymbolKind::Type: fn(db->GetType(sym)); break; case SymbolKind::Var: fn(db->GetVar(sym)); break; } } template void EachEntityDef(QueryDatabase* db, SymbolIdx sym, Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { for (auto& def : entity.def) if (!fn(def)) break; }); } template void EachOccurrence(QueryDatabase* db, SymbolIdx sym, bool include_decl, Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { for (Use use : entity.uses) fn(use); if (include_decl) { for (auto& def : entity.def) if (def.spell) fn(*def.spell); for (Use use : entity.declarations) fn(use); } }); } template void EachOccurrenceWithParent(QueryDatabase* db, SymbolIdx sym, bool include_decl, Fn&& fn) { WithEntity(db, sym, [&](const auto& entity) { lsSymbolKind parent_kind = lsSymbolKind::Unknown; for (auto& def : entity.def) if (def.spell) { WithEntity(db, *def.spell, [&](const auto& entity) { for (auto& def : entity.def) { parent_kind = def.kind; break; } }); break; } for (Use use : entity.uses) fn(use, parent_kind); if (include_decl) { for (auto& def : entity.def) if (def.spell) fn(*def.spell, parent_kind); for (Use use : entity.declarations) fn(use, parent_kind); } }); } template void EachDefinedEntity(std::vector& collection, const std::vector>& ids, Fn&& fn) { for (Id x : ids) { Q& obj = collection[x.id]; if (!obj.def.empty()) fn(obj); } }