mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-07 17:32:14 +00:00
wip
This commit is contained in:
parent
18aa28bdea
commit
aa677de886
10
indexer.cpp
10
indexer.cpp
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
IndexedFile::IndexedFile(IdCache* id_cache)
|
IndexedFile::IndexedFile(const std::string& path, IdCache* id_cache)
|
||||||
: id_cache(id_cache) {
|
: path(path), id_cache(id_cache) {
|
||||||
|
|
||||||
// TODO: Reconsider if we should still be reusing the same id_cache.
|
// TODO: Reconsider if we should still be reusing the same id_cache.
|
||||||
// Preallocate any existing resolved ids.
|
// Preallocate any existing resolved ids.
|
||||||
@ -85,7 +85,7 @@ std::string IndexedFile::ToString() {
|
|||||||
return output.GetString();
|
return output.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexedTypeDef::IndexedTypeDef(TypeId id, const std::string& usr) : def(id, usr) {
|
IndexedTypeDef::IndexedTypeDef(TypeId id, const std::string& usr) : id(id), def(usr) {
|
||||||
assert(usr.size() > 0);
|
assert(usr.size() > 0);
|
||||||
//std::cout << "Creating type with usr " << usr << std::endl;
|
//std::cout << "Creating type with usr " << usr << std::endl;
|
||||||
}
|
}
|
||||||
@ -849,7 +849,7 @@ IndexedFile Parse(IdCache* id_cache, std::string filename, std::vector<std::stri
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
IndexedFile db(id_cache);
|
IndexedFile db(filename, id_cache);
|
||||||
NamespaceHelper ns;
|
NamespaceHelper ns;
|
||||||
IndexParam param(&db, &ns);
|
IndexParam param(&db, &ns);
|
||||||
clang_indexTranslationUnit(index_action, ¶m, callbacks, sizeof(callbacks),
|
clang_indexTranslationUnit(index_action, ¶m, callbacks, sizeof(callbacks),
|
||||||
@ -951,7 +951,7 @@ void WriteToFile(const std::string& filename, const std::string& content) {
|
|||||||
file << content;
|
file << content;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main55555(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// TODO: Assert that we need to be on clang >= 3.9.1
|
// TODO: Assert that we need to be on clang >= 3.9.1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
54
indexer.h
54
indexer.h
@ -92,7 +92,7 @@ struct Location {
|
|||||||
this->column = column;
|
this->column = column;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileId file_id() {
|
FileId file_id() const {
|
||||||
return FileId(raw_file_id, raw_file_group);
|
return FileId(raw_file_id, raw_file_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,6 @@ using VarRef = Ref<IndexedVarDef>;
|
|||||||
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
|
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
|
||||||
struct TypeDefDefinitionData {
|
struct TypeDefDefinitionData {
|
||||||
// General metadata.
|
// General metadata.
|
||||||
TypeId id;
|
|
||||||
std::string usr;
|
std::string usr;
|
||||||
std::string short_name;
|
std::string short_name;
|
||||||
std::string qualified_name;
|
std::string qualified_name;
|
||||||
@ -277,11 +276,10 @@ struct TypeDefDefinitionData {
|
|||||||
std::vector<FuncId> funcs;
|
std::vector<FuncId> funcs;
|
||||||
std::vector<VarId> vars;
|
std::vector<VarId> vars;
|
||||||
|
|
||||||
TypeDefDefinitionData(TypeId id, const std::string& usr) : id(id), usr(usr) {}
|
TypeDefDefinitionData(const std::string& usr) : usr(usr) {}
|
||||||
|
|
||||||
bool operator==(const TypeDefDefinitionData<TypeId, FuncId, VarId>& other) const {
|
bool operator==(const TypeDefDefinitionData<TypeId, FuncId, VarId, Location>& other) const {
|
||||||
return
|
return
|
||||||
id == other.id &&
|
|
||||||
usr == other.usr &&
|
usr == other.usr &&
|
||||||
short_name == other.short_name &&
|
short_name == other.short_name &&
|
||||||
qualified_name == other.qualified_name &&
|
qualified_name == other.qualified_name &&
|
||||||
@ -293,14 +291,14 @@ struct TypeDefDefinitionData {
|
|||||||
vars == other.vars;
|
vars == other.vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const TypeDefDefinitionData<TypeId, FuncId, VarId>& other) const {
|
bool operator!=(const TypeDefDefinitionData<TypeId, FuncId, VarId, Location>& other) const { return !(*this == other); }
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedTypeDef {
|
struct IndexedTypeDef {
|
||||||
TypeDefDefinitionData<> def;
|
TypeDefDefinitionData<> def;
|
||||||
|
|
||||||
|
TypeId id;
|
||||||
|
|
||||||
// Immediate derived types.
|
// Immediate derived types.
|
||||||
std::vector<TypeId> derived;
|
std::vector<TypeId> derived;
|
||||||
|
|
||||||
@ -314,7 +312,7 @@ struct IndexedTypeDef {
|
|||||||
void AddUsage(Location loc, bool insert_if_not_present = true);
|
void AddUsage(Location loc, bool insert_if_not_present = true);
|
||||||
|
|
||||||
bool operator<(const IndexedTypeDef& other) const {
|
bool operator<(const IndexedTypeDef& other) const {
|
||||||
return def.id < other.def.id;
|
return def.usr < other.def.usr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -330,7 +328,6 @@ namespace std {
|
|||||||
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef, typename Location = Location>
|
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename FuncRef = FuncRef, typename Location = Location>
|
||||||
struct FuncDefDefinitionData {
|
struct FuncDefDefinitionData {
|
||||||
// General metadata.
|
// General metadata.
|
||||||
FuncId id;
|
|
||||||
std::string usr;
|
std::string usr;
|
||||||
std::string short_name;
|
std::string short_name;
|
||||||
std::string qualified_name;
|
std::string qualified_name;
|
||||||
@ -348,13 +345,12 @@ struct FuncDefDefinitionData {
|
|||||||
// Functions that this function calls.
|
// Functions that this function calls.
|
||||||
std::vector<FuncRef> callees;
|
std::vector<FuncRef> callees;
|
||||||
|
|
||||||
FuncDefDefinitionData(FuncId id, const std::string& usr) : id(id), usr(usr) {
|
FuncDefDefinitionData(const std::string& usr) : usr(usr) {
|
||||||
assert(usr.size() > 0);
|
assert(usr.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef>& other) const {
|
bool operator==(const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Location>& other) const {
|
||||||
return
|
return
|
||||||
id == other.id &&
|
|
||||||
usr == other.usr &&
|
usr == other.usr &&
|
||||||
short_name == other.short_name &&
|
short_name == other.short_name &&
|
||||||
qualified_name == other.qualified_name &&
|
qualified_name == other.qualified_name &&
|
||||||
@ -364,15 +360,14 @@ struct FuncDefDefinitionData {
|
|||||||
locals == other.locals &&
|
locals == other.locals &&
|
||||||
callees == other.callees;
|
callees == other.callees;
|
||||||
}
|
}
|
||||||
|
bool operator!=(const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Location>& other) const { return !(*this == other); }
|
||||||
bool operator!=(const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef>& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedFuncDef {
|
struct IndexedFuncDef {
|
||||||
FuncDefDefinitionData<> def;
|
FuncDefDefinitionData<> def;
|
||||||
|
|
||||||
|
FuncId id;
|
||||||
|
|
||||||
// Places the function is forward-declared.
|
// Places the function is forward-declared.
|
||||||
std::vector<Location> declarations;
|
std::vector<Location> declarations;
|
||||||
|
|
||||||
@ -392,12 +387,12 @@ struct IndexedFuncDef {
|
|||||||
|
|
||||||
bool is_bad_def = true;
|
bool is_bad_def = true;
|
||||||
|
|
||||||
IndexedFuncDef(FuncId id, const std::string& usr) : def(id, usr) {
|
IndexedFuncDef(FuncId id, const std::string& usr) : id(id), def(usr) {
|
||||||
assert(usr.size() > 0);
|
assert(usr.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const IndexedFuncDef& other) const {
|
bool operator<(const IndexedFuncDef& other) const {
|
||||||
return def.id < other.def.id;
|
return def.usr < other.def.usr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -413,7 +408,6 @@ namespace std {
|
|||||||
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
|
template<typename TypeId = TypeId, typename FuncId = FuncId, typename VarId = VarId, typename Location = Location>
|
||||||
struct VarDefDefinitionData {
|
struct VarDefDefinitionData {
|
||||||
// General metadata.
|
// General metadata.
|
||||||
VarId id;
|
|
||||||
std::string usr;
|
std::string usr;
|
||||||
std::string short_name;
|
std::string short_name;
|
||||||
std::string qualified_name;
|
std::string qualified_name;
|
||||||
@ -428,11 +422,10 @@ struct VarDefDefinitionData {
|
|||||||
// Type which declares this one (ie, it is a method)
|
// Type which declares this one (ie, it is a method)
|
||||||
optional<TypeId> declaring_type;
|
optional<TypeId> declaring_type;
|
||||||
|
|
||||||
VarDefDefinitionData(VarId id, const std::string& usr) : id(id), usr(usr) {}
|
VarDefDefinitionData(const std::string& usr) : usr(usr) {}
|
||||||
|
|
||||||
bool operator==(const VarDefDefinitionData<TypeId, FuncId, VarId>& other) const {
|
bool operator==(const VarDefDefinitionData<TypeId, FuncId, VarId, Location>& other) const {
|
||||||
return
|
return
|
||||||
id == other.id &&
|
|
||||||
usr == other.usr &&
|
usr == other.usr &&
|
||||||
short_name == other.short_name &&
|
short_name == other.short_name &&
|
||||||
qualified_name == other.qualified_name &&
|
qualified_name == other.qualified_name &&
|
||||||
@ -441,26 +434,25 @@ struct VarDefDefinitionData {
|
|||||||
variable_type == other.variable_type &&
|
variable_type == other.variable_type &&
|
||||||
declaring_type == other.declaring_type;
|
declaring_type == other.declaring_type;
|
||||||
}
|
}
|
||||||
|
bool operator!=(const VarDefDefinitionData<TypeId, FuncId, VarId, Location>& other) const { return !(*this == other); }
|
||||||
bool operator!=(const VarDefDefinitionData<TypeId, FuncId, VarId>& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedVarDef {
|
struct IndexedVarDef {
|
||||||
VarDefDefinitionData<> def;
|
VarDefDefinitionData<> def;
|
||||||
|
|
||||||
|
VarId id;
|
||||||
|
|
||||||
// Usages.
|
// Usages.
|
||||||
std::vector<Location> uses;
|
std::vector<Location> uses;
|
||||||
|
|
||||||
bool is_bad_def = true;
|
bool is_bad_def = true;
|
||||||
|
|
||||||
IndexedVarDef(VarId id, const std::string& usr) : def(id, usr) {
|
IndexedVarDef(VarId id, const std::string& usr) : id(id), def(usr) {
|
||||||
assert(usr.size() > 0);
|
assert(usr.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const IndexedVarDef& other) const {
|
bool operator<(const IndexedVarDef& other) const {
|
||||||
return def.id < other.def.id;
|
return def.usr < other.def.usr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -533,11 +525,13 @@ struct IdCache {
|
|||||||
struct IndexedFile {
|
struct IndexedFile {
|
||||||
IdCache* id_cache;
|
IdCache* id_cache;
|
||||||
|
|
||||||
|
std::string path;
|
||||||
|
|
||||||
std::vector<IndexedTypeDef> types;
|
std::vector<IndexedTypeDef> types;
|
||||||
std::vector<IndexedFuncDef> funcs;
|
std::vector<IndexedFuncDef> funcs;
|
||||||
std::vector<IndexedVarDef> vars;
|
std::vector<IndexedVarDef> vars;
|
||||||
|
|
||||||
IndexedFile(IdCache* id_cache);
|
IndexedFile(const std::string& path, IdCache* id_cache);
|
||||||
|
|
||||||
TypeId ToTypeId(const std::string& usr);
|
TypeId ToTypeId(const std::string& usr);
|
||||||
FuncId ToFuncId(const std::string& usr);
|
FuncId ToFuncId(const std::string& usr);
|
||||||
|
673
query.cc
673
query.cc
@ -17,278 +17,6 @@
|
|||||||
|
|
||||||
// TODO: Make all copy constructors explicit.
|
// TODO: Make all copy constructors explicit.
|
||||||
|
|
||||||
#if false
|
|
||||||
struct IdMap {
|
|
||||||
// TODO: id resolution is broken. We need to resolve same fundamental USR to same ID. Problem is that multiple USRs
|
|
||||||
// can have different source IDs.
|
|
||||||
|
|
||||||
// The first vector is indexed by TId::group.
|
|
||||||
// The second vector is indexed by TId::id.
|
|
||||||
template<typename TId>
|
|
||||||
using GroupMap = std::vector<std::unordered_map<TId, TId>>;
|
|
||||||
|
|
||||||
template<typename TId>
|
|
||||||
using GroupToUsrMap = std::vector<std::unordered_map<TId, std::string>>;
|
|
||||||
|
|
||||||
GroupToUsrMap<FileId> group_file_id_to_usr;
|
|
||||||
GroupToUsrMap<TypeId> group_type_id_to_usr;
|
|
||||||
GroupToUsrMap<FuncId> group_func_id_to_usr;
|
|
||||||
GroupToUsrMap<VarId> group_var_id_to_usr;
|
|
||||||
std::unordered_map<std::string, FileId> usr_to_file_id;
|
|
||||||
std::unordered_map<std::string, TypeId> usr_to_type_id;
|
|
||||||
std::unordered_map<std::string, FuncId> usr_to_func_id;
|
|
||||||
std::unordered_map<std::string, VarId> usr_to_var_id;
|
|
||||||
|
|
||||||
GroupId target_group;
|
|
||||||
int64_t next_file_id = 1;
|
|
||||||
int64_t next_type_id = 1;
|
|
||||||
int64_t next_func_id = 1;
|
|
||||||
int64_t next_var_id = 1;
|
|
||||||
|
|
||||||
GroupMap<FileId> remap_file_id;
|
|
||||||
GroupMap<TypeId> remap_type_id;
|
|
||||||
GroupMap<FuncId> remap_func_id;
|
|
||||||
GroupMap<VarId> remap_var_id;
|
|
||||||
|
|
||||||
IdMap(GroupId target_group) : target_group(target_group) {}
|
|
||||||
|
|
||||||
void Import(IdMap* other_id_map) {
|
|
||||||
// TODO: Implement me
|
|
||||||
// TODO: Let's refactor the entire ID management system. DB should
|
|
||||||
// lose concept of Var/Type/etc id and just use USR, since we
|
|
||||||
// are not going to be storing indices into arrays.
|
|
||||||
}
|
|
||||||
|
|
||||||
void Import(FileDb* file_db, UsrToIdResolver* usr_to_id) {
|
|
||||||
int group = usr_to_id->group;
|
|
||||||
|
|
||||||
if (group >= group_file_id_to_usr.size()) {
|
|
||||||
group_file_id_to_usr.resize(group + 1);
|
|
||||||
group_type_id_to_usr.resize(group + 1);
|
|
||||||
group_func_id_to_usr.resize(group + 1);
|
|
||||||
group_var_id_to_usr.resize(group + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
group_file_id_to_usr[group] = file_db->file_id_to_file_path;
|
|
||||||
|
|
||||||
std::unordered_map<TypeId, std::string>& type_id_to_usr = group_type_id_to_usr[group];
|
|
||||||
for (auto& entry : usr_to_id->usr_to_type_id)
|
|
||||||
type_id_to_usr[entry.second] = entry.first;
|
|
||||||
std::unordered_map<FuncId, std::string>& func_id_to_usr = group_func_id_to_usr[group];
|
|
||||||
for (auto& entry : usr_to_id->usr_to_func_id)
|
|
||||||
func_id_to_usr[entry.second] = entry.first;
|
|
||||||
std::unordered_map<VarId, std::string>& var_id_to_usr = group_var_id_to_usr[group];
|
|
||||||
for (auto& entry : usr_to_id->usr_to_var_id)
|
|
||||||
var_id_to_usr[entry.second] = entry.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TId>
|
|
||||||
inline TId GenericRemap(
|
|
||||||
GroupMap<TId>* map,
|
|
||||||
GroupToUsrMap<TId>* group_id_to_usr, std::unordered_map<std::string, TId>* usr_to_id,
|
|
||||||
int64_t* next_id, TId from) {
|
|
||||||
|
|
||||||
if (from.group == target_group)
|
|
||||||
return from;
|
|
||||||
|
|
||||||
// Find the group that |from| belongs to. Create groups if needed.
|
|
||||||
if (from.group >= map->size())
|
|
||||||
map->resize(from.group + 1);
|
|
||||||
|
|
||||||
// If the group doesn't have an ID already mapped out for |from|, map it.
|
|
||||||
std::unordered_map<TId, TId> group = (*map)[from.group];
|
|
||||||
|
|
||||||
// Lookup the id from the group or add it.
|
|
||||||
auto it = group.find(from);
|
|
||||||
if (it == group.end()) {
|
|
||||||
// NOTE: If the following asserts make sure that from.group is registered inside
|
|
||||||
// of the group_*_id_to_usr variables.
|
|
||||||
|
|
||||||
// Before adding a new id, we need to check if we have already added it.
|
|
||||||
const std::string& usr_for_id = (*group_id_to_usr)[from.group][from];
|
|
||||||
auto it = usr_to_id->find(usr_for_id);
|
|
||||||
if (it != usr_to_id->end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
// This is a brand new id we haven't seen before.
|
|
||||||
else {
|
|
||||||
TId result(target_group, (*next_id)++);
|
|
||||||
group[from] = result;
|
|
||||||
(*usr_to_id)[usr_for_id] = result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TId>
|
|
||||||
inline std::vector<TId> GenericVectorRemap(GroupMap<TId>* map, int64_t* next_id, const std::vector<TId>& from) {
|
|
||||||
std::vector<TId> result;
|
|
||||||
result.reserve(from.size());
|
|
||||||
for (const TId& e : from)
|
|
||||||
result.push_back(Remap(e));
|
|
||||||
return result;
|
|
||||||
/*
|
|
||||||
if (from.empty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
int group_id = from[0].group;
|
|
||||||
if (group_id >= map->size())
|
|
||||||
map->resize(group_id + 1);
|
|
||||||
|
|
||||||
std::unordered_map<TId, TId> group = (*map)[group_id];
|
|
||||||
|
|
||||||
std::vector<TId> result;
|
|
||||||
result.reserve(from.size());
|
|
||||||
for (TId id : from) {
|
|
||||||
if (id.group == target_group) {
|
|
||||||
result.push_back(id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup the id from the group or add it.
|
|
||||||
auto it = group.find(id);
|
|
||||||
if (it == group.end()) {
|
|
||||||
TId new_id(target_group, (*next_id)++);
|
|
||||||
group[id] = new_id;
|
|
||||||
result.push_back(new_id);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.push_back(it->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
FileId Remap(FileId from) {
|
|
||||||
return GenericRemap<FileId>(&remap_file_id, &group_file_id_to_usr, &usr_to_file_id, &next_file_id, from);
|
|
||||||
}
|
|
||||||
Usr Remap(TypeId from) {
|
|
||||||
return GenericRemap(&remap_type_id, &group_type_id_to_usr, &usr_to_type_id, &next_type_id, from);
|
|
||||||
}
|
|
||||||
Usr Remap(FuncId from) {
|
|
||||||
return GenericRemap(&remap_func_id, &group_func_id_to_usr, &usr_to_func_id, &next_func_id, from);
|
|
||||||
}
|
|
||||||
Usr Remap(VarId from) {
|
|
||||||
return GenericRemap(&remap_var_id, &group_var_id_to_usr, &usr_to_var_id, &next_var_id, from);
|
|
||||||
}
|
|
||||||
Location Remap(Location from) {
|
|
||||||
FileId file = Remap(from.file_id());
|
|
||||||
from.raw_file_group = file.group;
|
|
||||||
from.raw_file_id = file.id;
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
UsrRef Remap(FuncRef from) {
|
|
||||||
from.id = Remap(from.id);
|
|
||||||
from.loc = Remap(from.loc);
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
QueryableTypeDef::DefUpdate Remap(QueryableTypeDef::DefUpdate def) {
|
|
||||||
def.id = Remap(def.id);
|
|
||||||
if (def.definition)
|
|
||||||
def.definition = Remap(def.definition.value());
|
|
||||||
if (def.alias_of)
|
|
||||||
def.alias_of = Remap(def.alias_of.value());
|
|
||||||
def.parents = Remap(def.parents);
|
|
||||||
def.types = Remap(def.types);
|
|
||||||
def.funcs = Remap(def.funcs);
|
|
||||||
def.vars = Remap(def.vars);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
QueryableFuncDef::DefUpdate Remap(QueryableFuncDef::DefUpdate def) {
|
|
||||||
def.id = Remap(def.id);
|
|
||||||
if (def.definition)
|
|
||||||
def.definition = Remap(def.definition.value());
|
|
||||||
if (def.declaring_type)
|
|
||||||
def.declaring_type = Remap(def.declaring_type.value());
|
|
||||||
if (def.base)
|
|
||||||
def.base = Remap(def.base.value());
|
|
||||||
def.locals = Remap(def.locals);
|
|
||||||
def.callees = Remap(def.callees);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
QueryableVarDef::DefUpdate Remap(QueryableVarDef::DefUpdate def) {
|
|
||||||
def.id = Remap(def.id);
|
|
||||||
if (def.declaration)
|
|
||||||
def.declaration = Remap(def.declaration.value());
|
|
||||||
if (def.definition)
|
|
||||||
def.definition = Remap(def.definition.value());
|
|
||||||
if (def.variable_type)
|
|
||||||
def.variable_type = Remap(def.variable_type.value());
|
|
||||||
if (def.declaring_type)
|
|
||||||
def.declaring_type = Remap(def.declaring_type.value());
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
QueryableTypeDef Remap(QueryableTypeDef def) {
|
|
||||||
def.def = Remap(def.def);
|
|
||||||
def.derived = Remap(def.derived);
|
|
||||||
def.uses = Remap(def.uses);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
QueryableFuncDef Remap(QueryableFuncDef def) {
|
|
||||||
def.def = Remap(def.def);
|
|
||||||
def.declarations = Remap(def.declarations);
|
|
||||||
def.derived = Remap(def.derived);
|
|
||||||
def.callers = Remap(def.callers);
|
|
||||||
def.uses = Remap(def.uses);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
QueryableVarDef Remap(QueryableVarDef def) {
|
|
||||||
def.def = Remap(def.def);
|
|
||||||
def.uses = Remap(def.uses);
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
template<typename TId, typename TValue>
|
|
||||||
MergeableUpdate<TId, TValue> Remap(MergeableUpdate<TId, TValue> update) {
|
|
||||||
update.id = Remap(update.id);
|
|
||||||
update.to_add = Remap(update.to_add);
|
|
||||||
update.to_remove = Remap(update.to_remove);
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::vector<T> Remap(const std::vector<T>& from) {
|
|
||||||
std::vector<T> result;
|
|
||||||
result.reserve(from.size());
|
|
||||||
for (const T& e : from)
|
|
||||||
result.push_back(Remap(e));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//std::vector<FileId> Remap(const std::vector<FileId>& from) {
|
|
||||||
// return GenericVectorRemap(&remap_file_id, &next_file_id, from);
|
|
||||||
//}
|
|
||||||
std::vector<Location> Remap(const std::vector<Location>& from) {
|
|
||||||
std::vector<Location> result;
|
|
||||||
result.reserve(from.size());
|
|
||||||
for (Location l : from)
|
|
||||||
result.push_back(Remap(l));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::vector<Usr> Remap(const std::vector<TypeId>& from) {
|
|
||||||
return GenericVectorRemap(&remap_type_id, &next_type_id, from);
|
|
||||||
}
|
|
||||||
std::vector<Usr> Remap(const std::vector<FuncId>& from) {
|
|
||||||
return GenericVectorRemap(&remap_func_id, &next_func_id, from);
|
|
||||||
}
|
|
||||||
std::vector<Usr> Remap(const std::vector<VarId>& from) {
|
|
||||||
return GenericVectorRemap(&remap_var_id, &next_var_id, from);
|
|
||||||
}
|
|
||||||
std::vector<UsrRef> Remap(const std::vector<UsrRef>& from) {
|
|
||||||
std::vector<UsrRef> result;
|
|
||||||
result.reserve(from.size());
|
|
||||||
for (FuncRef r : from)
|
|
||||||
result.push_back(Remap(r));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -310,30 +38,29 @@ std::vector<Out> Transform(const std::vector<In>& input, std::function<Out(In)>
|
|||||||
result.push_back(op(in));
|
result.push_back(op(in));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Usr MapIdToUsr(IdCache& id_cache, const TypeId& id) {
|
||||||
Usr MapIdToUsr(IdCache& id_cache, TypeId& id) {
|
|
||||||
return id_cache.type_id_to_usr[id];
|
return id_cache.type_id_to_usr[id];
|
||||||
}
|
}
|
||||||
Usr MapIdToUsr(IdCache& id_cache, FuncId& id) {
|
Usr MapIdToUsr(IdCache& id_cache, const FuncId& id) {
|
||||||
return id_cache.func_id_to_usr[id];
|
return id_cache.func_id_to_usr[id];
|
||||||
}
|
}
|
||||||
Usr MapIdToUsr(IdCache& id_cache, VarId& id) {
|
Usr MapIdToUsr(IdCache& id_cache, const VarId& id) {
|
||||||
return id_cache.var_id_to_usr[id];
|
return id_cache.var_id_to_usr[id];
|
||||||
}
|
}
|
||||||
QueryableLocation MapIdToUsr(IdCache& id_cache, Location& id) {
|
QueryableLocation MapIdToUsr(IdCache& id_cache, const Location& id) {
|
||||||
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
|
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<TypeId>& ids) {
|
std::vector<Usr> MapIdToUsr(IdCache& id_cache, const std::vector<TypeId>& ids) {
|
||||||
return Transform<TypeId, Usr>(ids, [&](TypeId id) { return id_cache.type_id_to_usr[id]; });
|
return Transform<TypeId, Usr>(ids, [&](TypeId id) { return id_cache.type_id_to_usr[id]; });
|
||||||
}
|
}
|
||||||
std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<FuncId>& ids) {
|
std::vector<Usr> MapIdToUsr(IdCache& id_cache, const std::vector<FuncId>& ids) {
|
||||||
return Transform<FuncId, Usr>(ids, [&](FuncId id) { return id_cache.func_id_to_usr[id]; });
|
return Transform<FuncId, Usr>(ids, [&](FuncId id) { return id_cache.func_id_to_usr[id]; });
|
||||||
}
|
}
|
||||||
std::vector<Usr> MapIdToUsr(IdCache& id_cache, std::vector<VarId>& ids) {
|
std::vector<Usr> MapIdToUsr(IdCache& id_cache, const std::vector<VarId>& ids) {
|
||||||
return Transform<VarId, Usr>(ids, [&](VarId id) { return id_cache.var_id_to_usr[id]; });
|
return Transform<VarId, Usr>(ids, [&](VarId id) { return id_cache.var_id_to_usr[id]; });
|
||||||
}
|
}
|
||||||
std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, std::vector<FuncRef>& ids) {
|
std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, const std::vector<FuncRef>& ids) {
|
||||||
return Transform<FuncRef, UsrRef>(ids, [&](FuncRef ref) {
|
return Transform<FuncRef, UsrRef>(ids, [&](FuncRef ref) {
|
||||||
UsrRef result;
|
UsrRef result;
|
||||||
result.loc = MapIdToUsr(id_cache, ref.loc);
|
result.loc = MapIdToUsr(id_cache, ref.loc);
|
||||||
@ -341,13 +68,13 @@ std::vector<UsrRef> MapIdToUsr(IdCache& id_cache, std::vector<FuncRef>& ids) {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
std::vector<QueryableLocation> MapIdToUsr(IdCache& id_cache, std::vector<Location>& ids) {
|
std::vector<QueryableLocation> MapIdToUsr(IdCache& id_cache, const std::vector<Location>& ids) {
|
||||||
return Transform<Location, QueryableLocation>(ids, [&](Location id) {
|
return Transform<Location, QueryableLocation>(ids, [&](Location id) {
|
||||||
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
|
return QueryableLocation(id_cache.file_id_to_file_path[id.file_id()], id.line, id.column, id.interesting);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, TypeDefDefinitionData<>& def) {
|
QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, const TypeDefDefinitionData<>& def) {
|
||||||
QueryableTypeDef::DefUpdate result(def.usr, def.usr);
|
QueryableTypeDef::DefUpdate result(def.usr);
|
||||||
if (result.definition)
|
if (result.definition)
|
||||||
result.definition = MapIdToUsr(id_cache, def.definition.value());
|
result.definition = MapIdToUsr(id_cache, def.definition.value());
|
||||||
if (result.alias_of)
|
if (result.alias_of)
|
||||||
@ -358,8 +85,8 @@ QueryableTypeDef::DefUpdate MapIdToUsr(IdCache& id_cache, TypeDefDefinitionData<
|
|||||||
result.vars = MapIdToUsr(id_cache, def.vars);
|
result.vars = MapIdToUsr(id_cache, def.vars);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
QueryableFuncDef::DefUpdate MapIdToUsr(IdCache& id_cache, FuncDefDefinitionData<>& def) {
|
QueryableFuncDef::DefUpdate MapIdToUsr(IdCache& id_cache, const FuncDefDefinitionData<>& def) {
|
||||||
QueryableFuncDef::DefUpdate result(def.usr, def.usr);
|
QueryableFuncDef::DefUpdate result(def.usr);
|
||||||
if (result.definition)
|
if (result.definition)
|
||||||
result.definition = MapIdToUsr(id_cache, def.definition.value());
|
result.definition = MapIdToUsr(id_cache, def.definition.value());
|
||||||
if (result.declaring_type)
|
if (result.declaring_type)
|
||||||
@ -370,8 +97,8 @@ QueryableFuncDef::DefUpdate MapIdToUsr(IdCache& id_cache, FuncDefDefinitionData<
|
|||||||
result.callees = MapIdToUsr(id_cache, def.callees);
|
result.callees = MapIdToUsr(id_cache, def.callees);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
QueryableVarDef::DefUpdate MapIdToUsr(IdCache& id_cache, VarDefDefinitionData<>& def) {
|
QueryableVarDef::DefUpdate MapIdToUsr(IdCache& id_cache, const VarDefDefinitionData<>& def) {
|
||||||
QueryableVarDef::DefUpdate result(def.usr, def.usr);
|
QueryableVarDef::DefUpdate result(def.usr);
|
||||||
if (result.declaration)
|
if (result.declaration)
|
||||||
result.declaration = MapIdToUsr(id_cache, def.declaration.value());
|
result.declaration = MapIdToUsr(id_cache, def.declaration.value());
|
||||||
if (result.definition)
|
if (result.definition)
|
||||||
@ -383,13 +110,40 @@ QueryableVarDef::DefUpdate MapIdToUsr(IdCache& id_cache, VarDefDefinitionData<>&
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryableTypeDef::QueryableTypeDef(IdCache& id_cache, IndexedTypeDef& indexed)
|
QueryableFile::QueryableFile(const IndexedFile& indexed)
|
||||||
|
: file_id(indexed.path) {
|
||||||
|
|
||||||
|
auto add_outline = [this, &indexed](Usr usr, Location location) {
|
||||||
|
outline.push_back(UsrRef(usr, MapIdToUsr(*indexed.id_cache, location)));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const IndexedTypeDef& def : indexed.types) {
|
||||||
|
if (def.def.definition.has_value())
|
||||||
|
add_outline(def.def.usr, def.def.definition.value());
|
||||||
|
}
|
||||||
|
for (const IndexedFuncDef& def : indexed.funcs) {
|
||||||
|
for (Location decl : def.declarations)
|
||||||
|
add_outline(def.def.usr, decl);
|
||||||
|
if (def.def.definition.has_value())
|
||||||
|
add_outline(def.def.usr, def.def.definition.value());
|
||||||
|
}
|
||||||
|
for (const IndexedVarDef& def : indexed.vars) {
|
||||||
|
if (def.def.definition.has_value())
|
||||||
|
add_outline(def.def.usr, def.def.definition.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(outline.begin(), outline.end(), [](const UsrRef& a, const UsrRef& b) {
|
||||||
|
return a.loc < b.loc;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryableTypeDef::QueryableTypeDef(IdCache& id_cache, const IndexedTypeDef& indexed)
|
||||||
: def(MapIdToUsr(id_cache, indexed.def)) {
|
: def(MapIdToUsr(id_cache, indexed.def)) {
|
||||||
derived = MapIdToUsr(id_cache, indexed.derived);
|
derived = MapIdToUsr(id_cache, indexed.derived);
|
||||||
uses = MapIdToUsr(id_cache, indexed.uses);
|
uses = MapIdToUsr(id_cache, indexed.uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryableFuncDef::QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed)
|
QueryableFuncDef::QueryableFuncDef(IdCache& id_cache, const IndexedFuncDef& indexed)
|
||||||
: def(MapIdToUsr(id_cache, indexed.def)) {
|
: def(MapIdToUsr(id_cache, indexed.def)) {
|
||||||
declarations = MapIdToUsr(id_cache, indexed.declarations);
|
declarations = MapIdToUsr(id_cache, indexed.declarations);
|
||||||
derived = MapIdToUsr(id_cache, indexed.derived);
|
derived = MapIdToUsr(id_cache, indexed.derived);
|
||||||
@ -397,14 +151,11 @@ QueryableFuncDef::QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed)
|
|||||||
uses = MapIdToUsr(id_cache, indexed.uses);
|
uses = MapIdToUsr(id_cache, indexed.uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryableVarDef::QueryableVarDef(IdCache& id_cache, IndexedVarDef& indexed)
|
QueryableVarDef::QueryableVarDef(IdCache& id_cache, const IndexedVarDef& indexed)
|
||||||
: def(MapIdToUsr(id_cache, indexed.def)) {
|
: def(MapIdToUsr(id_cache, indexed.def)) {
|
||||||
uses = MapIdToUsr(id_cache, indexed.uses);
|
uses = MapIdToUsr(id_cache, indexed.uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueryableEntry {
|
|
||||||
const char* const str;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -468,127 +219,25 @@ void RemoveRange(std::vector<T>* dest, const std::vector<T>& to_remove) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct IndexUpdate {
|
|
||||||
// Type updates.
|
|
||||||
std::vector<Usr> types_removed;
|
|
||||||
std::vector<QueryableTypeDef> types_added;
|
|
||||||
std::vector<QueryableTypeDef::DefUpdate> types_def_changed;
|
|
||||||
std::vector<QueryableTypeDef::DerivedUpdate> types_derived;
|
|
||||||
std::vector<QueryableTypeDef::UsesUpdate> types_uses;
|
|
||||||
|
|
||||||
// Function updates.
|
|
||||||
std::vector<Usr> funcs_removed;
|
|
||||||
std::vector<QueryableFuncDef> funcs_added;
|
|
||||||
std::vector<QueryableFuncDef::DefUpdate> funcs_def_changed;
|
|
||||||
std::vector<QueryableFuncDef::DeclarationsUpdate> funcs_declarations;
|
|
||||||
std::vector<QueryableFuncDef::DerivedUpdate> funcs_derived;
|
|
||||||
std::vector<QueryableFuncDef::CallersUpdate> funcs_callers;
|
|
||||||
std::vector<QueryableFuncDef::UsesUpdate> funcs_uses;
|
|
||||||
|
|
||||||
// Variable updates.
|
|
||||||
std::vector<Usr> vars_removed;
|
|
||||||
std::vector<QueryableVarDef> vars_added;
|
|
||||||
std::vector<QueryableVarDef::DefUpdate> vars_def_changed;
|
|
||||||
std::vector<QueryableVarDef::UsesUpdate> vars_uses;
|
|
||||||
|
|
||||||
IndexUpdate(IndexedFile& file);
|
|
||||||
|
|
||||||
#if false
|
|
||||||
void Remap(IdMap* map) {
|
|
||||||
id_map = map;
|
|
||||||
|
|
||||||
#define INDEX_UPDATE_REMAP(name) \
|
|
||||||
name = id_map->Remap(name);
|
|
||||||
|
|
||||||
INDEX_UPDATE_REMAP(types_removed);
|
|
||||||
INDEX_UPDATE_REMAP(types_added);
|
|
||||||
INDEX_UPDATE_REMAP(types_def_changed);
|
|
||||||
INDEX_UPDATE_REMAP(types_derived);
|
|
||||||
INDEX_UPDATE_REMAP(types_uses);
|
|
||||||
|
|
||||||
INDEX_UPDATE_REMAP(funcs_removed);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_added);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_def_changed);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_declarations);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_derived);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_callers);
|
|
||||||
INDEX_UPDATE_REMAP(funcs_uses);
|
|
||||||
|
|
||||||
INDEX_UPDATE_REMAP(vars_removed);
|
|
||||||
INDEX_UPDATE_REMAP(vars_added);
|
|
||||||
INDEX_UPDATE_REMAP(vars_def_changed);
|
|
||||||
INDEX_UPDATE_REMAP(vars_uses);
|
|
||||||
|
|
||||||
#undef INDEX_UPDATE_REMAP
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if false
|
|
||||||
// Merges the contents of |update| into this IndexUpdate instance.
|
|
||||||
void Merge(const IndexUpdate& update) {
|
|
||||||
#define INDEX_UPDATE_MERGE(name) \
|
|
||||||
AddRange(&name, id_map->Remap(update.##name));
|
|
||||||
|
|
||||||
INDEX_UPDATE_MERGE(types_removed);
|
|
||||||
INDEX_UPDATE_MERGE(types_added);
|
|
||||||
INDEX_UPDATE_MERGE(types_def_changed);
|
|
||||||
INDEX_UPDATE_MERGE(types_derived);
|
|
||||||
INDEX_UPDATE_MERGE(types_uses);
|
|
||||||
|
|
||||||
INDEX_UPDATE_MERGE(funcs_removed);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_added);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_def_changed);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_declarations);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_derived);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_callers);
|
|
||||||
INDEX_UPDATE_MERGE(funcs_uses);
|
|
||||||
|
|
||||||
INDEX_UPDATE_MERGE(vars_removed);
|
|
||||||
INDEX_UPDATE_MERGE(vars_added);
|
|
||||||
INDEX_UPDATE_MERGE(vars_def_changed);
|
|
||||||
INDEX_UPDATE_MERGE(vars_uses);
|
|
||||||
|
|
||||||
#undef INDEX_UPDATE_MERGE
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
IndexUpdate::IndexUpdate(IndexedFile& file) {
|
|
||||||
for (IndexedTypeDef& def : file.types)
|
|
||||||
types_added.push_back(QueryableTypeDef(*file.id_cache, def));
|
|
||||||
for (IndexedFuncDef& def : file.funcs)
|
|
||||||
funcs_added.push_back(QueryableFuncDef(*file.id_cache, def));
|
|
||||||
for (IndexedVarDef& def : file.vars)
|
|
||||||
vars_added.push_back(QueryableVarDef(*file.id_cache, def));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if false
|
|
||||||
template<typename TId, typename TValue>
|
|
||||||
MergeableUpdate<TId, TValue> MakeMergeableUpdate(IdMap* id_map, TId symbol_id, const std::vector<TValue>& removed, const std::vector<TValue>& added) {
|
|
||||||
MergeableUpdate<TId, TValue> update;
|
|
||||||
update.id = id_map->Remap(symbol_id);
|
|
||||||
update.to_remove = id_map->Remap(removed);
|
|
||||||
update.to_add = id_map->Remap(added);
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TValue>
|
|
||||||
TValue* TryFind(std::unordered_set<TValue*>& set, TValue* value) {
|
|
||||||
// TODO: Make |value| a const ref?
|
|
||||||
auto it = set.find(value);
|
|
||||||
if (it == set.end())
|
|
||||||
return nullptr;
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::unordered_set<T*> CreateSet(std::vector<T>& elements) {
|
|
||||||
std::unordered_set<T*> result;
|
|
||||||
result.reserve(elements.size());
|
|
||||||
for (T& element : elements)
|
|
||||||
result.insert(&element);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Compares |previous| and |current|, adding all elements that are
|
// Compares |previous| and |current|, adding all elements that are
|
||||||
@ -631,7 +280,7 @@ void CompareGroups(
|
|||||||
auto curr_it = current_data.begin();
|
auto curr_it = current_data.begin();
|
||||||
while (prev_it != previous_data.end() && curr_it != current_data.end()) {
|
while (prev_it != previous_data.end() && curr_it != current_data.end()) {
|
||||||
// same id
|
// same id
|
||||||
if (prev_it->def.id == curr_it->def.id) {
|
if (prev_it->def.usr == curr_it->def.usr) {
|
||||||
if (!prev_it->is_bad_def && !curr_it->is_bad_def)
|
if (!prev_it->is_bad_def && !curr_it->is_bad_def)
|
||||||
on_found(&*prev_it, &*curr_it);
|
on_found(&*prev_it, &*curr_it);
|
||||||
else if (prev_it->is_bad_def)
|
else if (prev_it->is_bad_def)
|
||||||
@ -644,7 +293,7 @@ void CompareGroups(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prev_id is smaller - prev_it has data curr_it does not have.
|
// prev_id is smaller - prev_it has data curr_it does not have.
|
||||||
else if (prev_it->def.id < curr_it->def.id) {
|
else if (prev_it->def.usr < curr_it->def.usr) {
|
||||||
on_removed(&*prev_it);
|
on_removed(&*prev_it);
|
||||||
++prev_it;
|
++prev_it;
|
||||||
}
|
}
|
||||||
@ -669,8 +318,33 @@ void CompareGroups(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this const correct.
|
|
||||||
IndexUpdate ComputeDiff(IdMap* id_map, IndexedFile& previous, IndexedFile& current) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IndexUpdate::IndexUpdate(IndexedFile& file) {
|
||||||
|
files_added.push_back(QueryableFile(file));
|
||||||
|
for (const IndexedTypeDef& def : file.types)
|
||||||
|
types_added.push_back(QueryableTypeDef(*file.id_cache, def));
|
||||||
|
for (const IndexedFuncDef& def : file.funcs)
|
||||||
|
funcs_added.push_back(QueryableFuncDef(*file.id_cache, def));
|
||||||
|
for (const IndexedVarDef& def : file.vars)
|
||||||
|
vars_added.push_back(QueryableVarDef(*file.id_cache, def));
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexUpdate::IndexUpdate(IndexedFile& previous_file, IndexedFile& current_file) {
|
||||||
#define JOIN(a, b) a##b
|
#define JOIN(a, b) a##b
|
||||||
// |query_name| is the name of the variable on the query type.
|
// |query_name| is the name of the variable on the query type.
|
||||||
// |index_name| is the name of the variable on the index type.
|
// |index_name| is the name of the variable on the index type.
|
||||||
@ -679,71 +353,123 @@ IndexUpdate ComputeDiff(IdMap* id_map, IndexedFile& previous, IndexedFile& curre
|
|||||||
{ \
|
{ \
|
||||||
/* Check for changes. */ \
|
/* Check for changes. */ \
|
||||||
std::vector<type> removed, added; \
|
std::vector<type> removed, added; \
|
||||||
bool did_add = ComputeDifferenceForUpdate(JOIN(previous->, index_name), JOIN(current->, index_name), &removed, &added); \
|
bool did_add = ComputeDifferenceForUpdate( \
|
||||||
|
MapIdToUsr(*previous_file.id_cache, JOIN(previous_def->, index_name)), \
|
||||||
|
MapIdToUsr(*current_file.id_cache, JOIN(current_def->, index_name)), \
|
||||||
|
&removed, &added); \
|
||||||
if (did_add) {\
|
if (did_add) {\
|
||||||
std::cout << "Adding mergeable update on " << current->def.short_name << " (" << current->def.usr << ") for field " << #index_name << std::endl; \
|
std::cout << "Adding mergeable update on " << current_def->def.short_name << " (" << current_def->def.usr << ") for field " << #index_name << std::endl; \
|
||||||
JOIN(update., query_name).push_back(MakeMergeableUpdate(id_map, current->def.id, removed, added)); \
|
query_name.push_back(MergeableUpdate<type>(current_def->def.usr, removed, added)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(previous.usr_to_id == current.usr_to_id);
|
|
||||||
assert(previous.file_db == current.file_db);
|
// File
|
||||||
IndexUpdate update(id_map);
|
do {
|
||||||
|
// Outline is a special property and needs special handling, because it is a computed property
|
||||||
|
// of the IndexedFile (ie, to view it we need to construct a QueryableFile instance).
|
||||||
|
assert(previous_file.path == current_file.path);
|
||||||
|
QueryableFile previous_queryable_file(previous_file);
|
||||||
|
QueryableFile current_queryable_file(previous_file);
|
||||||
|
std::vector<UsrRef> removed, added;
|
||||||
|
bool did_add = ComputeDifferenceForUpdate(
|
||||||
|
previous_queryable_file.outline,
|
||||||
|
current_queryable_file.outline,
|
||||||
|
&removed, &added);
|
||||||
|
if (did_add) {
|
||||||
|
std::cout << "Adding mergeable update on outline (" << current_file.path << ")" << std::endl;
|
||||||
|
files_outline.push_back(MergeableUpdate<UsrRef>(current_file.path, removed, added));
|
||||||
|
}
|
||||||
|
} while (false); // do while false instead of just {} to appease Visual Studio code formatter.
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
CompareGroups<IndexedTypeDef>(previous.types, current.types,
|
CompareGroups<IndexedTypeDef>(previous_file.types, current_file.types,
|
||||||
/*onRemoved:*/[&update, &id_map](IndexedTypeDef* def) {
|
/*onRemoved:*/[this](IndexedTypeDef* def) {
|
||||||
update.types_removed.push_back(id_map->Remap(def->def.id));
|
types_removed.push_back(def->def.usr);
|
||||||
},
|
},
|
||||||
/*onAdded:*/[&update, &id_map](IndexedTypeDef* def) {
|
/*onAdded:*/[this, ¤t_file](IndexedTypeDef* def) {
|
||||||
update.types_added.push_back(QueryableTypeDef(*id_map, *def));
|
types_added.push_back(QueryableTypeDef(*current_file.id_cache, *def));
|
||||||
},
|
},
|
||||||
/*onChanged:*/[&update, &id_map](IndexedTypeDef* previous, IndexedTypeDef* current) {
|
/*onFound:*/[this, &previous_file, ¤t_file](IndexedTypeDef* previous_def, IndexedTypeDef* current_def) {
|
||||||
if (previous->def != current->def)
|
QueryableTypeDef::DefUpdate previous_remapped_def = MapIdToUsr(*previous_file.id_cache, previous_def->def);
|
||||||
update.types_def_changed.push_back(id_map->Remap(current->def));
|
QueryableTypeDef::DefUpdate current_remapped_def = MapIdToUsr(*current_file.id_cache, current_def->def);
|
||||||
|
if (previous_remapped_def != current_remapped_def)
|
||||||
|
types_def_changed.push_back(current_remapped_def);
|
||||||
|
|
||||||
PROCESS_UPDATE_DIFF(types_derived, derived, TypeId);
|
PROCESS_UPDATE_DIFF(types_derived, derived, Usr);
|
||||||
PROCESS_UPDATE_DIFF(types_uses, uses, Location);
|
PROCESS_UPDATE_DIFF(types_uses, uses, QueryableLocation);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
CompareGroups<IndexedFuncDef>(previous.funcs, current.funcs,
|
CompareGroups<IndexedFuncDef>(previous_file.funcs, current_file.funcs,
|
||||||
/*onRemoved:*/[&update, &id_map](IndexedFuncDef* def) {
|
/*onRemoved:*/[this](IndexedFuncDef* def) {
|
||||||
update.funcs_removed.push_back(id_map->Remap(def->def.id));
|
funcs_removed.push_back(def->def.usr);
|
||||||
},
|
},
|
||||||
/*onAdded:*/[&update, &id_map](IndexedFuncDef* def) {
|
/*onAdded:*/[this, ¤t_file](IndexedFuncDef* def) {
|
||||||
update.funcs_added.push_back(QueryableFuncDef(*id_map, *def));
|
funcs_added.push_back(QueryableFuncDef(*current_file.id_cache, *def));
|
||||||
},
|
},
|
||||||
/*onChanged:*/[&update, &id_map](IndexedFuncDef* previous, IndexedFuncDef* current) {
|
/*onFound:*/[this, &previous_file, ¤t_file](IndexedFuncDef* previous_def, IndexedFuncDef* current_def) {
|
||||||
if (previous->def != current->def)
|
QueryableFuncDef::DefUpdate previous_remapped_def = MapIdToUsr(*previous_file.id_cache, previous_def->def);
|
||||||
update.funcs_def_changed.push_back(id_map->Remap(current->def));
|
QueryableFuncDef::DefUpdate current_remapped_def = MapIdToUsr(*current_file.id_cache, current_def->def);
|
||||||
PROCESS_UPDATE_DIFF(funcs_declarations, declarations, Location);
|
if (previous_remapped_def != current_remapped_def)
|
||||||
PROCESS_UPDATE_DIFF(funcs_derived, derived, FuncId);
|
funcs_def_changed.push_back(current_remapped_def);
|
||||||
PROCESS_UPDATE_DIFF(funcs_callers, callers, FuncRef);
|
|
||||||
PROCESS_UPDATE_DIFF(funcs_uses, uses, Location);
|
PROCESS_UPDATE_DIFF(funcs_declarations, declarations, QueryableLocation);
|
||||||
|
PROCESS_UPDATE_DIFF(funcs_derived, derived, Usr);
|
||||||
|
PROCESS_UPDATE_DIFF(funcs_callers, callers, UsrRef);
|
||||||
|
PROCESS_UPDATE_DIFF(funcs_uses, uses, QueryableLocation);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
CompareGroups<IndexedVarDef>(previous.vars, current.vars,
|
CompareGroups<IndexedVarDef>(previous_file.vars, current_file.vars,
|
||||||
/*onRemoved:*/[&update, &id_map](IndexedVarDef* def) {
|
/*onRemoved:*/[this](IndexedVarDef* def) {
|
||||||
update.vars_removed.push_back(id_map->Remap(def->def.id));
|
vars_removed.push_back(def->def.usr);
|
||||||
},
|
},
|
||||||
/*onAdded:*/[&update, &id_map](IndexedVarDef* def) {
|
/*onAdded:*/[this, ¤t_file](IndexedVarDef* def) {
|
||||||
update.vars_added.push_back(QueryableVarDef(*id_map, *def));
|
vars_added.push_back(QueryableVarDef(*current_file.id_cache, *def));
|
||||||
},
|
},
|
||||||
/*onChanged:*/[&update, &id_map](IndexedVarDef* previous, IndexedVarDef* current) {
|
/*onFound:*/[this, &previous_file, ¤t_file](IndexedVarDef* previous_def, IndexedVarDef* current_def) {
|
||||||
if (previous->def != current->def)
|
QueryableVarDef::DefUpdate previous_remapped_def = MapIdToUsr(*previous_file.id_cache, previous_def->def);
|
||||||
update.vars_def_changed.push_back(id_map->Remap(current->def));
|
QueryableVarDef::DefUpdate current_remapped_def = MapIdToUsr(*current_file.id_cache, current_def->def);
|
||||||
PROCESS_UPDATE_DIFF(vars_uses, uses, Location);
|
if (previous_remapped_def != current_remapped_def)
|
||||||
});
|
vars_def_changed.push_back(current_remapped_def);
|
||||||
|
|
||||||
return update;
|
PROCESS_UPDATE_DIFF(vars_uses, uses, QueryableLocation);
|
||||||
|
});
|
||||||
|
|
||||||
#undef PROCESS_UPDATE_DIFF
|
#undef PROCESS_UPDATE_DIFF
|
||||||
#undef JOIN
|
#undef JOIN
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void IndexUpdate::Merge(const IndexUpdate& update) {
|
||||||
|
#define INDEX_UPDATE_MERGE(name) \
|
||||||
|
AddRange(&name, update.##name);
|
||||||
|
|
||||||
|
INDEX_UPDATE_MERGE(files_removed);
|
||||||
|
INDEX_UPDATE_MERGE(files_added);
|
||||||
|
INDEX_UPDATE_MERGE(files_outline);
|
||||||
|
|
||||||
|
INDEX_UPDATE_MERGE(types_removed);
|
||||||
|
INDEX_UPDATE_MERGE(types_added);
|
||||||
|
INDEX_UPDATE_MERGE(types_def_changed);
|
||||||
|
INDEX_UPDATE_MERGE(types_derived);
|
||||||
|
INDEX_UPDATE_MERGE(types_uses);
|
||||||
|
|
||||||
|
INDEX_UPDATE_MERGE(funcs_removed);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_added);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_def_changed);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_declarations);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_derived);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_callers);
|
||||||
|
INDEX_UPDATE_MERGE(funcs_uses);
|
||||||
|
|
||||||
|
INDEX_UPDATE_MERGE(vars_removed);
|
||||||
|
INDEX_UPDATE_MERGE(vars_added);
|
||||||
|
INDEX_UPDATE_MERGE(vars_def_changed);
|
||||||
|
INDEX_UPDATE_MERGE(vars_uses);
|
||||||
|
|
||||||
|
#undef INDEX_UPDATE_MERGE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -768,65 +494,20 @@ IndexUpdate ComputeDiff(IdMap* id_map, IndexedFile& previous, IndexedFile& curre
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The query database is heavily optimized for fast queries. It is stored
|
|
||||||
// in-memory.
|
|
||||||
struct QueryableDatabase {
|
|
||||||
// Indicies between lookup vectors are related to symbols, ie, index 5 in
|
|
||||||
// |qualified_names| matches index 5 in |symbols|.
|
|
||||||
std::vector<QueryableEntry> qualified_names;
|
|
||||||
std::vector<SymbolIdx> symbols;
|
|
||||||
|
|
||||||
// Raw data storage.
|
|
||||||
std::vector<QueryableFile> files; // File path is stored as a Usr.
|
|
||||||
std::vector<QueryableTypeDef> types;
|
|
||||||
std::vector<QueryableFuncDef> funcs;
|
|
||||||
std::vector<QueryableVarDef> vars;
|
|
||||||
|
|
||||||
// Lookup symbol based on a usr.
|
|
||||||
std::unordered_map<Usr, SymbolIdx> usr_to_symbol;
|
|
||||||
|
|
||||||
// Insert the contents of |update| into |db|.
|
|
||||||
void ApplyIndexUpdate(IndexUpdate* update);
|
|
||||||
|
|
||||||
void RemoveUsrs(const std::vector<Usr>& to_remove);
|
|
||||||
void Import(const std::vector<QueryableTypeDef>& defs);
|
|
||||||
void Import(const std::vector<QueryableFuncDef>& defs);
|
|
||||||
void Import(const std::vector<QueryableVarDef>& defs);
|
|
||||||
void Update(const std::vector<QueryableTypeDef::DefUpdate>& updates);
|
|
||||||
void Update(const std::vector<QueryableFuncDef::DefUpdate>& updates);
|
|
||||||
void Update(const std::vector<QueryableVarDef::DefUpdate>& updates);
|
|
||||||
};
|
|
||||||
|
|
||||||
void QueryableDatabase::RemoveUsrs(const std::vector<Usr>& to_remove) {
|
void QueryableDatabase::RemoveUsrs(const std::vector<Usr>& to_remove) {
|
||||||
// TODO: Removing usrs is tricky because it means we will have to rebuild idx locations. I'm thinking we just nullify
|
// TODO: Removing usrs is tricky because it means we will have to rebuild idx locations. I'm thinking we just nullify
|
||||||
// the entry instead of actually removing the data. The index could be massive.
|
// the entry instead of actually removing the data. The index could be massive.
|
||||||
|
for (Usr usr : to_remove)
|
||||||
|
usr_to_symbol[usr].kind = SymbolKind::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
void QueryableDatabase::Import(const std::vector<QueryableFile>& defs) {
|
||||||
usr_to_symbol.erase(std::remove_if(usr_to_symbol.begin(), usr_to_symbol.end(), [&to_remove](const std::string& usr) {
|
for (auto& def : defs) {
|
||||||
// TODO: make ids_to_remove a set?
|
usr_to_symbol[def.file_id] = SymbolIdx(SymbolKind::File, files.size());
|
||||||
return std::find(to_remove.begin(), to_remove.end(), usr) != to_remove.end();
|
files.push_back(def);
|
||||||
}), usr_to_symbol.end());
|
|
||||||
|
|
||||||
|
|
||||||
types.erase(std::remove_if(types.begin(), types.end(), [&to_remove](const QueryableTypeDef& def) {
|
|
||||||
return false;
|
|
||||||
}), types.end());
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
for (auto it = to_erase; it != usr_to_symbol.end(); ++it) {
|
|
||||||
switch (it->second.kind) {
|
|
||||||
case SymbolKind::Type:
|
|
||||||
types.erase(types.begin() + it->second.type_idx);
|
|
||||||
break;
|
|
||||||
case SymbolKind::Func:
|
|
||||||
funcs.erase(funcs.begin() + it->second.func_idx);
|
|
||||||
break;
|
|
||||||
case SymbolKind::Var:
|
|
||||||
vars.erase(vars.begin() + it->second.var_idx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueryableDatabase::Import(const std::vector<QueryableTypeDef>& defs) {
|
void QueryableDatabase::Import(const std::vector<QueryableTypeDef>& defs) {
|
||||||
@ -902,6 +583,10 @@ void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
|
|||||||
RemoveRange(JOIN(&def->, def_var_name), merge_update.to_remove); \
|
RemoveRange(JOIN(&def->, def_var_name), merge_update.to_remove); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveUsrs(update->files_removed);
|
||||||
|
Import(update->files_added);
|
||||||
|
HANDLE_MERGEABLE(files_outline, outline, files);
|
||||||
|
|
||||||
RemoveUsrs(update->types_removed);
|
RemoveUsrs(update->types_removed);
|
||||||
Import(update->types_added);
|
Import(update->types_added);
|
||||||
Update(update->types_def_changed);
|
Update(update->types_def_changed);
|
||||||
@ -934,7 +619,7 @@ void QueryableDatabase::ApplyIndexUpdate(IndexUpdate* update) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main233(int argc, char** argv) {
|
||||||
// TODO: Unify UserToIdResolver and FileDb
|
// TODO: Unify UserToIdResolver and FileDb
|
||||||
IdCache id_cache(1);
|
IdCache id_cache(1);
|
||||||
|
|
||||||
|
114
query.h
114
query.h
@ -48,6 +48,14 @@ struct QueryableLocation {
|
|||||||
line == other.line &&
|
line == other.line &&
|
||||||
column == other.column;
|
column == other.column;
|
||||||
}
|
}
|
||||||
|
bool operator!=(const QueryableLocation& other) const { return !(*this == other); }
|
||||||
|
bool operator<(const QueryableLocation& o) const {
|
||||||
|
return
|
||||||
|
path < o.path &&
|
||||||
|
line < o.line &&
|
||||||
|
column < o.column &&
|
||||||
|
interesting < o.interesting;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -55,9 +63,16 @@ struct UsrRef {
|
|||||||
Usr usr;
|
Usr usr;
|
||||||
QueryableLocation loc;
|
QueryableLocation loc;
|
||||||
|
|
||||||
|
UsrRef() {}
|
||||||
|
UsrRef(Usr usr, QueryableLocation loc) : usr(usr), loc(loc) {}
|
||||||
|
|
||||||
bool operator==(const UsrRef& other) const {
|
bool operator==(const UsrRef& other) const {
|
||||||
return usr == other.usr && loc == other.loc;
|
return usr == other.usr && loc == other.loc;
|
||||||
}
|
}
|
||||||
|
bool operator!=(const UsrRef& other) const { return !(*this == other); }
|
||||||
|
bool operator<(const UsrRef& other) const {
|
||||||
|
return usr < other.usr && loc < other.loc;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +94,19 @@ struct MergeableUpdate {
|
|||||||
// Entries to add and remove.
|
// Entries to add and remove.
|
||||||
std::vector<TValue> to_add;
|
std::vector<TValue> to_add;
|
||||||
std::vector<TValue> to_remove;
|
std::vector<TValue> to_remove;
|
||||||
|
|
||||||
|
MergeableUpdate(Usr usr, const std::vector<TValue>& to_add, const std::vector<TValue>& to_remove)
|
||||||
|
: usr(usr), to_add(to_add), to_remove(to_remove) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueryableFile {
|
||||||
|
using OutlineUpdate = MergeableUpdate<UsrRef>;
|
||||||
|
|
||||||
|
Usr file_id;
|
||||||
|
// Outline of the file (ie, all symbols).
|
||||||
|
std::vector<UsrRef> outline;
|
||||||
|
|
||||||
|
QueryableFile(const IndexedFile& indexed);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryableTypeDef {
|
struct QueryableTypeDef {
|
||||||
@ -90,7 +118,7 @@ struct QueryableTypeDef {
|
|||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
|
|
||||||
QueryableTypeDef(IdCache& id_cache, IndexedTypeDef& indexed);
|
QueryableTypeDef(IdCache& id_cache, const IndexedTypeDef& indexed);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryableFuncDef {
|
struct QueryableFuncDef {
|
||||||
@ -106,7 +134,7 @@ struct QueryableFuncDef {
|
|||||||
std::vector<UsrRef> callers;
|
std::vector<UsrRef> callers;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
|
|
||||||
QueryableFuncDef(IdCache& id_cache, IndexedFuncDef& indexed);
|
QueryableFuncDef(IdCache& id_cache, const IndexedFuncDef& indexed);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryableVarDef {
|
struct QueryableVarDef {
|
||||||
@ -116,10 +144,9 @@ struct QueryableVarDef {
|
|||||||
DefUpdate def;
|
DefUpdate def;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
|
|
||||||
QueryableVarDef(IdCache& id_cache, IndexedVarDef& indexed);
|
QueryableVarDef(IdCache& id_cache, const IndexedVarDef& indexed);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum class SymbolKind { Invalid, File, Type, Func, Var };
|
enum class SymbolKind { Invalid, File, Type, Func, Var };
|
||||||
struct SymbolIdx {
|
struct SymbolIdx {
|
||||||
SymbolKind kind;
|
SymbolKind kind;
|
||||||
@ -130,11 +157,78 @@ struct SymbolIdx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct QueryableFile {
|
|
||||||
FileId file_id;
|
|
||||||
|
|
||||||
// Symbols declared in the file.
|
|
||||||
std::vector<SymbolIdx> declared_symbols;
|
|
||||||
// Symbols which have definitions in the file.
|
struct IndexUpdate {
|
||||||
std::vector<SymbolIdx> defined_symbols;
|
// File updates.
|
||||||
|
std::vector<Usr> files_removed;
|
||||||
|
std::vector<QueryableFile> files_added;
|
||||||
|
std::vector<QueryableFile::OutlineUpdate> files_outline;
|
||||||
|
|
||||||
|
// Type updates.
|
||||||
|
std::vector<Usr> types_removed;
|
||||||
|
std::vector<QueryableTypeDef> types_added;
|
||||||
|
std::vector<QueryableTypeDef::DefUpdate> types_def_changed;
|
||||||
|
std::vector<QueryableTypeDef::DerivedUpdate> types_derived;
|
||||||
|
std::vector<QueryableTypeDef::UsesUpdate> types_uses;
|
||||||
|
|
||||||
|
// Function updates.
|
||||||
|
std::vector<Usr> funcs_removed;
|
||||||
|
std::vector<QueryableFuncDef> funcs_added;
|
||||||
|
std::vector<QueryableFuncDef::DefUpdate> funcs_def_changed;
|
||||||
|
std::vector<QueryableFuncDef::DeclarationsUpdate> funcs_declarations;
|
||||||
|
std::vector<QueryableFuncDef::DerivedUpdate> funcs_derived;
|
||||||
|
std::vector<QueryableFuncDef::CallersUpdate> funcs_callers;
|
||||||
|
std::vector<QueryableFuncDef::UsesUpdate> funcs_uses;
|
||||||
|
|
||||||
|
// Variable updates.
|
||||||
|
std::vector<Usr> vars_removed;
|
||||||
|
std::vector<QueryableVarDef> vars_added;
|
||||||
|
std::vector<QueryableVarDef::DefUpdate> vars_def_changed;
|
||||||
|
std::vector<QueryableVarDef::UsesUpdate> vars_uses;
|
||||||
|
|
||||||
|
|
||||||
|
// Creates a new IndexUpdate that will import |file|.
|
||||||
|
explicit IndexUpdate(IndexedFile& file);
|
||||||
|
|
||||||
|
// Creates an index update assuming that |previous| is already
|
||||||
|
// in the index, so only the delta between |previous| and |current|
|
||||||
|
// will be applied.
|
||||||
|
IndexUpdate(IndexedFile& previous, IndexedFile& current);
|
||||||
|
|
||||||
|
// Merges the contents of |update| into this IndexUpdate instance.
|
||||||
|
void Merge(const IndexUpdate& update);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The query database is heavily optimized for fast queries. It is stored
|
||||||
|
// in-memory.
|
||||||
|
struct QueryableDatabase {
|
||||||
|
// Indicies between lookup vectors are related to symbols, ie, index 5 in
|
||||||
|
// |qualified_names| matches index 5 in |symbols|.
|
||||||
|
std::vector<std::string> qualified_names;
|
||||||
|
std::vector<SymbolIdx> symbols;
|
||||||
|
|
||||||
|
// Raw data storage.
|
||||||
|
std::vector<QueryableFile> files; // File path is stored as a Usr.
|
||||||
|
std::vector<QueryableTypeDef> types;
|
||||||
|
std::vector<QueryableFuncDef> funcs;
|
||||||
|
std::vector<QueryableVarDef> vars;
|
||||||
|
|
||||||
|
// Lookup symbol based on a usr.
|
||||||
|
std::unordered_map<Usr, SymbolIdx> usr_to_symbol;
|
||||||
|
|
||||||
|
// Insert the contents of |update| into |db|.
|
||||||
|
void ApplyIndexUpdate(IndexUpdate* update);
|
||||||
|
|
||||||
|
void RemoveUsrs(const std::vector<Usr>& to_remove);
|
||||||
|
void Import(const std::vector<QueryableFile>& defs);
|
||||||
|
void Import(const std::vector<QueryableTypeDef>& defs);
|
||||||
|
void Import(const std::vector<QueryableFuncDef>& defs);
|
||||||
|
void Import(const std::vector<QueryableVarDef>& defs);
|
||||||
|
void Update(const std::vector<QueryableTypeDef::DefUpdate>& updates);
|
||||||
|
void Update(const std::vector<QueryableFuncDef::DefUpdate>& updates);
|
||||||
|
void Update(const std::vector<QueryableVarDef::DefUpdate>& updates);
|
||||||
};
|
};
|
@ -105,7 +105,7 @@ void Serialize(Writer& writer, IndexedFile* file) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
SERIALIZE("id", def.id);
|
SERIALIZE("id", id);
|
||||||
SERIALIZE("usr", def.usr);
|
SERIALIZE("usr", def.usr);
|
||||||
SERIALIZE("short_name", def.short_name);
|
SERIALIZE("short_name", def.short_name);
|
||||||
SERIALIZE("qualified_name", def.qualified_name);
|
SERIALIZE("qualified_name", def.qualified_name);
|
||||||
@ -129,7 +129,7 @@ void Serialize(Writer& writer, IndexedFile* file) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
SERIALIZE("id", def.id);
|
SERIALIZE("id", id);
|
||||||
SERIALIZE("usr", def.usr);
|
SERIALIZE("usr", def.usr);
|
||||||
SERIALIZE("short_name", def.short_name);
|
SERIALIZE("short_name", def.short_name);
|
||||||
SERIALIZE("qualified_name", def.qualified_name);
|
SERIALIZE("qualified_name", def.qualified_name);
|
||||||
@ -154,7 +154,7 @@ void Serialize(Writer& writer, IndexedFile* file) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
SERIALIZE("id", def.id);
|
SERIALIZE("id", id);
|
||||||
SERIALIZE("usr", def.usr);
|
SERIALIZE("usr", def.usr);
|
||||||
SERIALIZE("short_name", def.short_name);
|
SERIALIZE("short_name", def.short_name);
|
||||||
SERIALIZE("qualified_name", def.qualified_name);
|
SERIALIZE("qualified_name", def.qualified_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user