Change optional<...> QueryVar::Def to forward_list

Related to #403
This commit is contained in:
Fangrui Song 2018-02-17 21:52:14 -08:00
parent 7e45983d6d
commit cfdb6bf422
12 changed files with 131 additions and 118 deletions

View File

@ -148,20 +148,18 @@ void EmitSemanticHighlighting(QueryDatabase* db,
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); if (const QueryVar::Def* def = db->GetVar(sym).AnyDef()) {
if (!var.def) kind = def->kind;
continue; // applies to for loop storage = def->storage;
kind = var.def->kind; detailed_name = def->ShortName();
storage = var.def->storage; }
detailed_name = var.def->ShortName();
break; break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(sym); if (const QueryType::Def* def = db->GetType(sym).AnyDef()) {
if (!type.def) kind = def->kind;
continue; // applies to for loop detailed_name = def->detailed_name;
kind = type.def->kind; }
detailed_name = type.def->detailed_name;
break; break;
} }
default: default:

View File

@ -56,17 +56,19 @@ BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
std::vector<Out_CqueryMemberHierarchy::Entry> std::vector<Out_CqueryMemberHierarchy::Entry>
ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) { ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
QueryType& root_type = db->types[root.id]; QueryType& root_type = db->types[root.id];
if (!root_type.def) const QueryType::Def* def = root_type.AnyDef();
if (!def)
return {}; return {};
std::vector<Out_CqueryMemberHierarchy::Entry> ret; std::vector<Out_CqueryMemberHierarchy::Entry> ret;
EachWithGen(db->vars, root_type.def->vars, [&](QueryVar& var) { EachWithGen(db->vars, def->vars, [&](QueryVar& var) {
const QueryVar::Def* def1 = var.AnyDef();
Out_CqueryMemberHierarchy::Entry entry; Out_CqueryMemberHierarchy::Entry entry;
entry.name = var.def->ShortName(); entry.name = def1->ShortName();
entry.type_id = var.def->type ? *var.def->type : QueryTypeId(); entry.type_id = def1->type ? *def1->type : QueryTypeId();
if (var.def->spell) { if (def->spell) {
optional<lsLocation> loc = optional<lsLocation> loc =
GetLsLocation(db, working_files, *var.def->spell); GetLsLocation(db, working_files, *def1->spell);
// TODO invalid location // TODO invalid location
if (loc) if (loc)
entry.location = *loc; entry.location = *loc;
@ -96,9 +98,9 @@ struct CqueryMemberHierarchyInitialHandler
break; break;
} }
if (sym.kind == SymbolKind::Var) { if (sym.kind == SymbolKind::Var) {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (var.def && var.def->type) if (def && def->type)
out.result = BuildInitial(db, working_files, *var.def->type); out.result = BuildInitial(db, working_files, *def->type);
break; break;
} }
} }

View File

@ -55,7 +55,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
sym2id[syms.back()] = n++; sym2id[syms.back()] = n++;
} }
for (RawId i = 0; i < db->vars.size(); i++) for (RawId i = 0; i < db->vars.size(); i++)
if (db->vars[i].def) { if (db->vars[i].AnyDef()) {
syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Var}); syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Var});
sym2id[syms.back()] = n++; sym2id[syms.back()] = n++;
} }
@ -70,14 +70,14 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
}; };
n = 0; n = 0;
for (QueryFunc& func : db->funcs) for (QueryFunc& func : db->funcs)
if (func.def) { if (func.AnyDef()) {
add(func.declarations, kDeclWeight); add(func.declarations, kDeclWeight);
add(func.uses, 1); add(func.uses, 1);
Add(sym2id, adj, func.derived, n); Add(sym2id, adj, func.derived, n);
n++; n++;
} }
for (QueryType& type : db->types) for (QueryType& type : db->types)
if (type.def) { if (type.AnyDef()) {
add(type.uses, 1); add(type.uses, 1);
Add(sym2id, adj, type.instances, n); Add(sym2id, adj, type.instances, n);
Add(sym2id, adj, type.def->funcs, n); Add(sym2id, adj, type.def->funcs, n);
@ -86,7 +86,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
n++; n++;
} }
for (QueryVar& var : db->vars) for (QueryVar& var : db->vars)
if (var.def) { if (var.AnyDef()) {
add(var.declarations, kDeclWeight); add(var.declarations, kDeclWeight);
add(var.uses, 1); add(var.uses, 1);
n++; n++;

View File

@ -30,10 +30,10 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
default: default:
break; break;
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (!var.def || !var.def->type) if (!def || !def->type)
continue; continue;
id = *var.def->type; id = *def->type;
} }
// fallthrough // fallthrough
case SymbolKind::Type: { case SymbolKind::Type: {

View File

@ -80,11 +80,11 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
// Note: we ignore the definition if it is in the same file (ie, // Note: we ignore the definition if it is in the same file (ie,
// possibly a header). // possibly a header).
if (var.def && var.def->extent) { if (def && def->extent) {
QueryFileId t = var.def->extent->file; QueryFileId t = def->extent->file;
if (t != file_id) if (t != file_id)
return t; return t;
} }

View File

@ -247,16 +247,14 @@ struct TextDocumentCodeLensHandler
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); QueryVar& var = db->GetVar(sym);
if (!var.def) const QueryVar::Def* def = var.AnyDef();
continue; if (!def || (def->is_local() && !config->codeLensOnLocalVariables))
if (var.def->is_local() && !config->codeLensOnLocalVariables)
continue; continue;
bool force_display = true; bool force_display = true;
// Do not show 0 refs on macro with no uses, as it is most likely // Do not show 0 refs on macro with no uses, as it is most likely
// a header guard. // a header guard.
if (var.def->is_macro()) if (def->is_macro())
force_display = false; force_display = false;
AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0), AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0),

