diff --git a/src/position.h b/src/position.h index 35e3b91c..3e02900f 100644 --- a/src/position.h +++ b/src/position.h @@ -5,6 +5,7 @@ #include #include "serializer.h" +#include "utils.h" struct Position { int16_t line = -1; @@ -24,6 +25,7 @@ struct Position { bool operator<(const Position& that) const; }; static_assert(sizeof(Position) == 4, "Investigate, Position should be 32-bits for indexer size reasons"); +MAKE_HASHABLE(Position, t.line, t.column); struct Range { Position start; @@ -42,6 +44,7 @@ struct Range { bool operator!=(const Range& that) const; bool operator<(const Range& that) const; }; +MAKE_HASHABLE(Range, t.start, t.end); // Reflection void Reflect(Reader& visitor, Position& value); diff --git a/src/query.h b/src/query.h index 1b09f3c7..0cb02444 100644 --- a/src/query.h +++ b/src/query.h @@ -57,6 +57,7 @@ struct QueryLocation { } }; MAKE_REFLECT_STRUCT(QueryLocation, path, range); +MAKE_HASHABLE(QueryLocation, t.path, t.range); enum class SymbolKind { Invalid, File, Type, Func, Var }; MAKE_REFLECT_TYPE_PROXY(SymbolKind, int); diff --git a/src/query_utils.cc b/src/query_utils.cc index 86e7d603..0423f03f 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -665,20 +665,48 @@ NonElidedVector BuildExpandCallTree(QueryDatabase if (!root_func) return {}; + auto format_location = [](const lsLocation& location) -> std::string { + std::string path = location.uri.GetPath(); + size_t last_index = path.find_last_of('/'); + if (last_index != std::string::npos) + path = path.substr(last_index + 1); + + return path + ":" + std::to_string(location.range.start.line + 1) + ":" + std::to_string(location.range.start.character + 1); + }; + NonElidedVector result; - result.reserve(root_func->callers.size()); - for (QueryFuncRef caller : root_func->callers) { + std::unordered_set seen_locations; + + auto handle_caller = [&](const std::string& prefix, QueryFuncRef caller) { optional call_location = GetLsLocation(db, working_files, caller.loc); if (!call_location) - continue; + return; + + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: REMOVE |seen_locations| once we fix the querydb update bugs + // TODO: basically, querydb gets duplicate references inserted into it. + if (!seen_locations.insert(caller.loc).second) { + std::cerr << "!!!! FIXME DUPLICATE REFERENCE IN QUERYDB" << std::endl; + return; + } if (caller.has_id()) { optional& call_func = db->funcs[caller.id_.id]; if (!call_func) - continue; + return; Out_CqueryCallTree::CallEntry call_entry; - call_entry.name = call_func->def.short_name; + call_entry.name = prefix + call_func->def.short_name + " (" + format_location(*call_location) + ")"; call_entry.usr = call_func->def.usr; call_entry.location = *call_location; call_entry.hasCallers = !call_func->callers.empty(); @@ -694,7 +722,18 @@ NonElidedVector BuildExpandCallTree(QueryDatabase call_entry.hasCallers = false; result.push_back(call_entry); } - } + }; + + std::vector base_callers = GetCallersForAllBaseFunctions(db, *root_func); + std::vector derived_callers = GetCallersForAllDerivedFunctions(db, *root_func); + result.reserve(root_func->callers.size() + base_callers.size() + derived_callers.size()); + + for (QueryFuncRef caller : root_func->callers) + handle_caller("", caller); + for (QueryFuncRef caller : base_callers) + handle_caller("[B] ", caller); + for (QueryFuncRef caller : derived_callers) + handle_caller("[D] ", caller); return result; }