We may should represent Query{Func,Type,Var} as a bag of definitions and references

This commit is contained in:
Fangrui Song 2018-02-05 10:12:28 -08:00
parent cd96cb9570
commit 1a82f1f113
12 changed files with 63 additions and 192 deletions

View File

@ -39,13 +39,13 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
if (!type.def)
continue;
std::vector<QueryLocation> locations =
ToQueryLocation(db, &type.def->parents);
ToQueryLocation(db, type.def->parents);
out.result = GetLsLocations(db, working_files, locations);
break;
} else if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
std::vector<QueryLocation> locations =
ToQueryLocation(db, &func.def->base);
ToQueryLocation(db, func.def->base);
out.result = GetLsLocations(db, working_files, locations);
break;
}

View File

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

View File

@ -66,7 +66,7 @@ ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
entry.name = var.def->ShortName();
// FIXME WithGen
entry.type_id =
var.def->variable_type ? var.def->variable_type->value.id : RawId(-1);
var.def->variable_type ? var.def->variable_type->id : RawId(-1);
if (var.def->definition_spelling) {
optional<lsLocation> loc =
GetLsLocation(db, working_files, *var.def->definition_spelling);
@ -101,7 +101,7 @@ struct CqueryMemberHierarchyInitialHandler
if (ref.idx.kind == SymbolKind::Var) {
QueryVar& var = db->vars[ref.idx.idx];
if (var.def && var.def->variable_type)
out.result = BuildInitial(db, working_files, var.def->variable_type->value);
out.result = BuildInitial(db, working_files, *var.def->variable_type);
break;
}
}

View File

@ -95,7 +95,7 @@ BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
// FIXME WithGen
for (auto parent_id : root_func.def->base) {
QueryFunc& parent_func = db->funcs[parent_id.value.id];
QueryFunc& parent_func = db->funcs[parent_id.id];
if (!parent_func.def)
continue;
@ -105,7 +105,7 @@ BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
parent_entry.location = GetLsLocation(
db, working_files, *parent_func.def->definition_spelling);
parent_entry.children =
BuildParentInheritanceHierarchyForFunc(db, working_files, parent_id.value);
BuildParentInheritanceHierarchyForFunc(db, working_files, parent_id);
entries.push_back(parent_entry);
}
@ -141,10 +141,9 @@ BuildInheritanceHierarchyForFunc(QueryDatabase* db,
entry.children.push_back(base);
// Add derived.
// FIXME WithGen
for (auto derived : root_func.derived) {
auto derived_entry =
BuildInheritanceHierarchyForFunc(db, working_files, derived.value);
BuildInheritanceHierarchyForFunc(db, working_files, derived);
if (derived_entry)
entry.children.push_back(*derived_entry);
}

View File

@ -33,13 +33,13 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
QueryVar& var = db->vars[id];
if (!var.def || !var.def->variable_type)
continue;
id = var.def->variable_type->value.id;
id = var.def->variable_type->id;
}
// fallthrough
case SymbolKind::Type: {
QueryType& type = db->types[id];
std::vector<QueryLocation> locations =
ToQueryLocation(db, &type.instances);
ToQueryLocation(db, type.instances);
out.result = GetLsLocations(db, working_files, locations);
break;
}

View File