View File

@ -37,10 +37,10 @@ std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
case SymbolKind::Var: { case SymbolKind::Var: {
std::vector<Use> ret = std::vector<Use> ret =
GetDeclarationsOfSymbolForGotoDefinition(db, sym); GetDeclarationsOfSymbolForGotoDefinition(db, sym);
QueryVar& var = db->GetVar(sym); QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (var.def && var.def->type) { if (def && def->type) {
std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition( std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
db, SymbolIdx{*var.def->type, SymbolKind::Type}); db, SymbolIdx{*def->type, SymbolKind::Type});
ret.insert(ret.end(), types.begin(), types.end()); ret.insert(ret.end(), types.begin(), types.end());
} }
return ret; return ret;

View File

@ -9,30 +9,27 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
SymbolRef sym) { SymbolRef sym) {
switch (sym.kind) { switch (sym.kind) {
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(sym); if (const auto* def = db->GetType(sym).AnyDef()) {
if (type.def) return {def->comments, !def->hover.empty()
return {type.def->comments, ? std::string_view(def->hover)
!type.def->hover.empty() : std::string_view(def->detailed_name)};
? std::string_view(type.def->hover) }
: std::string_view(type.def->detailed_name)};
break; break;
} }
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym); if (const auto* def = db->GetFunc(sym).AnyDef()) {
if (func.def) return {def->comments, !def->hover.empty()
return {func.def->comments, ? std::string_view(def->hover)
!func.def->hover.empty() : std::string_view(def->detailed_name)};
? std::string_view(func.def->hover) }
: std::string_view(func.def->detailed_name)};
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); if (const auto* def = db->GetVar(sym).AnyDef()) {
if (var.def) return {def->comments, !def->hover.empty()
return {var.def->comments, ? std::string_view(def->hover)
!var.def->hover.empty() : std::string_view(def->detailed_name)};
? std::string_view(var.def->hover) }
: std::string_view(var.def->detailed_name)};
break; break;
} }
case SymbolKind::File: case SymbolKind::File:

View File

@ -772,8 +772,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
QueryVar& var = vars[usr_to_var[usr].id]; QueryVar& var = vars[usr_to_var[usr].id];
if (var.symbol_idx) if (var.symbol_idx)
symbols[var.symbol_idx->id].kind = SymbolKind::Invalid; symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
//var.def = QueryVar::Def(); var.def.clear();
var.def = nullopt;
} }
break; break;
} }
@ -895,10 +894,10 @@ void QueryDatabase::ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates) {
QueryVar& existing = vars[it->second.id]; QueryVar& existing = vars[it->second.id];
// Keep the existing definition if it is higher quality. // Keep the existing definition if it is higher quality.
if (!(existing.def && existing.def->spell && if (!(existing.AnyDef() && existing.AnyDef()->spell &&
!def.value.spell)) { !def.value.spell)) {
existing.def = std::move(def.value); existing.def.push_front(std::move(def.value));
if (!def.value.is_local()) if (!existing.def.front().is_local())
UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second); UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second);
} }
} }
@ -924,19 +923,19 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
return files[idx].def->path; return files[idx].def->path;
break; break;
case SymbolKind::Func: case SymbolKind::Func:
if (funcs[idx].def) { if (const auto* def = funcs[idx].AnyDef()) {
auto& def = funcs[idx].def; // Assume the part after short_name is not needed.
return std::string_view(def->detailed_name) return std::string_view(def->detailed_name)
.substr(0, def->short_name_offset + def->short_name_size); .substr(0, def->short_name_offset + def->short_name_size);
} }
break; break;
case SymbolKind::Type: case SymbolKind::Type:
if (types[idx].def) if (const auto* def = types[idx].AnyDef())
return types[idx].def->detailed_name; return def->detailed_name;
break; break;
case SymbolKind::Var: case SymbolKind::Var:
if (vars[idx].def) if (const auto* def = vars[idx].AnyDef())
return vars[idx].def->detailed_name; return def->detailed_name;
break; break;
} }
return ""; return "";
@ -952,16 +951,16 @@ std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const {
return files[idx].def->path; return files[idx].def->path;
break; break;
case SymbolKind::Func: case SymbolKind::Func:
if (funcs[idx].def) if (const auto* def = funcs[idx].AnyDef())
return funcs[idx].def->ShortName(); return def->ShortName();
break; break;
case SymbolKind::Type: case SymbolKind::Type:
if (types[idx].def) if (const auto* def = types[idx].AnyDef())
return types[idx].def->ShortName(); return def->ShortName();
break; break;
case SymbolKind::Var: case SymbolKind::Var:
if (vars[idx].def) if (const auto* def = vars[idx].AnyDef())
return vars[idx].def->ShortName(); return def->ShortName();
break; break;
} }
return ""; return "";

