mirror of
https://github.com/MaskRay/ccls.git
synced 2025-03-31 05:52:09 +00:00
Change optional<...> Query{Func,Type}::Def to forward_list
This commit is contained in:
parent
cfdb6bf422
commit
0f03146daa
@ -117,16 +117,16 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
||||
// This switch statement also filters out symbols that are not highlighted.
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (!func.def)
|
||||
const QueryFunc::Def* def = db->GetFunc(sym).AnyDef();
|
||||
if (!def)
|
||||
continue; // applies to for loop
|
||||
// Don't highlight overloadable operators or implicit lambda ->
|
||||
// std::function constructor.
|
||||
std::string_view short_name = func.def->ShortName();
|
||||
std::string_view short_name = def->ShortName();
|
||||
if (short_name.compare(0, 8, "operator") == 0 ||
|
||||
short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
|
||||
continue; // applies to for loop
|
||||
kind = func.def->kind;
|
||||
kind = def->kind;
|
||||
detailed_name = short_name;
|
||||
|
||||
// Check whether the function name is actually there.
|
||||
|
@ -35,16 +35,14 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||
});
|
||||
for (SymbolRef sym : syms) {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def)
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
out.result = GetLsLocations(db, working_files,
|
||||
ToUses(db, type.def->parents));
|
||||
ToUses(db, def->parents));
|
||||
break;
|
||||
} else if (sym.kind == SymbolKind::Func) {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (func.def)
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||
out.result = GetLsLocations(db, working_files,
|
||||
ToUses(db, func.def->base));
|
||||
ToUses(db, def->base));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -53,15 +53,16 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
|
||||
WorkingFiles* working_files,
|
||||
QueryFuncId root) {
|
||||
QueryFunc& root_func = db->funcs[root.id];
|
||||
if (!root_func.def || !root_func.def->spell)
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def || !def->spell)
|
||||
return {};
|
||||
optional<lsLocation> def_loc =
|
||||
GetLsLocation(db, working_files, *root_func.def->spell);
|
||||
GetLsLocation(db, working_files, *def->spell);
|
||||
if (!def_loc)
|
||||
return {};
|
||||
|
||||
Out_CqueryCallTree::CallEntry entry;
|
||||
entry.name = root_func.def->ShortName();
|
||||
entry.name = def->ShortName();
|
||||
entry.usr = std::to_string(root_func.usr);
|
||||
entry.location = *def_loc;
|
||||
entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func);
|
||||
@ -75,7 +76,8 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
||||
WorkingFiles* working_files,
|
||||
QueryFuncId root) {
|
||||
QueryFunc& root_func = db->funcs[root.id];
|
||||
if (!root_func.def)
|
||||
const QueryFunc::Def* root_func_def = root_func.AnyDef();
|
||||
if (!root_func_def)
|
||||
return {};
|
||||
|
||||
std::vector<Out_CqueryCallTree::CallEntry> result;
|
||||
@ -107,11 +109,12 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
||||
|
||||
if (caller.kind == SymbolKind::Func) {
|
||||
QueryFunc& call_func = db->GetFunc(caller);
|
||||
if (!call_func.def)
|
||||
const QueryFunc::Def* def = call_func.AnyDef();
|
||||
if (!def)
|
||||
return;
|
||||
|
||||
Out_CqueryCallTree::CallEntry call_entry;
|
||||
call_entry.name = call_func.def->ShortName();
|
||||
call_entry.name = def->ShortName();
|
||||
call_entry.usr = std::to_string(call_func.usr);
|
||||
call_entry.location = *call_location;
|
||||
call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func);
|
||||
|
@ -38,17 +38,17 @@ MAKE_REFLECT_STRUCT(Out_CqueryMemberHierarchy, jsonrpc, id, result);
|
||||
|
||||
std::vector<Out_CqueryMemberHierarchy::Entry>
|
||||
BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
|
||||
QueryType& root_type = db->types[root.id];
|
||||
if (!root_type.def || !root_type.def->spell)
|
||||
const auto* root_type = db->types[root.id].AnyDef();
|
||||
if (!root_type || !root_type->spell)
|
||||
return {};
|
||||
optional<lsLocation> def_loc =
|
||||
GetLsLocation(db, working_files, *root_type.def->spell);
|
||||
GetLsLocation(db, working_files, *root_type->spell);
|
||||
if (!def_loc)
|
||||
return {};
|
||||
|
||||
Out_CqueryMemberHierarchy::Entry entry;
|
||||
entry.type_id = root;
|
||||
entry.name = root_type.def->ShortName();
|
||||
entry.name = root_type->ShortName();
|
||||
entry.location = *def_loc;
|
||||
return {entry};
|
||||
}
|
||||
|
@ -45,12 +45,12 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
||||
int n = 0;
|
||||
|
||||
for (RawId i = 0; i < db->funcs.size(); i++)
|
||||
if (db->funcs[i].def) {
|
||||
if (db->funcs[i].AnyDef()) {
|
||||
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Func});
|
||||
sym2id[syms.back()] = n++;
|
||||
}
|
||||
for (RawId i = 0; i < db->types.size(); i++)
|
||||
if (db->types[i].def) {
|
||||
if (db->types[i].AnyDef()) {
|
||||
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Type});
|
||||
sym2id[syms.back()] = n++;
|
||||
}
|
||||
@ -77,12 +77,12 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
||||
n++;
|
||||
}
|
||||
for (QueryType& type : db->types)
|
||||
if (type.AnyDef()) {
|
||||
if (const auto* def = type.AnyDef()) {
|
||||
add(type.uses, 1);
|
||||
Add(sym2id, adj, type.instances, n);
|
||||
Add(sym2id, adj, type.def->funcs, n);
|
||||
Add(sym2id, adj, type.def->types, n);
|
||||
Add(sym2id, adj, type.def->vars, n);
|
||||
Add(sym2id, adj, def->funcs, n);
|
||||
Add(sym2id, adj, def->types, n);
|
||||
Add(sym2id, adj, def->vars, n);
|
||||
n++;
|
||||
}
|
||||
for (QueryVar& var : db->vars)
|
||||
|
@ -32,14 +32,15 @@ BuildParentInheritanceHierarchyForType(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryType& root_type) {
|
||||
std::vector<Out_CqueryTypeHierarchyTree::TypeEntry> parent_entries;
|
||||
parent_entries.reserve(root_type.def->parents.size());
|
||||
const QueryType::Def* def = root_type.AnyDef();
|
||||
parent_entries.reserve(def->parents.size());
|
||||
|
||||
EachWithGen(db->types, root_type.def->parents, [&](QueryType& parent_type) {
|
||||
EachWithGen(db->types, def->parents, [&](QueryType& parent_type) {
|
||||
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
||||
parent_entry.name = parent_type.def->detailed_name.c_str();
|
||||
if (parent_type.def->spell)
|
||||
parent_entry.location = GetLsLocation(
|
||||
db, working_files, *parent_type.def->spell);
|
||||
const QueryType::Def* def1 = parent_type.AnyDef();
|
||||
parent_entry.name = def1->detailed_name.c_str();
|
||||
if (def1->spell)
|
||||
parent_entry.location = GetLsLocation(db, working_files, *def1->spell);
|
||||
parent_entry.children =
|
||||
BuildParentInheritanceHierarchyForType(db, working_files, parent_type);
|
||||
|
||||
@ -54,12 +55,12 @@ BuildInheritanceHierarchyForType(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryType& root_type) {
|
||||
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
||||
const QueryType::Def* def = root_type.AnyDef();
|
||||
|
||||
// Name and location.
|
||||
entry.name = root_type.def->detailed_name;
|
||||
if (root_type.def->spell)
|
||||
entry.location =
|
||||
GetLsLocation(db, working_files, *root_type.def->spell);
|
||||
entry.name = def->detailed_name;
|
||||
if (def->spell)
|
||||
entry.location = GetLsLocation(db, working_files, *def->spell);
|
||||
|
||||
entry.children.reserve(root_type.derived.size());
|
||||
|
||||
@ -90,20 +91,20 @@ BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||
std::vector<Out_CqueryTypeHierarchyTree::TypeEntry> entries;
|
||||
|
||||
QueryFunc& root_func = db->funcs[root.id];
|
||||
if (!root_func.def || root_func.def->base.empty())
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def || def->base.empty())
|
||||
return {};
|
||||
|
||||
// FIXME WithGen
|
||||
for (auto parent_id : root_func.def->base) {
|
||||
for (auto parent_id : def->base) {
|
||||
QueryFunc& parent_func = db->funcs[parent_id.id];
|
||||
if (!parent_func.def)
|
||||
const QueryFunc::Def* def1 = parent_func.AnyDef();
|
||||
if (!def1)
|
||||
continue;
|
||||
|
||||
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
||||
parent_entry.name = parent_func.def->detailed_name;
|
||||
if (parent_func.def->spell)
|
||||
parent_entry.location = GetLsLocation(
|
||||
db, working_files, *parent_func.def->spell);
|
||||
parent_entry.name = def1->detailed_name;
|
||||
if (def1->spell)
|
||||
parent_entry.location = GetLsLocation(db, working_files, *def1->spell);
|
||||
parent_entry.children =
|
||||
BuildParentInheritanceHierarchyForFunc(db, working_files, parent_id);
|
||||
|
||||
@ -118,16 +119,17 @@ BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||
WorkingFiles* working_files,
|
||||
QueryFuncId root_id) {
|
||||
QueryFunc& root_func = db->funcs[root_id.id];
|
||||
if (!root_func.def)
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def)
|
||||
return nullopt;
|
||||
|
||||
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
||||
|
||||
// Name and location.
|
||||
entry.name = root_func.def->detailed_name;
|
||||
if (root_func.def->spell)
|
||||
entry.name = def->detailed_name;
|
||||
if (def->spell)
|
||||
entry.location =
|
||||
GetLsLocation(db, working_files, *root_func.def->spell);
|
||||
GetLsLocation(db, working_files, *def->spell);
|
||||
|
||||
entry.children.reserve(root_func.derived.size());
|
||||
|
||||
@ -169,7 +171,7 @@ struct CqueryTypeHierarchyTreeHandler
|
||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||
if (sym.kind == SymbolKind::Type) {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def)
|
||||
if (type.AnyDef())
|
||||
out.result =
|
||||
BuildInheritanceHierarchyForType(db, working_files, type);
|
||||
break;
|
||||
|
@ -69,13 +69,14 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
|
||||
for (SymbolRef sym : file->def->outline) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
// Note: we ignore the definition if it is in the same file (ie,
|
||||
// possibly a header).
|
||||
if (func.def && func.def->extent) {
|
||||
QueryFileId t = func.def->extent->file;
|
||||
if (t != file_id)
|
||||
return t;
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef()) {
|
||||
// Note: we ignore the definition if it is in the same file (ie,
|
||||
// possibly a header).
|
||||
if (def->extent) {
|
||||
QueryFileId t = def->extent->file;
|
||||
if (t != file_id)
|
||||
return t;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -149,7 +150,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
||||
QueryFileId decl_file_id,
|
||||
QueryFileId impl_file_id,
|
||||
QueryFunc& func) {
|
||||
assert(func.def);
|
||||
const QueryFunc::Def* def = func.AnyDef();
|
||||
assert(def);
|
||||
for (Use decl : func.declarations) {
|
||||
if (decl.file != decl_file_id)
|
||||
continue;
|
||||
@ -160,12 +162,12 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
||||
|
||||
optional<std::string> type_name;
|
||||
optional<lsPosition> same_file_insert_end;
|
||||
if (func.def->declaring_type) {
|
||||
QueryType& declaring_type = db->types[func.def->declaring_type->id];
|
||||
if (declaring_type.def) {
|
||||
type_name = std::string(declaring_type.def->ShortName());
|
||||
optional<lsRange> ls_type_extent = GetLsRange(
|
||||
working_file, declaring_type.def->extent->range);
|
||||
if (def->declaring_type) {
|
||||
QueryType& declaring_type = db->types[def->declaring_type->id];
|
||||
if (const auto* def1 = declaring_type.AnyDef()) {
|
||||
type_name = std::string(def1->ShortName());
|
||||
optional<lsRange> ls_type_extent =
|
||||
GetLsRange(working_file, def1->extent->range);
|
||||
if (ls_type_extent) {
|
||||
same_file_insert_end = ls_type_extent->end;
|
||||
same_file_insert_end->character += 1; // move past semicolon.
|
||||
@ -201,7 +203,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& sym_func = db->GetFunc(sym);
|
||||
if (!sym_func.def || !sym_func.def->extent)
|
||||
const QueryFunc::Def* def1 = sym_func.AnyDef();
|
||||
if (!def1 || !def1->extent)
|
||||
break;
|
||||
|
||||
for (Use func_decl : sym_func.declarations) {
|
||||
@ -209,7 +212,7 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
||||
int dist = func_decl.range.start.line - decl.range.start.line;
|
||||
if (abs(dist) < abs(best_dist)) {
|
||||
optional<lsLocation> def_loc = GetLsLocation(
|
||||
db, working_files, *sym_func.def->extent);
|
||||
db, working_files, *def1->extent);
|
||||
if (!def_loc)
|
||||
continue;
|
||||
|
||||
@ -347,7 +350,8 @@ struct TextDocumentCodeActionHandler
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (!type.def)
|
||||
const QueryType::Def* def = type.AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
int num_edits = 0;
|
||||
@ -355,8 +359,9 @@ struct TextDocumentCodeActionHandler
|
||||
// Get implementation file.
|
||||
Out_TextDocumentCodeAction::Command command;
|
||||
|
||||
EachWithGen(db->funcs, type.def->funcs, [&](QueryFunc& func_def) {
|
||||
if (func_def.def->extent)
|
||||
EachWithGen(db->funcs, def->funcs, [&](QueryFunc& func_def) {
|
||||
const QueryFunc::Def* def1 = func_def.AnyDef();
|
||||
if (def1->extent)
|
||||
return;
|
||||
EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/);
|
||||
optional<lsTextEdit> edit = BuildAutoImplementForFunction(
|
||||
@ -390,7 +395,7 @@ struct TextDocumentCodeActionHandler
|
||||
|
||||
command.arguments.textDocumentUri = *impl_uri;
|
||||
command.title = "Auto-Implement " + std::to_string(num_edits) +
|
||||
" methods on " + std::string(type.def->ShortName());
|
||||
" methods on " + std::string(def->ShortName());
|
||||
command.command = "cquery._autoImplement";
|
||||
out.result.push_back(command);
|
||||
break;
|
||||
@ -398,14 +403,15 @@ struct TextDocumentCodeActionHandler
|
||||
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (!func.def || func.def->extent)
|
||||
const QueryFunc::Def* def = func.AnyDef();
|
||||
if (!def || def->extent)
|
||||
break;
|
||||
|
||||
EnsureImplFile(db, file_id, impl_uri /*out*/, impl_file_id /*out*/);
|
||||
|
||||
// Get implementation file.
|
||||
Out_TextDocumentCodeAction::Command command;
|
||||
command.title = "Auto-Implement " + std::string(func.def->ShortName());
|
||||
command.title = "Auto-Implement " + std::string(def->ShortName());
|
||||
command.command = "cquery._autoImplement";
|
||||
command.arguments.textDocumentUri = *impl_uri;
|
||||
optional<lsTextEdit> edit = BuildAutoImplementForFunction(
|
||||
|
@ -155,9 +155,8 @@ struct TextDocumentCodeLensHandler
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (!type.def)
|
||||
continue;
|
||||
if (type.def->kind == ClangSymbolKind::Namespace)
|
||||
const QueryType::Def* def = type.AnyDef();
|
||||
if (!def || def->kind == ClangSymbolKind::Namespace)
|
||||
continue;
|
||||
AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0),
|
||||
type.uses, true /*force_display*/);
|
||||
@ -169,7 +168,8 @@ struct TextDocumentCodeLensHandler
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (!func.def)
|
||||
const QueryFunc::Def* def = func.AnyDef();
|
||||
if (!def)
|
||||
continue;
|
||||
|
||||
int16_t offset = 0;
|
||||
@ -215,9 +215,9 @@ struct TextDocumentCodeLensHandler
|
||||
ToUses(db, func.derived), false /*force_display*/);
|
||||
|
||||
// "Base"
|
||||
if (func.def->base.size() == 1) {
|
||||
if (def->base.size() == 1) {
|
||||
Maybe<Use> base_loc = GetDefinitionSpellingOfSymbol(
|
||||
db, SymbolIdx{func.def->base[0], SymbolKind::Func});
|
||||
db, SymbolIdx{def->base[0], SymbolKind::Func});
|
||||
if (base_loc) {
|
||||
optional<lsLocation> ls_base =
|
||||
GetLsLocation(db, working_files, *base_loc);
|
||||
@ -239,7 +239,7 @@ struct TextDocumentCodeLensHandler
|
||||
}
|
||||
} else {
|
||||
AddCodeLens("base", "base", &common, OffsetStartColumn(sym, 1),
|
||||
ToUses(db, func.def->base),
|
||||
ToUses(db, def->base),
|
||||
false /*force_display*/);
|
||||
}
|
||||
|
||||
|
16
src/query.cc
16
src/query.cc
@ -752,8 +752,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
|
||||
QueryType& type = types[usr_to_type[usr].id];
|
||||
if (type.symbol_idx)
|
||||
symbols[type.symbol_idx->id].kind = SymbolKind::Invalid;
|
||||
//type.def = QueryType::Def();
|
||||
type.def = nullopt;
|
||||
type.def.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -762,8 +761,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
|
||||
QueryFunc& func = funcs[usr_to_func[usr].id];
|
||||
if (func.symbol_idx)
|
||||
symbols[func.symbol_idx->id].kind = SymbolKind::Invalid;
|
||||
//func.def = QueryFunc::Def();
|
||||
func.def = nullopt;
|
||||
func.def.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -851,9 +849,9 @@ void QueryDatabase::ImportOrUpdate(
|
||||
QueryType& existing = types[it->second.id];
|
||||
|
||||
// Keep the existing definition if it is higher quality.
|
||||
if (!(existing.def && existing.def->spell &&
|
||||
!def.value.spell)) {
|
||||
existing.def = std::move(def.value);
|
||||
if (!(existing.AnyDef() && existing.AnyDef()->spell &&
|
||||
!def.value.spell)) {
|
||||
existing.def.push_front(std::move(def.value));
|
||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, it->second);
|
||||
}
|
||||
}
|
||||
@ -873,9 +871,9 @@ void QueryDatabase::ImportOrUpdate(
|
||||
QueryFunc& existing = funcs[it->second.id];
|
||||
|
||||
// Keep the existing definition if it is higher quality.
|
||||
if (!(existing.def && existing.def->spell &&
|
||||
if (!(existing.AnyDef() && existing.AnyDef()->spell &&
|
||||
!def.value.spell)) {
|
||||
existing.def = std::move(def.value);
|
||||
existing.def.push_front(std::move(def.value));
|
||||
UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, it->second);
|
||||
}
|
||||
}
|
||||
|
24
src/query.h
24
src/query.h
@ -140,14 +140,20 @@ struct QueryType {
|
||||
|
||||
Usr usr;
|
||||
Maybe<Id<void>> symbol_idx;
|
||||
optional<Def> def;
|
||||
std::forward_list<Def> def;
|
||||
std::vector<QueryTypeId> derived;
|
||||
std::vector<QueryVarId> instances;
|
||||
std::vector<Use> uses;
|
||||
|
||||
explicit QueryType(const Usr& usr) : usr(usr) {}
|
||||
const Def* AnyDef() const { return def ? &*def : nullptr; }
|
||||
Def* AnyDef() { return def ? &*def : nullptr; }
|
||||
const Def* AnyDef() const {
|
||||
if (def.empty()) return nullptr;
|
||||
return &def.front();
|
||||
}
|
||||
Def* AnyDef() {
|
||||
if (def.empty()) return nullptr;
|
||||
return &def.front();
|
||||
}
|
||||
};
|
||||
|
||||
struct QueryFunc {
|
||||
@ -159,14 +165,20 @@ struct QueryFunc {
|
||||
|
||||
Usr usr;
|
||||
Maybe<Id<void>> symbol_idx;
|
||||
optional<Def> def;
|
||||
std::forward_list<Def> def;
|
||||
std::vector<Use> declarations;
|
||||
std::vector<QueryFuncId> derived;
|
||||
std::vector<Use> uses;
|
||||
|
||||
explicit QueryFunc(const Usr& usr) : usr(usr) {}
|
||||
const Def* AnyDef() const { return def ? &*def : nullptr; }
|
||||
Def* AnyDef() { return def ? &*def : nullptr; }
|
||||
const Def* AnyDef() const {
|
||||
if (def.empty()) return nullptr;
|
||||
return &def.front();
|
||||
}
|
||||
Def* AnyDef() {
|
||||
if (def.empty()) return nullptr;
|
||||
return &def.front();
|
||||
}
|
||||
};
|
||||
|
||||
struct QueryVar {
|
||||
|
@ -21,16 +21,16 @@ int ComputeRangeSize(const Range& range) {
|
||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
SymbolIdx sym) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def)
|
||||
return type.def->spell;
|
||||
case SymbolKind::File:
|
||||
break;
|
||||
case SymbolKind::Func: {
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||
return def->spell;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (func.def)
|
||||
return func.def->spell;
|
||||
case SymbolKind::Type: {
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
return def->spell;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
@ -39,8 +39,6 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
return def->spell;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::File:
|
||||
break;
|
||||
case SymbolKind::Invalid:
|
||||
assert(false && "unexpected");
|
||||
break;
|
||||
@ -50,16 +48,17 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
|
||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def)
|
||||
return type.def->extent;
|
||||
case SymbolKind::File:
|
||||
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
||||
Role::None, QueryFileId(sym.id));
|
||||
case SymbolKind::Func: {
|
||||
if (const auto* def = db->GetFunc(sym).AnyDef())
|
||||
return def->extent;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (func.def)
|
||||
return func.def->extent;
|
||||
case SymbolKind::Type: {
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
return def->extent;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
@ -68,9 +67,6 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
||||
return def->extent;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::File:
|
||||
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
||||
Role::None, QueryFileId(sym.id));
|
||||
case SymbolKind::Invalid: {
|
||||
assert(false && "unexpected");
|
||||
break;
|
||||
@ -82,28 +78,26 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
||||
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||
SymbolIdx sym) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def)
|
||||
return type.def->file;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::File:
|
||||
return QueryFileId(sym.id);
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (!func.declarations.empty())
|
||||
return func.declarations[0].file;
|
||||
if (func.def)
|
||||
return func.def->file;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
const QueryVar::Def* def = db->GetVar(sym).AnyDef();
|
||||
if (def)
|
||||
if (const auto* def = func.AnyDef())
|
||||
return def->file;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Type: {
|
||||
if (const auto* def = db->GetType(sym).AnyDef())
|
||||
return def->file;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
if (const auto* def = db->GetVar(sym).AnyDef())
|
||||
return def->file;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::File:
|
||||
return QueryFileId(sym.id);
|
||||
case SymbolKind::Invalid: {
|
||||
assert(false && "unexpected");
|
||||
break;
|
||||
@ -118,8 +112,9 @@ std::vector<Use> ToUses(QueryDatabase* db,
|
||||
ret.reserve(ids.size());
|
||||
for (auto id : ids) {
|
||||
QueryFunc& func = db->funcs[id.id];
|
||||
if (func.def && func.def->spell)
|
||||
ret.push_back(*func.def->spell);
|
||||
const QueryFunc::Def* def = func.AnyDef();
|
||||
if (def && def->spell)
|
||||
ret.push_back(*def->spell);
|
||||
else if (func.declarations.size())
|
||||
ret.push_back(func.declarations[0]);
|
||||
}
|
||||
@ -132,8 +127,9 @@ std::vector<Use> ToUses(QueryDatabase* db,
|
||||
ret.reserve(ids.size());
|
||||
for (auto id : ids) {
|
||||
QueryType& type = db->types[id.id];
|
||||
if (type.def && type.def->spell)
|
||||
ret.push_back(*type.def->spell);
|
||||
const QueryType::Def* def = type.AnyDef();
|
||||
if (def && def->spell)
|
||||
ret.push_back(*def->spell);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -143,7 +139,7 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
|
||||
ret.reserve(ids.size());
|
||||
for (auto id : ids) {
|
||||
QueryVar& var = db->vars[id.id];
|
||||
QueryVar::Def* def = var.AnyDef();
|
||||
const QueryVar::Def* def = var.AnyDef();
|
||||
if (def && def->spell)
|
||||
ret.push_back(*def->spell);
|
||||
else if (var.declarations.size())
|
||||
@ -205,11 +201,10 @@ std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||
// function has the postfix `ForGotoDefintion`, but it lets the user
|
||||
// jump to the start of a type if clicking goto-definition on the same
|
||||
// type from within the type definition.
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (type.def) {
|
||||
Maybe<Use> def = type.def->spell;
|
||||
if (def)
|
||||
return {*def};
|
||||
if (const auto* def = db->GetType(sym).AnyDef()) {
|
||||
Maybe<Use> spell = def->spell;
|
||||
if (spell)
|
||||
return {*spell};
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -228,10 +223,11 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
// Check self.
|
||||
if (!root.uses.empty())
|
||||
return true;
|
||||
const QueryFunc::Def* def = root.AnyDef();
|
||||
|
||||
// Check for base calls.
|
||||
std::queue<QueryFunc*> queue;
|
||||
EachWithGen<QueryFunc>(db->funcs, root.def->base, [&](QueryFunc& func) {
|
||||
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func) {
|
||||
queue.push(&func);
|
||||
});
|
||||
while (!queue.empty()) {
|
||||
@ -239,8 +235,8 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
queue.pop();
|
||||
if (!func.uses.empty())
|
||||
return true;
|
||||
if (func.def)
|
||||
EachWithGen<QueryFunc>(db->funcs, func.def->base, [&](QueryFunc& func1) {
|
||||
if (def)
|
||||
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
});
|
||||
}
|
||||
@ -265,11 +261,12 @@ bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
QueryFunc& root) {
|
||||
std::vector<Use> callers;
|
||||
if (!root.def)
|
||||
const QueryFunc::Def* def = root.AnyDef();
|
||||
if (!def)
|
||||
return callers;
|
||||
|
||||
std::queue<QueryFunc*> queue;
|
||||
EachWithGen<QueryFunc>(db->funcs, root.def->base, [&](QueryFunc& func1) {
|
||||
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
});
|
||||
while (!queue.empty()) {
|
||||
@ -277,8 +274,8 @@ std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
queue.pop();
|
||||
|
||||
AddRange(&callers, func.uses);
|
||||
if (func.def)
|
||||
EachWithGen<QueryFunc>(db->funcs, func.def->base, [&](QueryFunc& func1) {
|
||||
if (def)
|
||||
EachWithGen<QueryFunc>(db->funcs, def->base, [&](QueryFunc& func1) {
|
||||
queue.push(&func1);
|
||||
});
|
||||
}
|
||||
@ -453,19 +450,19 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->GetType(sym);
|
||||
if (!type.def)
|
||||
const QueryType::Def* def = db->GetType(sym).AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
lsSymbolInformation info;
|
||||
if (use_short_name)
|
||||
info.name = type.def->ShortName();
|
||||
info.name = def->ShortName();
|
||||
else
|
||||
info.name = type.def->detailed_name;
|
||||
if (type.def->detailed_name.c_str() != type.def->ShortName())
|
||||
info.containerName = type.def->detailed_name;
|
||||
info.name = def->detailed_name;
|
||||
if (def->detailed_name.c_str() != def->ShortName())
|
||||
info.containerName = def->detailed_name;
|
||||
// TODO ClangSymbolKind -> lsSymbolKind
|
||||
switch (type.def->kind) {
|
||||
switch (def->kind) {
|
||||
default:
|
||||
info.kind = lsSymbolKind::Class;
|
||||
break;
|
||||
@ -476,17 +473,17 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||
return info;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
if (!func.def)
|
||||
const QueryFunc::Def* def = db->GetFunc(sym).AnyDef();
|
||||
if (!def)
|
||||
break;
|
||||
|
||||
lsSymbolInformation info;
|
||||
if (use_short_name)
|
||||
info.name = func.def->ShortName();
|
||||
info.name = def->ShortName();
|
||||
else
|
||||
info.name = func.def->detailed_name;
|
||||
info.containerName = func.def->detailed_name;
|
||||
switch (func.def->kind) {
|
||||
info.name = def->detailed_name;
|
||||
info.containerName = def->detailed_name;
|
||||
switch (def->kind) {
|
||||
default:
|
||||
info.kind = lsSymbolKind::Function;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user