@ -159,7 +159,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
optional<std::string> type_name;
optional<lsPosition> same_file_insert_end;
if (func.def->declaring_type) {
QueryType& declaring_type = db->types[func.def->declaring_type->value.id];
QueryType& declaring_type = db->types[func.def->declaring_type->id];
if (declaring_type.def) {
type_name = std::string(declaring_type.def->ShortName());
optional<lsRange> ls_type_def_extent = GetLsRange(

View File

@ -159,10 +159,10 @@ struct TextDocumentCodeLensHandler
true /*force_display*/);
AddCodeLens("derived", "derived", &common,
ref.loc.OffsetStartColumn(1),
ToQueryLocation(db, &type.derived), nullopt,
ToQueryLocation(db, type.derived), nullopt,
false /*force_display*/);
AddCodeLens("var", "vars", &common, ref.loc.OffsetStartColumn(2),
ToQueryLocation(db, &type.instances), nullopt,
ToQueryLocation(db, type.instances), nullopt,
false /*force_display*/);
break;
}
@ -216,14 +216,14 @@ struct TextDocumentCodeLensHandler
AddCodeLens("derived", "derived", &common,
ref.loc.OffsetStartColumn(offset++),
ToQueryLocation(db, &func.derived), nullopt,
ToQueryLocation(db, func.derived), nullopt,
false /*force_display*/);
// "Base"
if (func.def->base.size() == 1) {
// FIXME WithGen
optional<QueryLocation> base_loc =
GetDefinitionSpellingOfSymbol(db, func.def->base[0].value);
GetDefinitionSpellingOfSymbol(db, func.def->base[0]);
if (base_loc) {
optional<lsLocation> ls_base =
GetLsLocation(db, working_files, *base_loc);
@ -245,7 +245,7 @@ struct TextDocumentCodeLensHandler
}
} else {
AddCodeLens("base", "base", &common, ref.loc.OffsetStartColumn(1),
ToQueryLocation(db, &func.def->base), nullopt,
ToQueryLocation(db, func.def->base), nullopt,
false /*force_display*/);
}

View File

@ -36,7 +36,7 @@ std::vector<QueryLocation> GetGotoDefinitionTargets(QueryDatabase* db,
if (var.def && var.def->variable_type) {
std::vector<QueryLocation> types =
GetDeclarationsOfSymbolForGotoDefinition(
db, SymbolIdx(SymbolKind::Type, var.def->variable_type->value.id));
db, SymbolIdx(SymbolKind::Type, var.def->variable_type->id));
ret.insert(ret.end(), types.begin(), types.end());
}
return ret;

View File

@ -44,11 +44,11 @@ optional<QueryType::Def> ToQuery(const IdMap& id_map,
result.comments = type.comments;
result.definition_spelling = id_map.ToQuery(type.definition_spelling);
result.definition_extent = id_map.ToQuery(type.definition_extent);
result.alias_of = id_map.ToQuery(type.alias_of,0);
result.parents = id_map.ToQuery(type.parents,0);
result.types = id_map.ToQuery(type.types,0);
result.funcs = id_map.ToQuery(type.funcs,0);
result.vars = id_map.ToQuery(type.vars,0);
result.alias_of = id_map.ToQuery(type.alias_of);
result.parents = id_map.ToQuery(type.parents);
result.types = id_map.ToQuery(type.types);
result.funcs = id_map.ToQuery(type.funcs);
result.vars = id_map.ToQuery(type.vars);
return result;
}
@ -67,9 +67,9 @@ optional<QueryFunc::Def> ToQuery(const IdMap& id_map,
result.comments = func.comments;
result.definition_spelling = id_map.ToQuery(func.definition_spelling);
result.definition_extent = id_map.ToQuery(func.definition_extent);
result.declaring_type = id_map.ToQuery(func.declaring_type,0);
result.base = id_map.ToQuery(func.base,0);
result.locals = id_map.ToQuery(func.locals,0);
result.declaring_type = id_map.ToQuery(func.declaring_type);
result.base = id_map.ToQuery(func.base);
result.locals = id_map.ToQuery(func.locals);
result.callees = id_map.ToQuery(func.callees);
return result;
}
@ -86,7 +86,7 @@ optional<QueryVar::Def> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
result.comments = var.comments;
result.definition_spelling = id_map.ToQuery(var.definition_spelling);
result.definition_extent = id_map.ToQuery(var.definition_extent);
result.variable_type = id_map.ToQuery(var.variable_type,0);
result.variable_type = id_map.ToQuery(var.variable_type);
result.parent_id = var.parent_id;
result.parent_kind = var.parent_kind;
result.kind = var.kind;
@ -355,64 +355,6 @@ Maybe<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
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());
}
void UpdateGen(QueryDatabase* db, WithGen<QueryFuncId>& ref) {
ref.gen = db->funcs[ref.value.id].gen;
}
void UpdateGen(QueryDatabase* db, WithGen<QueryTypeId>& ref) {
ref.gen = db->types[ref.value.id].gen;
}
void UpdateGen(QueryDatabase* db, WithGen<QueryVarId>& ref) {
ref.gen = db->vars[ref.value.id].gen;
}
template <typename T>
void UpdateGen(QueryDatabase* db, Maybe<T>& ref) {
if (ref)
UpdateGen(db, *ref);
}
template <typename T>
void UpdateGen(QueryDatabase* db, std::vector<T>& ref) {
for (T& x : ref)
UpdateGen(db, x);
}
void UpdateGen(QueryDatabase* db, QueryFunc::Def& def) {
UpdateGen(db, def.declaring_type);
UpdateGen(db, def.base);
UpdateGen(db, def.locals);
}
void UpdateGen(QueryDatabase* db, QueryType::Def& def) {
UpdateGen(db, def.alias_of);
UpdateGen(db, def.parents);
UpdateGen(db, def.funcs);
UpdateGen(db, def.types);
UpdateGen(db, def.vars);
}
void UpdateGen(QueryDatabase* db, QueryVar::Def& def) {
UpdateGen(db, def.variable_type);
}
} // namespace
template <>
@ -476,20 +418,6 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
assert(cached_var_ids_.find(id) != cached_var_ids_.end());
return QueryVarId(cached_var_ids_.find(id)->second);
}
WithGen<QueryTypeId> IdMap::ToQuery(IndexTypeId id,int) const {
assert(cached_type_ids_.find(id) != cached_type_ids_.end());
return QueryTypeId(cached_type_ids_.find(id)->second);
}
WithGen<QueryFuncId> IdMap::ToQuery(IndexFuncId id,int) const {
if (id == IndexFuncId())
return QueryFuncId();
assert(cached_func_ids_.find(id) != cached_func_ids_.end());
return QueryFuncId(cached_func_ids_.find(id)->second);
}
WithGen<QueryVarId> IdMap::ToQuery(IndexVarId id,int) const {
assert(cached_var_ids_.find(id) != cached_var_ids_.end());
return QueryVarId(cached_var_ids_.find(id)->second);
}
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
return QueryFuncRef(ToQuery(ref.id), ToQuery(ref.loc), ref.is_implicit);
}
@ -857,13 +785,6 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) {
RemoveRange(&def.def_var_name, merge_update.to_remove); \
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)
files[usr_to_file[NormalizedPath(filename)].id].def = nullopt;
@ -871,14 +792,14 @@ void QueryDatabase::ApplyIndexUpdate(IndexUpdate* update) {
RemoveUsrs(SymbolKind::Type, update->types_removed);
ImportOrUpdate(update->types_def_update);
HANDLE_MERGEABLE_WITH_GEN(types_derived, derived, types);
HANDLE_MERGEABLE_WITH_GEN(types_instances, instances, types);
HANDLE_MERGEABLE(types_derived, derived, types);
HANDLE_MERGEABLE(types_instances, instances, types);
HANDLE_MERGEABLE(types_uses, uses, types);
RemoveUsrs(SymbolKind::Func, update->funcs_removed);
ImportOrUpdate(update->funcs_def_update);
HANDLE_MERGEABLE(funcs_declarations, declarations, funcs);
HANDLE_MERGEABLE_WITH_GEN(funcs_derived, derived, funcs);
HANDLE_MERGEABLE(funcs_derived, derived, funcs);
HANDLE_MERGEABLE(funcs_callers, callers, funcs);
RemoveUsrs(SymbolKind::Var, update->vars_removed);
@ -925,7 +846,6 @@ void QueryDatabase::ImportOrUpdate(
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type,
it->second.id);
}
UpdateGen(this, *existing.def);
}
}
@ -949,7 +869,6 @@ void QueryDatabase::ImportOrUpdate(
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func,
it->second.id);
}
UpdateGen(this, *existing.def);
}
}
@ -974,7 +893,6 @@ void QueryDatabase::ImportOrUpdate(
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var,
it->second.id);
}
UpdateGen(this, *existing.def);
}
}