View File

@ -5,6 +5,7 @@
#include <sparsepp/spp.h> #include <sparsepp/spp.h>
#include <forward_list>
#include <functional> #include <functional>
struct QueryFile; struct QueryFile;
@ -145,6 +146,8 @@ struct QueryType {
std::vector<Use> uses; std::vector<Use> uses;
explicit QueryType(const Usr& usr) : usr(usr) {} explicit QueryType(const Usr& usr) : usr(usr) {}
const Def* AnyDef() const { return def ? &*def : nullptr; }
Def* AnyDef() { return def ? &*def : nullptr; }
}; };
struct QueryFunc { struct QueryFunc {
@ -162,6 +165,8 @@ struct QueryFunc {
std::vector<Use> uses; std::vector<Use> uses;
explicit QueryFunc(const Usr& usr) : usr(usr) {} explicit QueryFunc(const Usr& usr) : usr(usr) {}
const Def* AnyDef() const { return def ? &*def : nullptr; }
Def* AnyDef() { return def ? &*def : nullptr; }
}; };
struct QueryVar { struct QueryVar {
@ -172,11 +177,19 @@ struct QueryVar {
Usr usr; Usr usr;
Maybe<Id<void>> symbol_idx; Maybe<Id<void>> symbol_idx;
optional<Def> def; std::forward_list<Def> def;
std::vector<Use> declarations; std::vector<Use> declarations;
std::vector<Use> uses; std::vector<Use> uses;
explicit QueryVar(const Usr& usr) : usr(usr) {} explicit QueryVar(const Usr& usr) : usr(usr) {}
const Def* AnyDef() const {
if (def.empty()) return nullptr;
return &def.front();
}
Def* AnyDef() {
if (def.empty()) return nullptr;
return &def.front();
}
}; };
struct IndexUpdate { struct IndexUpdate {
@ -297,21 +310,21 @@ struct QueryDatabase {
case SymbolKind::File: case SymbolKind::File:
return QueryFileId(ref.id); return QueryFileId(ref.id);
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& file = funcs[ref.id.id]; const QueryFunc::Def* def = funcs[ref.id.id].AnyDef();
if (file.def) if (def)
return file.def->file; return def->file;
break; break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = types[ref.id.id]; const QueryType::Def* def = types[ref.id.id].AnyDef();
if (type.def) if (def)
return type.def->file; return def->file;
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = vars[ref.id.id]; const QueryVar::Def* def = vars[ref.id.id].AnyDef();
if (var.def) if (def)
return var.def->file; return def->file;
break; break;
} }
} }

View File

@ -34,9 +34,9 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (var.def) if (def)
return var.def->spell; return def->spell;
break; break;
} }
case SymbolKind::File: case SymbolKind::File:
@ -63,9 +63,9 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (var.def) if (def)
return var.def->extent; return def->extent;
break; break;
} }
case SymbolKind::File: case SymbolKind::File:
@ -97,9 +97,9 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (var.def) if (def)
return var.def->file; return def->file;
break; break;
} }
case SymbolKind::File: case SymbolKind::File:
@ -143,8 +143,9 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
ret.reserve(ids.size()); ret.reserve(ids.size());
for (auto id : ids) { for (auto id : ids) {
QueryVar& var = db->vars[id.id]; QueryVar& var = db->vars[id.id];
if (var.def && var.def->spell) QueryVar::Def* def = var.AnyDef();
ret.push_back(*var.def->spell); if (def && def->spell)
ret.push_back(*def->spell);
else if (var.declarations.size()) else if (var.declarations.size())
ret.push_back(var.declarations[0]); ret.push_back(var.declarations[0]);
} }
@ -158,16 +159,20 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(sym); QueryType& type = db->GetType(sym);
std::vector<Use> ret = type.uses; std::vector<Use> ret = type.uses;
if (include_decl && type.def && type.def->spell) if (include_decl) {
ret.push_back(*type.def->spell); const QueryType::Def* def = type.AnyDef();
if (def && def->spell)
ret.push_back(*def->spell);
}
return ret; return ret;
} }
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(sym); QueryFunc& func = db->GetFunc(sym);
std::vector<Use> ret = func.uses; std::vector<Use> ret = func.uses;
if (include_decl) { if (include_decl) {
if (func.def && func.def->spell) const QueryFunc::Def* def = func.AnyDef();
ret.push_back(*func.def->spell); if (def && def->spell)
ret.push_back(*def->spell);
AddRange(&ret, func.declarations); AddRange(&ret, func.declarations);
} }
return ret; return ret;
@ -176,8 +181,9 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
QueryVar& var = db->GetVar(sym); QueryVar& var = db->GetVar(sym);
std::vector<Use> ret = var.uses; std::vector<Use> ret = var.uses;
if (include_decl) { if (include_decl) {
if (var.def && var.def->spell) const QueryVar::Def* def = var.AnyDef();
ret.push_back(*var.def->spell); if (def && def->spell)
ret.push_back(*def->spell);
ret.insert(ret.end(), var.declarations.begin(), var.declarations.end()); ret.insert(ret.end(), var.declarations.begin(), var.declarations.end());
} }
return ret; return ret;
@ -393,21 +399,21 @@ optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
default: default:
break; break;
case SymbolKind::Func: { case SymbolKind::Func: {
QueryFunc& func = db->GetFunc(use); const QueryFunc::Def* def = db->GetFunc(use).AnyDef();
if (func.def) if (def)
ret.containerName = std::string_view(func.def->detailed_name); ret.containerName = std::string_view(def->detailed_name);
break; break;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
QueryType& type = db->GetType(use); const QueryType::Def* def = db->GetType(use).AnyDef();
if (type.def) if (def)
ret.containerName = std::string_view(type.def->detailed_name); ret.containerName = std::string_view(def->detailed_name);
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(use); const QueryVar::Def* def = db->GetVar(use).AnyDef();
if (var.def) if (def)
ret.containerName = std::string_view(var.def->detailed_name); ret.containerName = std::string_view(def->detailed_name);
break; break;
} }
} }
@ -492,17 +498,17 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
return info; return info;
} }
case SymbolKind::Var: { case SymbolKind::Var: {
QueryVar& var = db->GetVar(sym); const QueryVar::Def* def = db->GetVar(sym).AnyDef();
if (!var.def) if (!def)
break; break;
lsSymbolInformation info; lsSymbolInformation info;
if (use_short_name) if (use_short_name)
info.name = var.def->ShortName(); info.name = def->ShortName();
else else
info.name = var.def->detailed_name; info.name = def->detailed_name;
info.containerName = var.def->detailed_name; info.containerName = def->detailed_name;
switch (var.def->kind) { switch (def->kind) {
default: default:
info.kind = lsSymbolKind::Variable; info.kind = lsSymbolKind::Variable;
break; break;

View File

@ -69,15 +69,15 @@ void EachWithGen(std::vector<Q>& collection, Id<Q> x, Fn fn) {
Q& obj = collection[x.id]; Q& obj = collection[x.id];
// FIXME Deprecate optional<Def> def // FIXME Deprecate optional<Def> def
// if (obj.gen == x.gen && obj.def) // if (obj.gen == x.gen && obj.def)
if (obj.def) if (obj.AnyDef())
fn(obj); fn(obj);
} }
template <typename Q, typename Fn> template <typename Q, typename Fn>
void EachWithGen(std::vector<Q>& collection, std::vector<Id<Q>>& ids, Fn fn) { void EachWithGen(std::vector<Q>& collection, const std::vector<Id<Q>>& ids, Fn fn) {
for (Id<Q> x : ids) { for (Id<Q> x : ids) {
Q& obj = collection[x.id]; Q& obj = collection[x.id];
if (obj.def) // FIXME Deprecate optional<Def> def if (obj.AnyDef())
fn(obj); fn(obj);
} }
} }