mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-18 06:31:15 +00:00
QueryFile is now storing symbol indices directly
This commit is contained in:
parent
4249fc4a38
commit
74b1fe7194
@ -124,8 +124,7 @@ std::string Join(const std::vector<std::string>& elements, std::string sep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
optional<QueryableLocation> GetDefinitionSpellingOfUsr(QueryableDatabase* db, const Usr& usr) {
|
optional<QueryableLocation> GetDefinitionSpellingOfSymbol(QueryableDatabase* db, const SymbolIdx& symbol) {
|
||||||
SymbolIdx symbol = db->usr_to_symbol[usr];
|
|
||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryableTypeDef* def = &db->types[symbol.idx];
|
QueryableTypeDef* def = &db->types[symbol.idx];
|
||||||
@ -148,6 +147,10 @@ optional<QueryableLocation> GetDefinitionSpellingOfUsr(QueryableDatabase* db, co
|
|||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<QueryableLocation> GetDefinitionSpellingOfUsr(QueryableDatabase* db, const Usr& usr) {
|
||||||
|
return GetDefinitionSpellingOfSymbol(db, db->usr_to_symbol[usr]);
|
||||||
|
}
|
||||||
|
|
||||||
optional<QueryableLocation> GetDefinitionExtentOfUsr(QueryableDatabase* db, const Usr& usr) {
|
optional<QueryableLocation> GetDefinitionExtentOfUsr(QueryableDatabase* db, const Usr& usr) {
|
||||||
SymbolIdx symbol = db->usr_to_symbol[usr];
|
SymbolIdx symbol = db->usr_to_symbol[usr];
|
||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
@ -555,10 +558,10 @@ void QueryDbMainLoop(
|
|||||||
int target_line = msg->params.position.line + 1;
|
int target_line = msg->params.position.line + 1;
|
||||||
int target_column = msg->params.position.character + 1;
|
int target_column = msg->params.position.character + 1;
|
||||||
|
|
||||||
for (const UsrRef& ref : file->def.all_symbols) {
|
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
||||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
||||||
optional<QueryableLocation> location = GetDefinitionSpellingOfUsr(db, ref.usr);
|
optional<QueryableLocation> location = GetDefinitionSpellingOfSymbol(db, ref.idx);
|
||||||
if (location)
|
if (location)
|
||||||
response.result.push_back(GetLsLocation(location.value()));
|
response.result.push_back(GetLsLocation(location.value()));
|
||||||
break;
|
break;
|
||||||
@ -582,13 +585,12 @@ void QueryDbMainLoop(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "File outline size is " << file->def.outline.size() << std::endl;
|
std::cerr << "File outline size is " << file->def.outline.size() << std::endl;
|
||||||
for (UsrRef ref : file->def.outline) {
|
for (SymbolRef ref : file->def.outline) {
|
||||||
SymbolIdx symbol = db->usr_to_symbol[ref.usr];
|
SymbolIdx symbol = ref.idx;
|
||||||
|
|
||||||
lsSymbolInformation info;
|
lsSymbolInformation info;
|
||||||
info.location = GetLsLocation(ref.loc);
|
info.location = GetLsLocation(ref.loc);
|
||||||
|
|
||||||
// TODO: cleanup namespace/naming so there is only one SymbolKind.
|
|
||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryableTypeDef& def = db->types[symbol.idx];
|
QueryableTypeDef& def = db->types[symbol.idx];
|
||||||
@ -645,11 +647,11 @@ void QueryDbMainLoop(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UsrRef ref : file->def.outline) {
|
for (SymbolRef ref : file->def.outline) {
|
||||||
// NOTE: We OffsetColumn so that the code lens always show up in a
|
// NOTE: We OffsetColumn so that the code lens always show up in a
|
||||||
// predictable order. Otherwise, the client may randomize it.
|
// predictable order. Otherwise, the client may randomize it.
|
||||||
|
|
||||||
SymbolIdx symbol = db->usr_to_symbol[ref.usr];
|
SymbolIdx symbol = ref.idx;
|
||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryableTypeDef& def = db->types[symbol.idx];
|
QueryableTypeDef& def = db->types[symbol.idx];
|
||||||
|
@ -30,7 +30,7 @@ struct Id {
|
|||||||
uint64_t id;
|
uint64_t id;
|
||||||
|
|
||||||
Id() : id(0) {} // Needed for containers. Do not use directly.
|
Id() : id(0) {} // Needed for containers. Do not use directly.
|
||||||
Id(uint64_t id) : id(id) {}
|
explicit Id(uint64_t id) : id(id) {}
|
||||||
|
|
||||||
bool operator==(const Id<T>& other) const { return id == other.id; }
|
bool operator==(const Id<T>& other) const { return id == other.id; }
|
||||||
|
|
||||||
|
148
src/query.cc
148
src/query.cc
@ -135,46 +135,46 @@ QueryableFile::Def BuildFileDef(const IdMap& id_map, const IndexedFile& indexed)
|
|||||||
QueryableFile::Def def;
|
QueryableFile::Def def;
|
||||||
def.usr = indexed.path;
|
def.usr = indexed.path;
|
||||||
|
|
||||||
auto add_outline = [&def, &id_map](Usr usr, Range range) {
|
auto add_outline = [&def, &id_map](SymbolIdx idx, Range range) {
|
||||||
def.outline.push_back(UsrRef(usr, MapIdToUsr(id_map, range)));
|
def.outline.push_back(SymbolRef(idx, MapIdToUsr(id_map, range)));
|
||||||
};
|
};
|
||||||
auto add_all_symbols = [&def, &id_map](Usr usr, Range range) {
|
auto add_all_symbols = [&def, &id_map](SymbolIdx idx, Range range) {
|
||||||
def.all_symbols.push_back(UsrRef(usr, MapIdToUsr(id_map, range)));
|
def.all_symbols.push_back(SymbolRef(idx, MapIdToUsr(id_map, range)));
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const IndexedTypeDef& def : indexed.types) {
|
for (const IndexedTypeDef& def : indexed.types) {
|
||||||
if (def.def.definition_spelling.has_value())
|
if (def.def.definition_spelling.has_value())
|
||||||
add_all_symbols(def.def.usr, def.def.definition_spelling.value());
|
add_all_symbols(id_map.ToSymbol(def.id), def.def.definition_spelling.value());
|
||||||
if (def.def.definition_extent.has_value())
|
if (def.def.definition_extent.has_value())
|
||||||
add_outline(def.def.usr, def.def.definition_extent.value());
|
add_outline(id_map.ToSymbol(def.id), def.def.definition_extent.value());
|
||||||
for (const Range& use : def.uses)
|
for (const Range& use : def.uses)
|
||||||
add_all_symbols(def.def.usr, use);
|
add_all_symbols(id_map.ToSymbol(def.id), use);
|
||||||
}
|
}
|
||||||
for (const IndexedFuncDef& def : indexed.funcs) {
|
for (const IndexedFuncDef& def : indexed.funcs) {
|
||||||
if (def.def.definition_spelling.has_value())
|
if (def.def.definition_spelling.has_value())
|
||||||
add_all_symbols(def.def.usr, def.def.definition_spelling.value());
|
add_all_symbols(id_map.ToSymbol(def.id), def.def.definition_spelling.value());
|
||||||
if (def.def.definition_extent.has_value())
|
if (def.def.definition_extent.has_value())
|
||||||
add_outline(def.def.usr, def.def.definition_extent.value());
|
add_outline(id_map.ToSymbol(def.id), def.def.definition_extent.value());
|
||||||
for (Range decl : def.declarations) {
|
for (Range decl : def.declarations) {
|
||||||
add_outline(def.def.usr, decl);
|
add_outline(id_map.ToSymbol(def.id), decl);
|
||||||
add_all_symbols(def.def.usr, decl);
|
add_all_symbols(id_map.ToSymbol(def.id), decl);
|
||||||
}
|
}
|
||||||
for (const Range& use : def.uses)
|
for (const Range& use : def.uses)
|
||||||
add_all_symbols(def.def.usr, use);
|
add_all_symbols(id_map.ToSymbol(def.id), use);
|
||||||
}
|
}
|
||||||
for (const IndexedVarDef& def : indexed.vars) {
|
for (const IndexedVarDef& def : indexed.vars) {
|
||||||
if (def.def.definition_spelling.has_value())
|
if (def.def.definition_spelling.has_value())
|
||||||
add_all_symbols(def.def.usr, def.def.definition_spelling.value());
|
add_all_symbols(id_map.ToSymbol(def.id), def.def.definition_spelling.value());
|
||||||
if (def.def.definition_extent.has_value())
|
if (def.def.definition_extent.has_value())
|
||||||
add_outline(def.def.usr, def.def.definition_extent.value());
|
add_outline(id_map.ToSymbol(def.id), def.def.definition_extent.value());
|
||||||
for (const Range& use : def.uses)
|
for (const Range& use : def.uses)
|
||||||
add_all_symbols(def.def.usr, use);
|
add_all_symbols(id_map.ToSymbol(def.id), use);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(def.outline.begin(), def.outline.end(), [](const UsrRef& a, const UsrRef& b) {
|
std::sort(def.outline.begin(), def.outline.end(), [](const SymbolRef& a, const SymbolRef& b) {
|
||||||
return a.loc.range.start < b.loc.range.start;
|
return a.loc.range.start < b.loc.range.start;
|
||||||
});
|
});
|
||||||
std::sort(def.all_symbols.begin(), def.all_symbols.end(), [](const UsrRef& a, const UsrRef& b) {
|
std::sort(def.all_symbols.begin(), def.all_symbols.end(), [](const SymbolRef& a, const SymbolRef& b) {
|
||||||
return a.loc.range.start < b.loc.range.start;
|
return a.loc.range.start < b.loc.range.start;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -352,123 +352,101 @@ QueryFileId GetQueryFileIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
|||||||
auto it = query_db->usr_to_symbol.find(usr);
|
auto it = query_db->usr_to_symbol.find(usr);
|
||||||
if (it != query_db->usr_to_symbol.end()) {
|
if (it != query_db->usr_to_symbol.end()) {
|
||||||
assert(it->second.kind == SymbolKind::File);
|
assert(it->second.kind == SymbolKind::File);
|
||||||
return it->second.idx;
|
return QueryFileId(it->second.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = query_db->files.size();
|
size_t idx = query_db->files.size();
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::File, idx);
|
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::File, idx);
|
||||||
query_db->files.push_back(QueryableFile(usr));
|
query_db->files.push_back(QueryableFile(usr));
|
||||||
return idx;
|
return QueryFileId(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryTypeId GetQueryTypeIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
QueryTypeId GetQueryTypeIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
||||||
auto it = query_db->usr_to_symbol.find(usr);
|
auto it = query_db->usr_to_symbol.find(usr);
|
||||||
if (it != query_db->usr_to_symbol.end()) {
|
if (it != query_db->usr_to_symbol.end()) {
|
||||||
assert(it->second.kind == SymbolKind::Type);
|
assert(it->second.kind == SymbolKind::Type);
|
||||||
return it->second.idx;
|
return QueryTypeId(it->second.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = query_db->types.size();
|
size_t idx = query_db->types.size();
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Type, idx);
|
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Type, idx);
|
||||||
query_db->types.push_back(QueryableTypeDef(usr));
|
query_db->types.push_back(QueryableTypeDef(usr));
|
||||||
return idx;
|
return QueryTypeId(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryFuncId GetQueryFuncIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
QueryFuncId GetQueryFuncIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
||||||
auto it = query_db->usr_to_symbol.find(usr);
|
auto it = query_db->usr_to_symbol.find(usr);
|
||||||
if (it != query_db->usr_to_symbol.end()) {
|
if (it != query_db->usr_to_symbol.end()) {
|
||||||
assert(it->second.kind == SymbolKind::Func);
|
assert(it->second.kind == SymbolKind::Func);
|
||||||
return it->second.idx;
|
return QueryFuncId(it->second.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = query_db->funcs.size();
|
size_t idx = query_db->funcs.size();
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Func, idx);
|
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Func, idx);
|
||||||
query_db->funcs.push_back(QueryableFuncDef(usr));
|
query_db->funcs.push_back(QueryableFuncDef(usr));
|
||||||
return idx;
|
return QueryFuncId(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryVarId GetQueryVarIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
QueryVarId GetQueryVarIdFromUsr(QueryableDatabase* query_db, const Usr& usr) {
|
||||||
auto it = query_db->usr_to_symbol.find(usr);
|
auto it = query_db->usr_to_symbol.find(usr);
|
||||||
if (it != query_db->usr_to_symbol.end()) {
|
if (it != query_db->usr_to_symbol.end()) {
|
||||||
assert(it->second.kind == SymbolKind::Var);
|
assert(it->second.kind == SymbolKind::Var);
|
||||||
return it->second.idx;
|
return QueryVarId(it->second.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = query_db->vars.size();
|
size_t idx = query_db->vars.size();
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Var, idx);
|
query_db->usr_to_symbol[usr] = SymbolIdx(SymbolKind::Var, idx);
|
||||||
query_db->vars.push_back(QueryableVarDef(usr));
|
query_db->vars.push_back(QueryableVarDef(usr));
|
||||||
return idx;
|
return QueryVarId(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if false
|
|
||||||
int GetOrAddSymbol(QueryableDatabase* query_db, SymbolKind kind, const Usr& usr) {
|
|
||||||
// TODO: consider having separate lookup maps so they are smaller (maybe
|
|
||||||
// lookups will go faster).
|
|
||||||
auto it = query_db->usr_to_symbol.find(usr);
|
|
||||||
|
|
||||||
// Found; return existing symbol.
|
|
||||||
if (it != query_db->usr_to_symbol.end()) {
|
|
||||||
assert(it->second.kind == kind);
|
|
||||||
return it->second.idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found; add a new symbol.
|
|
||||||
switch (kind) {
|
|
||||||
case SymbolKind::File: {
|
|
||||||
int idx = query_db->files.size();
|
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(kind, idx);
|
|
||||||
query_db->files.push_back(QueryableFile(usr));
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
case SymbolKind::Type: {
|
|
||||||
int idx = query_db->types.size();
|
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(kind, idx);
|
|
||||||
query_db->types.push_back(QueryableTypeDef(usr));
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
case SymbolKind::Func: {
|
|
||||||
int idx = query_db->funcs.size();
|
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(kind, idx);
|
|
||||||
query_db->funcs.push_back(QueryableFuncDef(usr));
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
case SymbolKind::Var: {
|
|
||||||
int idx = query_db->vars.size();
|
|
||||||
query_db->usr_to_symbol[usr] = SymbolIdx(kind, idx);
|
|
||||||
query_db->vars.push_back(QueryableVarDef(usr));
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
case SymbolKind::Invalid: {
|
|
||||||
assert(false);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IdMap::IdMap(QueryableDatabase* query_db, const IdCache& local_ids)
|
IdMap::IdMap(QueryableDatabase* query_db, const IdCache& local_ids)
|
||||||
: local_ids(local_ids) {
|
: local_ids(local_ids) {
|
||||||
index_file_id = GetQueryFileIdFromUsr(query_db, local_ids.primary_file);
|
index_file_id = GetQueryFileIdFromUsr(query_db, local_ids.primary_file);
|
||||||
|
|
||||||
cached_type_ids_.reserve(local_ids.type_id_to_usr.size());
|
cached_type_ids_.set_empty_key(-1);
|
||||||
|
cached_type_ids_.resize(local_ids.type_id_to_usr.size());
|
||||||
for (const auto& entry : local_ids.type_id_to_usr)
|
for (const auto& entry : local_ids.type_id_to_usr)
|
||||||
cached_type_ids_[entry.first] = GetQueryTypeIdFromUsr(query_db, entry.second);
|
cached_type_ids_[entry.first.id] = GetQueryTypeIdFromUsr(query_db, entry.second).id;
|
||||||
|
|
||||||
cached_func_ids_.reserve(local_ids.func_id_to_usr.size());
|
cached_func_ids_.set_empty_key(-1);
|
||||||
|
cached_func_ids_.resize(local_ids.func_id_to_usr.size());
|
||||||
for (const auto& entry : local_ids.func_id_to_usr)
|
for (const auto& entry : local_ids.func_id_to_usr)
|
||||||
cached_func_ids_[entry.first] = GetQueryFuncIdFromUsr(query_db, entry.second);
|
cached_func_ids_[entry.first.id] = GetQueryFuncIdFromUsr(query_db, entry.second).id;
|
||||||
|
|
||||||
cached_var_ids_.reserve(local_ids.var_id_to_usr.size());
|
cached_var_ids_.set_empty_key(-1);
|
||||||
|
cached_var_ids_.resize(local_ids.var_id_to_usr.size());
|
||||||
for (const auto& entry : local_ids.var_id_to_usr)
|
for (const auto& entry : local_ids.var_id_to_usr)
|
||||||
cached_var_ids_[entry.first] = GetQueryVarIdFromUsr(query_db, entry.second);
|
cached_var_ids_[entry.first.id] = GetQueryVarIdFromUsr(query_db, entry.second).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryTypeId IdMap::ToQuery(IndexTypeId id) const {
|
||||||
|
assert(cached_type_ids_.find(id.id) != cached_type_ids_.end());
|
||||||
|
return QueryTypeId(cached_type_ids_.find(id.id)->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryFuncId IdMap::ToQuery(IndexFuncId id) const {
|
||||||
|
assert(cached_func_ids_.find(id.id) != cached_func_ids_.end());
|
||||||
|
return QueryFuncId(cached_func_ids_.find(id.id)->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryVarId IdMap::ToQuery(IndexVarId id) const {
|
||||||
|
assert(cached_var_ids_.find(id.id) != cached_var_ids_.end());
|
||||||
|
return QueryVarId(cached_var_ids_.find(id.id)->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolIdx IdMap::ToSymbol(IndexTypeId id) const {
|
||||||
|
return SymbolIdx(SymbolKind::Type, ToQuery(id).id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolIdx IdMap::ToSymbol(IndexFuncId id) const {
|
||||||
|
return SymbolIdx(SymbolKind::Func, ToQuery(id).id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolIdx IdMap::ToSymbol(IndexVarId id) const {
|
||||||
|
return SymbolIdx(SymbolKind::Var, ToQuery(id).id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -633,7 +611,7 @@ void IndexUpdate::Merge(const IndexUpdate& update) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UpdateQualifiedName(QueryableDatabase* db, int* qualified_name_index, SymbolKind kind, int symbol_index, const std::string& name) {
|
void UpdateQualifiedName(QueryableDatabase* db, size_t* qualified_name_index, SymbolKind kind, size_t symbol_index, const std::string& name) {
|
||||||
if (*qualified_name_index == -1) {
|
if (*qualified_name_index == -1) {
|
||||||
db->qualified_names.push_back(name);
|
db->qualified_names.push_back(name);
|
||||||
db->symbols.push_back(SymbolIdx(kind, symbol_index));
|
db->symbols.push_back(SymbolIdx(kind, symbol_index));
|
||||||
|
68
src/query.h
68
src/query.h
@ -56,6 +56,38 @@ struct QueryableLocation {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SymbolKind { Invalid, File, Type, Func, Var };
|
||||||
|
struct SymbolIdx {
|
||||||
|
SymbolKind kind;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
SymbolIdx() : kind(SymbolKind::Invalid), idx(-1) {} // Default ctor needed by stdlib. Do not use.
|
||||||
|
SymbolIdx(SymbolKind kind, uint64_t idx) : kind(kind), idx(idx) {}
|
||||||
|
|
||||||
|
bool operator==(const SymbolIdx& that) const {
|
||||||
|
return kind == that.kind && idx == that.idx;
|
||||||
|
}
|
||||||
|
bool operator!=(const SymbolIdx& that) const { return !(*this == that); }
|
||||||
|
bool operator<(const SymbolIdx& that) const {
|
||||||
|
return kind < that.kind || idx < that.idx;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SymbolRef {
|
||||||
|
SymbolIdx idx;
|
||||||
|
QueryableLocation loc;
|
||||||
|
|
||||||
|
SymbolRef(SymbolIdx idx, QueryableLocation loc) : idx(idx), loc(loc) {}
|
||||||
|
|
||||||
|
bool operator==(const SymbolRef& that) const {
|
||||||
|
return idx == that.idx && loc == that.loc;
|
||||||
|
}
|
||||||
|
bool operator!=(const SymbolRef& that) const { return !(*this == that); }
|
||||||
|
bool operator<(const SymbolRef& that) const {
|
||||||
|
return idx < that.idx && loc.range.start < that.loc.range.start;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct UsrRef {
|
struct UsrRef {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
QueryableLocation loc;
|
QueryableLocation loc;
|
||||||
@ -110,15 +142,15 @@ struct QueryableFile {
|
|||||||
struct Def {
|
struct Def {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
// Outline of the file (ie, for code lens).
|
// Outline of the file (ie, for code lens).
|
||||||
std::vector<UsrRef> outline;
|
std::vector<SymbolRef> outline;
|
||||||
// Every symbol found in the file (ie, for goto definition)
|
// Every symbol found in the file (ie, for goto definition)
|
||||||
std::vector<UsrRef> all_symbols;
|
std::vector<SymbolRef> all_symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DefUpdate = Def;
|
using DefUpdate = Def;
|
||||||
|
|
||||||
DefUpdate def;
|
DefUpdate def;
|
||||||
int qualified_name_idx = -1;
|
size_t qualified_name_idx = -1;
|
||||||
|
|
||||||
QueryableFile(const Usr& usr) { def.usr = usr; }
|
QueryableFile(const Usr& usr) { def.usr = usr; }
|
||||||
QueryableFile(const Def& def) : def(def) {}
|
QueryableFile(const Def& def) : def(def) {}
|
||||||
@ -135,7 +167,7 @@ struct QueryableTypeDef {
|
|||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
std::vector<Usr> instantiations;
|
std::vector<Usr> instantiations;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
int qualified_name_idx = -1;
|
size_t qualified_name_idx = -1;
|
||||||
|
|
||||||
QueryableTypeDef(const Usr& usr) : def(usr) {}
|
QueryableTypeDef(const Usr& usr) : def(usr) {}
|
||||||
QueryableTypeDef(const DefUpdate& def) : def(def) {}
|
QueryableTypeDef(const DefUpdate& def) : def(def) {}
|
||||||
@ -154,7 +186,7 @@ struct QueryableFuncDef {
|
|||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
std::vector<UsrRef> callers;
|
std::vector<UsrRef> callers;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
int qualified_name_idx = -1;
|
size_t qualified_name_idx = -1;
|
||||||
|
|
||||||
QueryableFuncDef(const Usr& usr) : def(usr) {}
|
QueryableFuncDef(const Usr& usr) : def(usr) {}
|
||||||
QueryableFuncDef(const DefUpdate& def) : def(def) {}
|
QueryableFuncDef(const DefUpdate& def) : def(def) {}
|
||||||
@ -167,23 +199,13 @@ struct QueryableVarDef {
|
|||||||
|
|
||||||
DefUpdate def;
|
DefUpdate def;
|
||||||
std::vector<QueryableLocation> uses;
|
std::vector<QueryableLocation> uses;
|
||||||
int qualified_name_idx = -1;
|
size_t qualified_name_idx = -1;
|
||||||
|
|
||||||
QueryableVarDef(const Usr& usr) : def(usr) {}
|
QueryableVarDef(const Usr& usr) : def(usr) {}
|
||||||
QueryableVarDef(const DefUpdate& def) : def(def) {}
|
QueryableVarDef(const DefUpdate& def) : def(def) {}
|
||||||
QueryableVarDef(const IdMap& id_map, const IndexedVarDef& indexed);
|
QueryableVarDef(const IdMap& id_map, const IndexedVarDef& indexed);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SymbolKind { Invalid, File, Type, Func, Var };
|
|
||||||
struct SymbolIdx {
|
|
||||||
SymbolKind kind;
|
|
||||||
uint64_t idx;
|
|
||||||
|
|
||||||
SymbolIdx() : kind(SymbolKind::Invalid), idx(-1) {} // Default ctor needed by stdlib. Do not use.
|
|
||||||
SymbolIdx(SymbolKind kind, uint64_t idx) : kind(kind), idx(idx) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct IndexUpdate {
|
struct IndexUpdate {
|
||||||
// Creates a new IndexUpdate based on the delta from previous to current. If
|
// Creates a new IndexUpdate based on the delta from previous to current. If
|
||||||
// no delta computation should be done just pass null for previous.
|
// no delta computation should be done just pass null for previous.
|
||||||
@ -272,10 +294,18 @@ struct IdMap {
|
|||||||
|
|
||||||
IdMap(QueryableDatabase* query_db, const IdCache& local_ids);
|
IdMap(QueryableDatabase* query_db, const IdCache& local_ids);
|
||||||
|
|
||||||
|
QueryTypeId ToQuery(IndexTypeId id) const;
|
||||||
|
QueryFuncId ToQuery(IndexFuncId id) const;
|
||||||
|
QueryVarId ToQuery(IndexVarId id) const;
|
||||||
|
SymbolIdx ToSymbol(IndexTypeId id) const;
|
||||||
|
SymbolIdx ToSymbol(IndexFuncId id) const;
|
||||||
|
SymbolIdx ToSymbol(IndexVarId id) const;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
private:
|
private:
|
||||||
QueryFileId index_file_id;
|
QueryFileId index_file_id;
|
||||||
std::unordered_map<IndexTypeId, QueryTypeId> cached_type_ids_;
|
// TODO: make these type safe
|
||||||
std::unordered_map<IndexFuncId, QueryFuncId> cached_func_ids_;
|
google::dense_hash_map<size_t, size_t> cached_type_ids_; // IndexTypeId -> QueryTypeId
|
||||||
std::unordered_map<IndexVarId, QueryVarId> cached_var_ids_;
|
google::dense_hash_map<size_t, size_t> cached_func_ids_; // IndexFuncId -> QueryFuncId
|
||||||
|
google::dense_hash_map<size_t, size_t> cached_var_ids_; // IndexVarId -> QueryVarId
|
||||||
};
|
};
|
||||||
|
@ -56,7 +56,7 @@ void DiffDocuments(std::string path, rapidjson::Document& expected, rapidjson::D
|
|||||||
|
|
||||||
int max_diff = 5;
|
int max_diff = 5;
|
||||||
|
|
||||||
int len = std::min(actual_output.size(), expected_output.size());
|
size_t len = std::min(actual_output.size(), expected_output.size());
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
if (actual_output[i] != expected_output[i]) {
|
if (actual_output[i] != expected_output[i]) {
|
||||||
if (--max_diff < 0) {
|
if (--max_diff < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user