Use DeclRef spell to represent Use spell + Use extent

This commit is contained in:
Fangrui Song 2018-10-04 16:59:33 -07:00
parent 08b09bc1da
commit 2864f2c647
10 changed files with 55 additions and 106 deletions

View File

@ -762,12 +762,10 @@ public:
auto do_def_decl = [&](auto *entity) { auto do_def_decl = [&](auto *entity) {
if (is_def) { if (is_def) {
entity->def.spell = {{loc, role}, lid};
SourceRange R = OrigD->getSourceRange(); SourceRange R = OrigD->getSourceRange();
entity->def.extent = { entity->def.spell = {
{R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc, Use{{loc, role}, lid},
Role::None}, R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc};
lid};
entity->def.parent_kind = lsSymbolKind::File; entity->def.parent_kind = lsSymbolKind::File;
GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind); GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind);
} else if (is_decl) { } else if (is_decl) {
@ -862,10 +860,9 @@ public:
IndexType &type1 = db->ToType(usr1); IndexType &type1 = db->ToType(usr1);
SourceLocation L1 = D1->getLocation(); SourceLocation L1 = D1->getLocation();
type1.def.spell = { type1.def.spell = {
{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition}, Use{{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition},
lid}; lid},
type1.def.extent = {{FromTokenRange(SM, Lang, R1), Role::None}, FromTokenRange(SM, Lang, R1)};
lid};
type1.def.detailed_name = Intern(info1->short_name); type1.def.detailed_name = Intern(info1->short_name);
type1.def.short_name_size = int16_t(info1->short_name.size()); type1.def.short_name_size = int16_t(info1->short_name.size());
type1.def.kind = lsSymbolKind::TypeParameter; type1.def.kind = lsSymbolKind::TypeParameter;
@ -887,9 +884,8 @@ public:
SourceLocation L = D->getLocation(); SourceLocation L = D->getLocation();
if (SM.getFileID(L) == LocFID) { if (SM.getFileID(L) == LocFID) {
var->def.spell = { var->def.spell = {
{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid}; Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid},
var->def.extent = { FromTokenRange(SM, Lang, D->getSourceRange())};
{FromTokenRange(SM, Lang, D->getSourceRange()), Role::None}, lid};
var->def.parent_kind = lsSymbolKind::Method; var->def.parent_kind = lsSymbolKind::Method;
} }
} }
@ -1086,19 +1082,15 @@ public:
if (IndexFile *db = param.ConsumeFile(*FE)) { if (IndexFile *db = param.ConsumeFile(*FE)) {
auto [Name, usr] = GetMacro(Tok); auto [Name, usr] = GetMacro(Tok);
IndexVar &var = db->ToVar(usr); IndexVar &var = db->ToVar(usr);
auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID); Range range = FromTokenRange(SM, Lang, {L, L}, &UniqueID);
var.def.kind = lsSymbolKind::Macro; var.def.kind = lsSymbolKind::Macro;
var.def.parent_kind = lsSymbolKind::File; var.def.parent_kind = lsSymbolKind::File;
if (var.def.spell) { if (var.def.spell)
DeclRef &d = var.declarations.emplace_back(); var.declarations.push_back(*var.def.spell);
static_cast<Use&>(d) = *var.def.spell;
d.extent = var.def.spell->range;
}
var.def.spell = Use{{range, Role::Definition}};
const MacroInfo *MI = MD->getMacroInfo(); const MacroInfo *MI = MD->getMacroInfo();
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
range = FromTokenRange(SM, param.Ctx->getLangOpts(), R); Range extent = FromTokenRange(SM, param.Ctx->getLangOpts(), R);
var.def.extent = Use{{range, Role::None}}; var.def.spell = {Use{{range, Role::Definition}}, extent};
if (var.def.detailed_name[0] == '\0') { if (var.def.detailed_name[0] == '\0') {
var.def.detailed_name = Intern(Name); var.def.detailed_name = Intern(Name);
var.def.short_name_size = Name.size(); var.def.short_name_size = Name.size();

View File

@ -106,8 +106,7 @@ struct FuncDef : NameMixin<FuncDef> {
const char *detailed_name = ""; const char *detailed_name = "";
const char *hover = ""; const char *hover = "";
const char *comments = ""; const char *comments = "";
Maybe<Use> spell; Maybe<DeclRef> spell;
Maybe<Use> extent;
// Method this method overrides. // Method this method overrides.
std::vector<Usr> bases; std::vector<Usr> bases;
@ -126,8 +125,8 @@ struct FuncDef : NameMixin<FuncDef> {
std::vector<Usr> GetBases() const { return bases; } std::vector<Usr> GetBases() const { return bases; }
}; };
MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, extent, MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars,
bases, vars, callees, qual_name_offset, short_name_offset, callees, qual_name_offset, short_name_offset,
short_name_size, kind, parent_kind, storage); short_name_size, kind, parent_kind, storage);
struct IndexFunc : NameMixin<IndexFunc> { struct IndexFunc : NameMixin<IndexFunc> {
@ -143,8 +142,7 @@ struct TypeDef : NameMixin<TypeDef> {
const char *detailed_name = ""; const char *detailed_name = "";
const char *hover = ""; const char *hover = "";
const char *comments = ""; const char *comments = "";
Maybe<Use> spell; Maybe<DeclRef> spell;
Maybe<Use> extent;
std::vector<Usr> bases; std::vector<Usr> bases;
// Types, functions, and variables defined in this type. // Types, functions, and variables defined in this type.
@ -164,8 +162,8 @@ struct TypeDef : NameMixin<TypeDef> {
std::vector<Usr> GetBases() const { return bases; } std::vector<Usr> GetBases() const { return bases; }
}; };
MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, extent, MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases,
bases, funcs, types, vars, alias_of, qual_name_offset, funcs, types, vars, alias_of, qual_name_offset,
short_name_offset, short_name_size, kind, parent_kind); short_name_offset, short_name_size, kind, parent_kind);
struct IndexType { struct IndexType {
@ -183,8 +181,7 @@ struct VarDef : NameMixin<VarDef> {
const char *detailed_name = ""; const char *detailed_name = "";
const char *hover = ""; const char *hover = "";
const char *comments = ""; const char *comments = "";
Maybe<Use> spell; Maybe<DeclRef> spell;
Maybe<Use> extent;
// Type of the variable. // Type of the variable.
Usr type = 0; Usr type = 0;
@ -208,7 +205,7 @@ struct VarDef : NameMixin<VarDef> {
std::vector<Usr> GetBases() const { return {}; } std::vector<Usr> GetBases() const { return {}; }
}; };
MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, extent, type, MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type,
qual_name_offset, short_name_offset, short_name_size, kind, qual_name_offset, short_name_offset, short_name_size, kind,
parent_kind, storage); parent_kind, storage);

View File

@ -106,7 +106,7 @@ struct Handler_TextDocumentCodeLens
}; };
auto ToSpell = [&](SymbolRef sym, int file_id) -> Use { auto ToSpell = [&](SymbolRef sym, int file_id) -> Use {
Maybe<Use> def = GetDefinitionSpell(db, sym); Maybe<DeclRef> def = GetDefinitionSpell(db, sym);
if (def && def->file_id == file_id && if (def && def->file_id == file_id &&
def->range.start.line == sym.range.start.line) def->range.start.line == sym.range.start.line)
return *def; return *def;

View File

@ -29,7 +29,7 @@ std::vector<Use> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
if (ret.empty()) { if (ret.empty()) {
for (auto &def : db->GetVar(sym).def) for (auto &def : db->GetVar(sym).def)
if (def.type) { if (def.type) {
if (Maybe<Use> use = GetDefinitionSpell( if (Maybe<DeclRef> use = GetDefinitionSpell(
db, SymbolIdx{def.type, SymbolKind::Type})) { db, SymbolIdx{def.type, SymbolKind::Type})) {
ret.push_back(*use); ret.push_back(*use);
break; break;
@ -135,11 +135,11 @@ struct Handler_TextDocumentDefinition
: short_name; : short_name;
if (short_name != short_query) if (short_name != short_query)
return; return;
if (Maybe<Use> use = GetDefinitionSpell(db, sym)) { if (Maybe<DeclRef> dr = GetDefinitionSpell(db, sym)) {
std::tuple<int, int, bool, int> score{ std::tuple<int, int, bool, int> score{
int(name.size() - short_query.size()), 0, int(name.size() - short_query.size()), 0,
use->file_id != file_id, dr->file_id != file_id,
std::abs(use->range.start.line - position.line)}; std::abs(dr->range.start.line - position.line)};
// Update the score with qualified name if the qualified name // Update the score with qualified name if the qualified name
// occurs in |name|. // occurs in |name|.
auto pos = name.rfind(query); auto pos = name.rfind(query);
@ -162,9 +162,9 @@ struct Handler_TextDocumentDefinition
fn({var.usr, SymbolKind::Var}); fn({var.usr, SymbolKind::Var});
if (best_sym.kind != SymbolKind::Invalid) { if (best_sym.kind != SymbolKind::Invalid) {
Maybe<Use> use = GetDefinitionSpell(db, best_sym); Maybe<DeclRef> dr = GetDefinitionSpell(db, best_sym);
assert(use); assert(dr);
if (auto loc = GetLsLocation(db, working_files, *use)) if (auto loc = GetLsLocation(db, working_files, *dr))
out.result.push_back(*loc); out.result.push_back(*loc);
} }
} }

View File

@ -120,10 +120,10 @@ struct Handler_TextDocumentDocumentSymbol
ds.detail = def->Name(true); ds.detail = def->Name(true);
for (auto &def : entity.def) for (auto &def : entity.def)
if (def.file_id == file_id) { if (def.file_id == file_id) {
if (!def.spell || !def.extent) if (!def.spell)
break; break;
ds.kind = def.kind; ds.kind = def.kind;
if (auto ls_range = GetLsRange(wfile, def.extent->range)) if (auto ls_range = GetLsRange(wfile, def.spell->extent))
ds.range = *ls_range; ds.range = *ls_range;
else else
break; break;

View File

@ -25,8 +25,8 @@ bool AddSymbol(
return false; return false;
Use loc; Use loc;
if (Maybe<Use> location = GetDefinitionExtent(db, sym)) if (Maybe<DeclRef> dr = GetDefinitionSpell(db, sym))
loc = *location; loc = *dr;
else { else {
auto decls = GetNonDefDeclarations(db, sym); auto decls = GetNonDefDeclarations(db, sym);
if (decls.empty()) if (decls.empty())

View File

@ -221,28 +221,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
// References (Use &use) in this function are important to update file_id. // References (Use &use) in this function are important to update file_id.
auto Ref = [&](std::unordered_map<int, int> &lid2fid, Usr usr, auto Ref = [&](std::unordered_map<int, int> &lid2fid, Usr usr,
SymbolKind kind, Use &use, int delta, int k = 1) { SymbolKind kind, Use &use, int delta) {
use.file_id = use.file_id =
use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second;
SymbolRef sym{use.range, usr, kind, use.role}; SymbolRef sym{use.range, usr, kind, use.role};
if (k & 1) { int &v = files[use.file_id].symbol2refcnt[sym];
int &v = files[use.file_id].symbol2refcnt[sym]; v += delta;
v += delta; assert(v >= 0);
assert(v >= 0); if (!v)
if (!v) files[use.file_id].symbol2refcnt.erase(sym);
files[use.file_id].symbol2refcnt.erase(sym);
}
if (k & 2) {
int &v = files[use.file_id].outline2refcnt[sym];
v += delta;
assert(v >= 0);
if (!v)
files[use.file_id].outline2refcnt.erase(sym);
}
}; };
auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr, auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr,
SymbolKind kind, DeclRef &dr, int delta) { SymbolKind kind, DeclRef &dr, int delta) {
Ref(lid2fid, usr, kind, dr, delta, 1); Ref(lid2fid, usr, kind, dr, delta);
files[dr.file_id] files[dr.file_id]
.outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta; .outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta;
}; };
@ -293,12 +284,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
funcs.reserve(t); funcs.reserve(t);
func_usr.reserve(t); func_usr.reserve(t);
} }
for (auto &[usr, def] : u->funcs_removed) { for (auto &[usr, def] : u->funcs_removed)
if (def.spell) if (def.spell)
Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1); RefDecl(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1);
if (def.extent)
Ref(prev_lid2file_id, usr, SymbolKind::Func, *def.extent, -1, 2);
}
RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed); RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed);
Update(lid2file_id, u->file_id, std::move(u->funcs_def_update)); Update(lid2file_id, u->file_id, std::move(u->funcs_def_update));
for (auto &[usr, del_add]: u->funcs_declarations) { for (auto &[usr, del_add]: u->funcs_declarations) {
@ -317,12 +305,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
types.reserve(t); types.reserve(t);
type_usr.reserve(t); type_usr.reserve(t);
} }
for (auto &[usr, def] : u->types_removed) { for (auto &[usr, def] : u->types_removed)
if (def.spell) if (def.spell)
Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1); RefDecl(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1);
if (def.extent)
Ref(prev_lid2file_id, usr, SymbolKind::Type, *def.extent, -1, 2);
}
RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed); RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed);
Update(lid2file_id, u->file_id, std::move(u->types_def_update)); Update(lid2file_id, u->file_id, std::move(u->types_def_update));
for (auto &[usr, del_add]: u->types_declarations) { for (auto &[usr, del_add]: u->types_declarations) {
@ -342,12 +327,9 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
vars.reserve(t); vars.reserve(t);
var_usr.reserve(t); var_usr.reserve(t);
} }
for (auto &[usr, def] : u->vars_removed) { for (auto &[usr, def] : u->vars_removed)
if (def.spell) if (def.spell)
Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1); RefDecl(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1);
if (def.extent)
Ref(prev_lid2file_id, usr, SymbolKind::Var, *def.extent, -1, 2);
}
RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed); RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed);
Update(lid2file_id, u->file_id, std::move(u->vars_def_update)); Update(lid2file_id, u->file_id, std::move(u->vars_def_update));
for (auto &[usr, del_add]: u->vars_declarations) { for (auto &[usr, del_add]: u->vars_declarations) {
@ -388,11 +370,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
AssignFileId(lid2file_id, file_id, *def.spell); AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{ files[def.spell->file_id].symbol2refcnt[{
def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++; def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++;
} files[def.spell->file_id].outline2refcnt[{
if (def.extent) { def.spell->extent, u.first, SymbolKind::Func, def.spell->role}]++;
AssignFileId(lid2file_id, file_id, *def.extent);
files[def.extent->file_id].outline2refcnt[{
def.extent->range, u.first, SymbolKind::Func, def.extent->role}]++;
} }
auto R = func_usr.try_emplace({u.first}, func_usr.size()); auto R = func_usr.try_emplace({u.first}, func_usr.size());
@ -415,11 +394,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
AssignFileId(lid2file_id, file_id, *def.spell); AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{ files[def.spell->file_id].symbol2refcnt[{
def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++; def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++;
} files[def.spell->file_id].outline2refcnt[{
if (def.extent) { def.spell->extent, u.first, SymbolKind::Type, def.spell->role}]++;
AssignFileId(lid2file_id, file_id, *def.extent);
files[def.extent->file_id].outline2refcnt[{
def.extent->range, u.first, SymbolKind::Type, def.extent->role}]++;
} }
auto R = type_usr.try_emplace({u.first}, type_usr.size()); auto R = type_usr.try_emplace({u.first}, type_usr.size());
if (R.second) if (R.second)
@ -441,11 +417,8 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
AssignFileId(lid2file_id, file_id, *def.spell); AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{ files[def.spell->file_id].symbol2refcnt[{
def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++; def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++;
} files[def.spell->file_id].outline2refcnt[{
if (def.extent) { def.spell->extent, u.first, SymbolKind::Var, def.spell->role}]++;
AssignFileId(lid2file_id, file_id, *def.extent);
files[def.extent->file_id].outline2refcnt[{
def.extent->range, u.first, SymbolKind::Var, def.extent->role}]++;
} }
auto R = var_usr.try_emplace({u.first}, var_usr.size()); auto R = var_usr.try_emplace({u.first}, var_usr.size());
if (R.second) if (R.second)

View File

@ -40,21 +40,12 @@ GetDeclarations(llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
} // namespace } // namespace
Maybe<Use> GetDefinitionSpell(DB *db, SymbolIdx sym) { Maybe<DeclRef> GetDefinitionSpell(DB *db, SymbolIdx sym) {
Maybe<Use> ret; Maybe<DeclRef> ret;
EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); }); EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.spell); });
return ret; return ret;
} }
Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym) {
// Used to jump to file.
if (sym.kind == SymbolKind::File)
return Use{{Range{{0, 0}, {0, 0}}, Role::None}, int(sym.usr)};
Maybe<Use> ret;
EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); });
return ret;
}
std::vector<Use> GetFuncDeclarations(DB *db, const std::vector<Usr> &usrs) { std::vector<Use> GetFuncDeclarations(DB *db, const std::vector<Usr> &usrs) {
return GetDeclarations(db->func_usr, db->funcs, usrs); return GetDeclarations(db->func_usr, db->funcs, usrs);
} }