View File

@ -249,9 +249,9 @@ MAKE_REFLECT_STRUCT(QueryFile::Def,
dependencies);
struct QueryType {
using Def = TypeDefDefinitionData<WithGen<QueryTypeId>,
WithGen<QueryFuncId>,
WithGen<QueryVarId>,
using Def = TypeDefDefinitionData<QueryTypeId,
QueryFuncId,
QueryVarId,
QueryLocation>;
using DefUpdate = WithUsr<Def>;
using DerivedUpdate = MergeableUpdate<QueryTypeId, QueryTypeId>;
@ -262,17 +262,17 @@ struct QueryType {
Generation gen;
Maybe<Id<void>> symbol_idx;
optional<Def> def;
std::vector<WithGen<QueryTypeId>> derived;
std::vector<WithGen<QueryVarId>> instances;
std::vector<QueryTypeId> derived;
std::vector<QueryVarId> instances;
std::vector<QueryLocation> uses;
explicit QueryType(const Usr& usr) : usr(usr), gen(0) {}
};
struct QueryFunc {
using Def = FuncDefDefinitionData<WithGen<QueryTypeId>,
WithGen<QueryFuncId>,
WithGen<QueryVarId>,
using Def = FuncDefDefinitionData<QueryTypeId,
QueryFuncId,
QueryVarId,
QueryFuncRef,
QueryLocation>;
using DefUpdate = WithUsr<Def>;
@ -285,16 +285,16 @@ struct QueryFunc {
Maybe<Id<void>> symbol_idx;
optional<Def> def;
std::vector<QueryLocation> declarations;
std::vector<WithGen<QueryFuncId>> derived;
std::vector<QueryFuncId> derived;
std::vector<QueryFuncRef> callers;
explicit QueryFunc(const Usr& usr) : usr(usr), gen(0) {}
};
struct QueryVar {
using Def = VarDefDefinitionData<WithGen<QueryTypeId>,
WithGen<QueryFuncId>,
WithGen<QueryVarId>,
using Def = VarDefDefinitionData<QueryTypeId,
QueryFuncId,
QueryVarId,
QueryLocation>;
using DefUpdate = WithUsr<Def>;
using DeclarationsUpdate = MergeableUpdate<QueryVarId, QueryLocation>;
@ -452,9 +452,6 @@ struct IdMap {
QueryTypeId ToQuery(IndexTypeId id) const;
QueryFuncId ToQuery(IndexFuncId id) const;
QueryVarId ToQuery(IndexVarId id) const;
WithGen<QueryTypeId> ToQuery(IndexTypeId id, int) const;
WithGen<QueryFuncId> ToQuery(IndexFuncId id, int) const;
WithGen<QueryVarId> ToQuery(IndexVarId id, int) const;
QueryFuncRef ToQuery(IndexFuncRef ref) const;
QueryLocation ToQuery(IndexFunc::Declaration decl) const;
template <typename I>

View File

@ -14,25 +14,16 @@ int ComputeRangeSize(const Range& range) {
}
template <typename Q>
std::vector<QueryLocation> ToQueryLocation(
std::vector<QueryLocation> ToQueryLocationHelper(
QueryDatabase* db,
std::vector<Q> QueryDatabase::*collection,
std::vector<WithGen<Id<Q>>>* ids_) {
auto& ids = *ids_;
const std::vector<Id<Q>>& 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];
}
for (auto id : ids) {
optional<QueryLocation> loc = GetDefinitionSpellingOfSymbol(db, id);
if (loc)
locs.push_back(*loc);
}
ids.resize(j);
return locs;
}
@ -171,42 +162,17 @@ std::vector<QueryLocation> ToQueryLocation(
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryTypeId>& ids) {
std::vector<QueryLocation> locs;
locs.reserve(ids.size());
for (const QueryTypeId& id : ids) {
optional<QueryLocation> loc = GetDefinitionSpellingOfSymbol(db, id);
if (loc)
locs.push_back(loc.value());
}
return locs;
return ToQueryLocationHelper(db, ids);
}
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryFuncId>& ids) {
std::vector<QueryLocation> locs;
locs.reserve(ids.size());
for (const QueryFuncId& id : ids) {
optional<QueryLocation> loc = GetDefinitionSpellingOfSymbol(db, id);
if (loc)
locs.push_back(loc.value());
}
return locs;
}
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
std::vector<WithGen<QueryFuncId>>* ids_) {
return ToQueryLocation(db, &QueryDatabase::funcs, ids_);
return ToQueryLocationHelper(db, ids);
}
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
std::vector<WithGen<QueryTypeId>>* ids_) {
return ToQueryLocation(db, &QueryDatabase::types, ids_);
}
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
std::vector<WithGen<QueryVarId>>* ids_) {
return ToQueryLocation(db, &QueryDatabase::vars, ids_);
const std::vector<QueryVarId>& ids) {
return ToQueryLocationHelper(db, ids);
}
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,
@ -514,8 +480,7 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
info.kind = lsSymbolKind::Function;
if (func.def->declaring_type.has_value()) {
// FIXME WithGen
QueryType& container = db->types[func.def->declaring_type->value.id];
QueryType& container = db->types[func.def->declaring_type->id];
if (container.def)
info.kind = lsSymbolKind::Method;
}

