Add Generation gen; to Query{Func,Type,Var} and corresponding ToQueryLocation

This commit is contained in:
Fangrui Song 2018-02-03 13:12:03 -08:00
parent 54c587a700
commit 3d6d000297
8 changed files with 102 additions and 33 deletions

View File

@ -37,7 +37,7 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
if (ref.idx.kind == SymbolKind::Type) { if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx]; QueryType& type = db->types[ref.idx.idx];
std::vector<QueryLocation> locations = std::vector<QueryLocation> locations =
ToQueryLocation(db, type.derived); ToQueryLocation(db, &type.derived);
out.result = GetLsLocations(db, working_files, locations); out.result = GetLsLocations(db, working_files, locations);
break; break;
} else if (ref.idx.kind == SymbolKind::Func) { } else if (ref.idx.kind == SymbolKind::Func) {

View File

@ -85,12 +85,15 @@ BuildInheritanceHierarchyForType(QueryDatabase* db,
entry.children.push_back(base); entry.children.push_back(base);
// Add derived. // Add derived.
for (QueryTypeId derived : root_type.derived) { for (WithGen<QueryTypeId> derived : root_type.derived) {
QueryType& type = db->types[derived.value.id];
if (derived.gen == type.gen) {
auto derived_entry = auto derived_entry =
BuildInheritanceHierarchyForType(db, working_files, derived); BuildInheritanceHierarchyForType(db, working_files, derived.value);
if (derived_entry) if (derived_entry)
entry.children.push_back(*derived_entry); entry.children.push_back(*derived_entry);
} }
}
return entry; return entry;
} }

View File

@ -39,7 +39,7 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->types[id]; QueryType& type = db->types[id];
std::vector<QueryLocation> locations = std::vector<QueryLocation> locations =
ToQueryLocation(db, type.instances); ToQueryLocation(db, &type.instances);
out.result = GetLsLocations(db, working_files, locations); out.result = GetLsLocations(db, working_files, locations);
break; break;
} }

View File

@ -159,10 +159,10 @@ struct TextDocumentCodeLensHandler
true /*force_display*/); true /*force_display*/);
AddCodeLens("derived", "derived", &common, AddCodeLens("derived", "derived", &common,
ref.loc.OffsetStartColumn(1), ref.loc.OffsetStartColumn(1),
ToQueryLocation(db, type.derived), nullopt, ToQueryLocation(db, &type.derived), nullopt,
false /*force_display*/); false /*force_display*/);
AddCodeLens("var", "vars", &common, ref.loc.OffsetStartColumn(2), AddCodeLens("var", "vars", &common, ref.loc.OffsetStartColumn(2),
ToQueryLocation(db, type.instances), nullopt, ToQueryLocation(db, &type.instances), nullopt,
false /*force_display*/); false /*force_display*/);
break; break;
} }

View File

