Improve tree view

- Show base/derived callers ([B] and [D] prefix)
- Show call position information
- Temporarily prevent duplicate calls from appearing, needs a proper fix.
This commit is contained in:
Jacob Dufault 2017-07-19 00:12:04 -07:00
parent f4db0967b2
commit 79ec5a749a
3 changed files with 49 additions and 6 deletions

View File

@ -5,6 +5,7 @@
#include <string> #include <string>
#include "serializer.h" #include "serializer.h"
#include "utils.h"
struct Position { struct Position {
int16_t line = -1; int16_t line = -1;
@ -24,6 +25,7 @@ struct Position {
bool operator<(const Position& that) const; bool operator<(const Position& that) const;
}; };
static_assert(sizeof(Position) == 4, "Investigate, Position should be 32-bits for indexer size reasons"); static_assert(sizeof(Position) == 4, "Investigate, Position should be 32-bits for indexer size reasons");
MAKE_HASHABLE(Position, t.line, t.column);
struct Range { struct Range {
Position start; Position start;
@ -42,6 +44,7 @@ struct Range {
bool operator!=(const Range& that) const; bool operator!=(const Range& that) const;
bool operator<(const Range& that) const; bool operator<(const Range& that) const;
}; };
MAKE_HASHABLE(Range, t.start, t.end);
// Reflection // Reflection
void Reflect(Reader& visitor, Position& value); void Reflect(Reader& visitor, Position& value);

View File

@ -57,6 +57,7 @@ struct QueryLocation {
} }
}; };
MAKE_REFLECT_STRUCT(QueryLocation, path, range); MAKE_REFLECT_STRUCT(QueryLocation, path, range);
MAKE_HASHABLE(QueryLocation, t.path, t.range);
enum class SymbolKind { Invalid, File, Type, Func, Var }; enum class SymbolKind { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(SymbolKind, int); MAKE_REFLECT_TYPE_PROXY(SymbolKind, int);

View File

@ -665,20 +665,48 @@ NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(QueryDatabase
if (!root_func) if (!root_func)
return {}; 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<Out_CqueryCallTree::CallEntry> result; NonElidedVector<Out_CqueryCallTree::CallEntry> result;
result.reserve(root_func->callers.size()); std::unordered_set<QueryLocation> seen_locations;
for (QueryFuncRef caller : root_func->callers) {
auto handle_caller = [&](const std::string& prefix, QueryFuncRef caller) {
optional<lsLocation> call_location = GetLsLocation(db, working_files, caller.loc); optional<lsLocation> call_location = GetLsLocation(db, working_files, caller.loc);
if (!call_location) 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()) { if (caller.has_id()) {
optional<QueryFunc>& call_func = db->funcs[caller.id_.id]; optional<QueryFunc>& call_func = db->funcs[caller.id_.id];
if (!call_func) if (!call_func)
continue; return;
Out_CqueryCallTree::CallEntry call_entry; 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.usr = call_func->def.usr;
call_entry.location = *call_location; call_entry.location = *call_location;
call_entry.hasCallers = !call_func->callers.empty(); call_entry.hasCallers = !call_func->callers.empty();
@ -694,7 +722,18 @@ NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(QueryDatabase
call_entry.hasCallers = false; call_entry.hasCallers = false;
result.push_back(call_entry); result.push_back(call_entry);
} }
} };
std::vector<QueryFuncRef> base_callers = GetCallersForAllBaseFunctions(db, *root_func);
std::vector<QueryFuncRef> 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; return result;
} }