View File

@ -25,12 +25,9 @@ std::vector<QueryLocation> ToQueryLocation(
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryTypeId>& refs);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
std::vector<WithGen<QueryFuncId>>*);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
std::vector<WithGen<QueryTypeId>>*);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
std::vector<WithGen<QueryVarId>>*);
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryVarId>& refs);
std::vector<QueryLocation> ToQueryLocation(QueryDatabase* db,
const std::vector<QueryFuncId>& ids);
std::vector<QueryLocation> GetUsesOfSymbol(QueryDatabase* db,
@ -74,8 +71,8 @@ void EmitDiagnostics(WorkingFiles* working_files,
std::vector<lsDiagnostic> diagnostics);
template <typename Q, typename Fn>
void EachWithGen(std::vector<Q>& collection, WithGen<Id<Q>> x, Fn fn) {
Q& obj = collection[x.value.id];
void EachWithGen(std::vector<Q>& collection, Id<Q> x, Fn fn) {
Q& obj = collection[x.id];
// FIXME Deprecate optional<Def> def
// if (obj.gen == x.gen && obj.def)
if (obj.def)
@ -83,15 +80,10 @@ void EachWithGen(std::vector<Q>& collection, WithGen<Id<Q>> x, Fn fn) {
}
template <typename Q, typename Fn>
void EachWithGen(std::vector<Q>& collection, std::vector<WithGen<Id<Q>>>& ids, Fn fn) {
size_t j = 0;
for (WithGen<Id<Q>> x : ids) {
Q& obj = collection[x.value.id];
if (1 /*obj.gen == x.gen*/) {
if (obj.def) // FIXME Deprecate optional<Def> def
fn(obj);
ids[j++] = x;
}
void EachWithGen(std::vector<Q>& collection, std::vector<Id<Q>>& ids, Fn fn) {
for (Id<Q> x : ids) {
Q& obj = collection[x.id];
if (obj.def) // FIXME Deprecate optional<Def> def
fn(obj);
}
ids.resize(j);
}