mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 09:31:59 +00:00
Do not remove querydb defined type/func/var if the final reference is removed from a file.
We still remove the defined type/func/var if it was defined in that file, though.
This commit is contained in:
parent
97832f2a73
commit
d47869ad0f
69
src/query.cc
69
src/query.cc
@ -21,8 +21,6 @@ namespace {
|
|||||||
optional<QueryType::DefUpdate> ToQuery(const IdMap& id_map, const IndexType::Def& type) {
|
optional<QueryType::DefUpdate> ToQuery(const IdMap& id_map, const IndexType::Def& type) {
|
||||||
if (type.detailed_name.empty())
|
if (type.detailed_name.empty())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
if (!type.definition_extent)
|
|
||||||
return nullopt;
|
|
||||||
|
|
||||||
QueryType::DefUpdate result(type.usr);
|
QueryType::DefUpdate result(type.usr);
|
||||||
result.short_name = type.short_name;
|
result.short_name = type.short_name;
|
||||||
@ -40,8 +38,6 @@ optional<QueryType::DefUpdate> ToQuery(const IdMap& id_map, const IndexType::Def
|
|||||||
optional<QueryFunc::DefUpdate> ToQuery(const IdMap& id_map, const IndexFunc::Def& func) {
|
optional<QueryFunc::DefUpdate> ToQuery(const IdMap& id_map, const IndexFunc::Def& func) {
|
||||||
if (func.detailed_name.empty())
|
if (func.detailed_name.empty())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
if (!func.definition_extent)
|
|
||||||
return nullopt;
|
|
||||||
|
|
||||||
QueryFunc::DefUpdate result(func.usr);
|
QueryFunc::DefUpdate result(func.usr);
|
||||||
result.short_name = func.short_name;
|
result.short_name = func.short_name;
|
||||||
@ -58,8 +54,6 @@ optional<QueryFunc::DefUpdate> ToQuery(const IdMap& id_map, const IndexFunc::Def
|
|||||||
optional<QueryVar::DefUpdate> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
|
optional<QueryVar::DefUpdate> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
|
||||||
if (var.detailed_name.empty())
|
if (var.detailed_name.empty())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
if (!var.definition_extent)
|
|
||||||
return nullopt;
|
|
||||||
|
|
||||||
QueryVar::DefUpdate result(var.usr);
|
QueryVar::DefUpdate result(var.usr);
|
||||||
result.short_name = var.short_name;
|
result.short_name = var.short_name;
|
||||||
@ -463,10 +457,24 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, const IdMap& current_id_m
|
|||||||
// File
|
// File
|
||||||
files_def_update.push_back(BuildFileDef(current_id_map, current_file));
|
files_def_update.push_back(BuildFileDef(current_id_map, current_file));
|
||||||
|
|
||||||
|
// **NOTE** We only remove entries if they were defined in the previous index.
|
||||||
|
// For example, if a type is included from another file it will be defined
|
||||||
|
// simply so we can attribute the usage/reference to it. If the reference goes
|
||||||
|
// away we don't want to remove the type/func/var usage.
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
CompareGroups<IndexType>(previous_file.types, current_file.types,
|
CompareGroups<IndexType>(previous_file.types, current_file.types,
|
||||||
/*onRemoved:*/[this](IndexType* def) {
|
/*onRemoved:*/[this, &previous_id_map](IndexType* type) {
|
||||||
types_removed.push_back(def->def.usr);
|
if (type->def.definition_spelling)
|
||||||
|
types_removed.push_back(type->def.usr);
|
||||||
|
else {
|
||||||
|
if (!type->derived.empty())
|
||||||
|
types_derived.push_back(QueryType::DerivedUpdate(previous_id_map.ToQuery(type->id), {}, previous_id_map.ToQuery(type->derived)));
|
||||||
|
if (!type->instances.empty())
|
||||||
|
types_instances.push_back(QueryType::InstancesUpdate(previous_id_map.ToQuery(type->id), {}, previous_id_map.ToQuery(type->instances)));
|
||||||
|
if (!type->uses.empty())
|
||||||
|
types_uses.push_back(QueryType::UsesUpdate(previous_id_map.ToQuery(type->id), {}, previous_id_map.ToQuery(type->uses)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/*onAdded:*/[this, ¤t_id_map](IndexType* type) {
|
/*onAdded:*/[this, ¤t_id_map](IndexType* type) {
|
||||||
optional<QueryType::DefUpdate> def_update = ToQuery(current_id_map, type->def);
|
optional<QueryType::DefUpdate> def_update = ToQuery(current_id_map, type->def);
|
||||||
@ -492,8 +500,18 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, const IdMap& current_id_m
|
|||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
CompareGroups<IndexFunc>(previous_file.funcs, current_file.funcs,
|
CompareGroups<IndexFunc>(previous_file.funcs, current_file.funcs,
|
||||||
/*onRemoved:*/[this](IndexFunc* def) {
|
/*onRemoved:*/[this, &previous_id_map](IndexFunc* func) {
|
||||||
funcs_removed.push_back(def->def.usr);
|
if (func->def.definition_spelling) {
|
||||||
|
funcs_removed.push_back(func->def.usr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!func->declarations.empty())
|
||||||
|
funcs_declarations.push_back(QueryFunc::DeclarationsUpdate(previous_id_map.ToQuery(func->id), {}, previous_id_map.ToQuery(func->declarations)));
|
||||||
|
if (!func->derived.empty())
|
||||||
|
funcs_derived.push_back(QueryFunc::DerivedUpdate(previous_id_map.ToQuery(func->id), {}, previous_id_map.ToQuery(func->derived)));
|
||||||
|
if (!func->callers.empty())
|
||||||
|
funcs_callers.push_back(QueryFunc::CallersUpdate(previous_id_map.ToQuery(func->id), {}, previous_id_map.ToQuery(func->callers)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/*onAdded:*/[this, ¤t_id_map](IndexFunc* func) {
|
/*onAdded:*/[this, ¤t_id_map](IndexFunc* func) {
|
||||||
optional<QueryFunc::DefUpdate> def_update = ToQuery(current_id_map, func->def);
|
optional<QueryFunc::DefUpdate> def_update = ToQuery(current_id_map, func->def);
|
||||||
@ -519,8 +537,14 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map, const IdMap& current_id_m
|
|||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
CompareGroups<IndexVar>(previous_file.vars, current_file.vars,
|
CompareGroups<IndexVar>(previous_file.vars, current_file.vars,
|
||||||
/*onRemoved:*/[this](IndexVar* def) {
|
/*onRemoved:*/[this, &previous_id_map](IndexVar* var) {
|
||||||
vars_removed.push_back(def->def.usr);
|
if (var->def.definition_spelling) {
|
||||||
|
vars_removed.push_back(var->def.usr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!var->uses.empty())
|
||||||
|
vars_uses.push_back(QueryVar::UsesUpdate(previous_id_map.ToQuery(var->id), {}, previous_id_map.ToQuery(var->uses)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/*onAdded:*/[this, ¤t_id_map](IndexVar* var) {
|
/*onAdded:*/[this, ¤t_id_map](IndexVar* var) {
|
||||||
optional<QueryVar::DefUpdate> def_update = ToQuery(current_id_map, var->def);
|
optional<QueryVar::DefUpdate> def_update = ToQuery(current_id_map, var->def);
|
||||||
@ -799,9 +823,9 @@ TEST_CASE("remove defs") {
|
|||||||
IndexFile previous("foo.cc");
|
IndexFile previous("foo.cc");
|
||||||
IndexFile current("foo.cc");
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
previous.ToTypeId("usr1");
|
previous.Resolve(previous.ToTypeId("usr1"))->def.definition_spelling = Range(Position(1, 0));
|
||||||
previous.ToFuncId("usr2");
|
previous.Resolve(previous.ToFuncId("usr2"))->def.definition_spelling = Range(Position(2, 0));
|
||||||
previous.ToVarId("usr3");
|
previous.Resolve(previous.ToVarId("usr3"))->def.definition_spelling = Range(Position(3, 0));
|
||||||
|
|
||||||
IndexUpdate update = GetDelta(previous, current);
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
@ -810,6 +834,21 @@ TEST_CASE("remove defs") {
|
|||||||
REQUIRE(update.vars_removed == std::vector<Usr>{ "usr3" });
|
REQUIRE(update.vars_removed == std::vector<Usr>{ "usr3" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("do not remove ref-only defs") {
|
||||||
|
IndexFile previous("foo.cc");
|
||||||
|
IndexFile current("foo.cc");
|
||||||
|
|
||||||
|
previous.Resolve(previous.ToTypeId("usr1"))->uses.push_back(Range(Position(1, 0)));
|
||||||
|
previous.Resolve(previous.ToFuncId("usr2"))->callers.push_back(IndexFuncRef(IndexFuncId(0), Range(Position(2, 0)), false /*is_implicit*/));
|
||||||
|
previous.Resolve(previous.ToVarId("usr3"))->uses.push_back(Range(Position(3, 0)));
|
||||||
|
|
||||||
|
IndexUpdate update = GetDelta(previous, current);
|
||||||
|
|
||||||
|
REQUIRE(update.types_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.funcs_removed == std::vector<Usr>{});
|
||||||
|
REQUIRE(update.vars_removed == std::vector<Usr>{});
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("func callers") {
|
TEST_CASE("func callers") {
|
||||||
IndexFile previous("foo.cc");
|
IndexFile previous("foo.cc");
|
||||||
IndexFile current("foo.cc");
|
IndexFile current("foo.cc");
|
||||||
|
Loading…
Reference in New Issue
Block a user