Fix call tree when function ref does not refer to a function.

This commit is contained in:
Jacob Dufault 2017-06-13 23:50:30 -07:00
parent 4bddc95908
commit 3d0b8fd807
3 changed files with 33 additions and 24 deletions

View File

@ -892,19 +892,32 @@ NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(QueryDatabase
NonElidedVector<Out_CqueryCallTree::CallEntry> result; NonElidedVector<Out_CqueryCallTree::CallEntry> result;
result.reserve(root_func->callers.size()); result.reserve(root_func->callers.size());
for (QueryFuncRef caller : root_func->callers) { for (QueryFuncRef caller : root_func->callers) {
optional<QueryFunc>& call_func = db->funcs[caller.id.id];
if (!call_func)
continue;
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; continue;
Out_CqueryCallTree::CallEntry call_entry; if (caller.has_id()) {
call_entry.name = call_func->def.short_name; optional<QueryFunc>& call_func = db->funcs[caller.id_.id];
call_entry.usr = call_func->def.usr; if (!call_func)
call_entry.location = *call_location; continue;
call_entry.hasCallers = !call_func->callers.empty();
result.push_back(call_entry); Out_CqueryCallTree::CallEntry call_entry;
call_entry.name = call_func->def.short_name;
call_entry.usr = call_func->def.usr;
call_entry.location = *call_location;
call_entry.hasCallers = !call_func->callers.empty();
result.push_back(call_entry);
}
else {
// TODO: See if we can do a better job here. Need more information from
// the indexer.
Out_CqueryCallTree::CallEntry call_entry;
call_entry.name = "Likely Constructor";
call_entry.usr = "no_usr";
call_entry.location = *call_location;
call_entry.hasCallers = false;
result.push_back(call_entry);
}
} }
return result; return result;
@ -1732,7 +1745,6 @@ bool IndexMain_DoCreateIndexUpdate(
return false; return false;
Timer time; Timer time;
// TODO/FIXME: Running call tree on IndexUpdate::CreateDelta crashes cquery.
IndexUpdate update = IndexUpdate::CreateDelta(response->previous_id_map.get(), response->current_id_map.get(), IndexUpdate update = IndexUpdate::CreateDelta(response->previous_id_map.get(), response->current_id_map.get(),
response->previous_index.get(), response->current_index.get()); response->previous_index.get(), response->current_index.get());
response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset();

View File

@ -78,6 +78,7 @@ struct IdCache;
struct IndexFuncRef { struct IndexFuncRef {
// NOTE: id can be -1 if the function call is not coming from a function.
IndexFuncId id; IndexFuncId id;
Range loc; Range loc;
bool is_implicit = false; bool is_implicit = false;

View File

@ -100,26 +100,29 @@ struct SymbolRef {
MAKE_REFLECT_STRUCT(SymbolRef, idx, loc); MAKE_REFLECT_STRUCT(SymbolRef, idx, loc);
struct QueryFuncRef { struct QueryFuncRef {
QueryFuncId id; // NOTE: id_ can be -1 if the function call is not coming from a function.
QueryFuncId id_;
QueryLocation loc; QueryLocation loc;
bool is_implicit = false; bool is_implicit = false;
bool has_id() const { return id_.id != -1; }
QueryFuncRef() {} // Do not use, needed for reflect. QueryFuncRef() {} // Do not use, needed for reflect.
QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit) : id(id), loc(loc), is_implicit(is_implicit) {} QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit) : id_(id), loc(loc), is_implicit(is_implicit) {}
bool operator==(const QueryFuncRef& that) const { bool operator==(const QueryFuncRef& that) const {
return id == that.id && loc == that.loc && is_implicit == that.is_implicit; return id_ == that.id_ && loc == that.loc && is_implicit == that.is_implicit;
} }
bool operator!=(const QueryFuncRef& that) const { return !(*this == that); } bool operator!=(const QueryFuncRef& that) const { return !(*this == that); }
bool operator<(const QueryFuncRef& that) const { bool operator<(const QueryFuncRef& that) const {
if (id < that.id) if (id_ < that.id_)
return true; return true;
if (id == that.id && loc.range.start < that.loc.range.start) if (id_ == that.id_ && loc.range.start < that.loc.range.start)
return true; return true;
return id == that.id && loc.range.start == that.loc.range.start && is_implicit < that.is_implicit; return id_ == that.id_ && loc.range.start == that.loc.range.start && is_implicit < that.is_implicit;
} }
}; };
MAKE_REFLECT_STRUCT(QueryFuncRef, id, loc, is_implicit); MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc, is_implicit);
// There are two sources of reindex updates: the (single) definition of a // There are two sources of reindex updates: the (single) definition of a
// symbol has changed, or one of many users of the symbol has changed. // symbol has changed, or one of many users of the symbol has changed.
@ -298,13 +301,6 @@ struct QueryDatabase {
struct IdMap { struct IdMap {
// TODO threading model
// - [querydb] Create IdMap mapping from every id registered in local_ids
// - [indexer] Create IndexUpdate using IdMap cached state
// - [querydb] Apply IndexUpdate
//
// Then lookup in cached_* should *never* fail.
const IdCache& local_ids; const IdCache& local_ids;
QueryFileId primary_file; QueryFileId primary_file;