@ -355,6 +355,24 @@ Maybe<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
return QueryVarId(idx); return QueryVarId(idx);
} }
template <typename T>
void AddRangeWithGen(std::vector<WithGen<T>>* dest, const std::vector<T>& to_add, Generation gen) {
for (auto& x : to_add)
dest->push_back(WithGen<T>{gen, x});
}
template <typename T>
void RemoveRangeWithGen(std::vector<WithGen<T>>* dest, const std::vector<T>& to_remove) {
dest->erase(std::remove_if(dest->begin(), dest->end(),
[&](const WithGen<T>& t) {
// TODO: make to_remove a set?
return std::find(to_remove.begin(),
to_remove.end(),
t.value) != to_remove.end();
}),
dest->end());
}
} // namespace } // namespace
template <> template <>
@ -797,6 +815,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryType& type = types[usr_to_type[usr].id]; QueryType& type = types[usr_to_type[usr].id];
if (type.symbol_idx) if (type.symbol_idx)
symbols[type.symbol_idx->id].kind = SymbolKind::Invalid; symbols[type.symbol_idx->id].kind = SymbolKind::Invalid;
type.gen++;
type.def = nullopt; type.def = nullopt;
} }
break; break;
@ -806,6 +825,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryFunc& func = funcs[usr_to_func[usr].id]; QueryFunc& func = funcs[usr_to_func[usr].id];
if (func.symbol_idx) if (func.symbol_idx)
symbols[func.symbol_idx->id].kind = SymbolKind::Invalid; symbols[func.symbol_idx->id].kind = SymbolKind::Invalid;
func.gen++;
func.def = nullopt; func.def = nullopt;
} }
break; break;
@ -815,6 +835,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryVar& var = vars[usr_to_var[usr].id]; QueryVar& var = vars[usr_to_var[usr].id];
if (var.symbol_idx) if (var.symbol_idx)
symbols[var.symbol_idx->id].kind = SymbolKind::Invalid; symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
var.gen++;
var.def = nullopt; var.def = nullopt;
} }
break; break;
@ -840,6 +861,13 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) {
RemoveRange(&def.def_var_name, merge_update.to_remove); \ RemoveRange(&def.def_var_name, merge_update.to_remove); \
VerifyUnique(def.def_var_name); \ VerifyUnique(def.def_var_name); \
} }
#define HANDLE_MERGEABLE_WITH_GEN(update_var_name, def_var_name, storage_name) \
for (auto merge_update : update->update_var_name) { \
auto& def = storage_name[merge_update.id.id]; \
AddRangeWithGen(&def.def_var_name, merge_update.to_add, def.gen); \
RemoveRangeWithGen(&def.def_var_name, merge_update.to_remove); \
VerifyUnique(def.def_var_name); \
}
for (const std::string& filename : update->files_removed) for (const std::string& filename : update->files_removed)
files[usr_to_file[NormalizedPath(filename)].id].def = nullopt; files[usr_to_file[NormalizedPath(filename)].id].def = nullopt;
@ -847,8 +875,8 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) {
RemoveUsrs(SymbolKind::Type, update->types_removed); RemoveUsrs(SymbolKind::Type, update->types_removed);
ImportOrUpdate(update->types_def_update); ImportOrUpdate(update->types_def_update);
HANDLE_MERGEABLE(types_derived, derived, types); HANDLE_MERGEABLE_WITH_GEN(types_derived, derived, types);
HANDLE_MERGEABLE(types_instances, instances, types); HANDLE_MERGEABLE_WITH_GEN(types_instances, instances, types);
HANDLE_MERGEABLE(types_uses, uses, types); HANDLE_MERGEABLE(types_uses, uses, types);
RemoveUsrs(SymbolKind::Func, update->funcs_removed); RemoveUsrs(SymbolKind::Func, update->funcs_removed);

View File

@ -18,6 +18,14 @@ using QueryTypeId = Id<QueryType>;
using QueryFuncId = Id<QueryFunc>; using QueryFuncId = Id<QueryFunc>;
using QueryVarId = Id<QueryVar>; using QueryVarId = Id<QueryVar>;
using Generation = uint32_t;
template <typename T>
struct WithGen {
Generation gen;
T value;
};
struct IdMap; struct IdMap;
struct QueryLocation { struct QueryLocation {
@ -239,13 +247,14 @@ struct QueryType {
using UsesUpdate = MergeableUpdate<QueryTypeId, QueryLocation>; using UsesUpdate = MergeableUpdate<QueryTypeId, QueryLocation>;
Usr usr; Usr usr;
optional<Def> def; Generation gen;
std::vector<QueryTypeId> derived;
std::vector<QueryVarId> instances;
std::vector<QueryLocation> uses;
Maybe<Id<void>> symbol_idx; Maybe<Id<void>> symbol_idx;
optional<Def> def;
std::vector<WithGen<QueryTypeId>> derived;
std::vector<WithGen<QueryVarId>> instances;
std::vector<QueryLocation> uses;
explicit QueryType(const Usr& usr) : usr(usr) {} explicit QueryType(const Usr& usr) : usr(usr), gen(0) {}
}; };
struct QueryFunc { struct QueryFunc {
@ -260,13 +269,14 @@ struct QueryFunc {
using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>; using CallersUpdate = MergeableUpdate<QueryFuncId, QueryFuncRef>;
Usr usr; Usr usr;
Generation gen;
Maybe<Id<void>> symbol_idx;
optional<Def> def; optional<Def> def;
std::vector<QueryLocation> declarations; std::vector<QueryLocation> declarations;
std::vector<QueryFuncId> derived; std::vector<QueryFuncId> derived;
std::vector<QueryFuncRef> callers; std::vector<QueryFuncRef> callers;
Maybe<Id<void>> symbol_idx;
explicit QueryFunc(const Usr& usr) : usr(usr) {} explicit QueryFunc(const Usr& usr) : usr(usr), gen(0) {}
}; };
struct QueryVar { struct QueryVar {
@ -277,12 +287,13 @@ struct QueryVar {
using UsesUpdate = MergeableUpdate<QueryVarId, QueryLocation>; using UsesUpdate = MergeableUpdate<QueryVarId, QueryLocation>;
Usr usr; Usr usr;
Generation gen;
Maybe<Id<void>> symbol_idx;
optional<Def> def; optional<Def> def;
std::vector<QueryLocation> declarations; std::vector<QueryLocation> declarations;
std::vector<QueryLocation> uses; std::vector<QueryLocation> uses;
Maybe<Id<void>> symbol_idx;
explicit QueryVar(const Usr& usr) : usr(usr) {} explicit QueryVar(const Usr& usr) : usr(usr), gen(0) {}
}; };
struct IndexUpdate { struct IndexUpdate {

View File

@ -13,6 +13,29 @@ int ComputeRangeSize(const Range& range) {
return range.end.column - range.start.column; return range.end.column - range.start.column;
} }
template <typename Q>
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
std::vector<Q> QueryDatabase::*collection,
std::vector<WithGen<Id<Q>>>* ids_) {
auto& ids = *ids_;
std::vector<QueryLocation> locs;
locs.reserve(ids.size());
size_t j = 0;
for (size_t i = 0; i < ids.size(); i++) {
Q& obj = (db->*collection)[ids[i].value.id];
if (obj.gen == ids[i].gen) {
optional<QueryLocation> loc =
GetDefinitionSpellingOfSymbol(db, ids[i].value);
if (loc)
locs.push_back(*loc);
ids[j++] = ids[i];
}
}
ids.resize(j);
return locs;
}
} // namespace } // namespace
optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db, optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
@ -169,16 +192,16 @@ std::vector<QueryLocation> ToQueryLocation(
} }
return locs; return locs;
} }
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
const std::vector<QueryVarId>& ids) { std::vector<QueryLocation> ToQueryLocation(
std::vector<QueryLocation> locs; QueryDatabase* db,
locs.reserve(ids.size()); std::vector<WithGen<QueryTypeId>>* ids_) {
for (const QueryVarId& id : ids) { return ToQueryLocation(db, &QueryDatabase::types, ids_);
optional<QueryLocation> loc = GetDefinitionSpellingOfSymbol(db, id); }
if (loc) std::vector<QueryLocation> ToQueryLocation(
locs.push_back(loc.value()); QueryDatabase* db,
} std::vector<WithGen<QueryVarId>>* ids_) {
return locs; return ToQueryLocation(db, &QueryDatabase::vars, ids_);
} }
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db, std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,

View File

@ -22,12 +22,16 @@ optional<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
std::vector<QueryLocation> ToQueryLocation( std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db, QueryDatabase* db,
const std::vector<QueryFuncRef>& refs); const std::vector<QueryFuncRef>& refs);
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryTypeId>& refs);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db, std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
const std::vector<QueryTypeId>& ids); std::vector<WithGen<QueryTypeId>>*);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db, std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
const std::vector<QueryFuncId>& ids); const std::vector<QueryFuncId>& ids);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db, std::vector<QueryLocation> ToQueryLocation(
const std::vector<QueryVarId>& ids); QueryDatabase* db,
std::vector<WithGen<QueryVarId>>*);
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db, std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,
const SymbolIdx& symbol, const SymbolIdx& symbol,
bool include_decl); bool include_decl);