View File

@ -8,8 +8,7 @@
#include <optional> #include <optional>
Maybe<Use> GetDefinitionSpell(DB *db, SymbolIdx sym); Maybe<DeclRef> GetDefinitionSpell(DB *db, SymbolIdx sym);
Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym);
// Get defining declaration (if exists) or an arbitrary declaration (otherwise) // Get defining declaration (if exists) or an arbitrary declaration (otherwise)
// for each id. // for each id.

View File

@ -250,7 +250,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
ReflectShortName(visitor, value.def); ReflectShortName(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", value.def.spell);
REFLECT_MEMBER2("extent", value.def.extent);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("bases", value.def.bases);
REFLECT_MEMBER2("vars", value.def.vars); REFLECT_MEMBER2("vars", value.def.vars);
@ -273,7 +272,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
ReflectShortName(visitor, value.def); ReflectShortName(visitor, value.def);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", value.def.spell);
REFLECT_MEMBER2("extent", value.def.extent);
REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("bases", value.def.bases);
REFLECT_MEMBER2("funcs", value.def.funcs); REFLECT_MEMBER2("funcs", value.def.funcs);
REFLECT_MEMBER2("types", value.def.types); REFLECT_MEMBER2("types", value.def.types);
@ -297,7 +295,6 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) {
ReflectShortName(visitor, value.def); ReflectShortName(visitor, value.def);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", value.def.spell);
REFLECT_MEMBER2("extent", value.def.extent);
REFLECT_MEMBER2("type", value.def.type); REFLECT_MEMBER2("type", value.def.type);
REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("kind", value.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind); REFLECT_MEMBER2("parent_kind", value.def.parent_kind);