struct IndexFuncRef : Reference {};

This commit is contained in:
Fangrui Song 2018-02-08 22:06:09 -08:00
parent 82b429bfbc
commit 4bfb5a3586
3 changed files with 39 additions and 45 deletions

View File

@ -592,10 +592,12 @@ void OnIndexReference_Function(IndexFile* db,
called = db->Resolve(called_id); called = db->Resolve(called_id);
AddFuncRef(&caller->def.callees, AddFuncRef(&caller->def.callees,
IndexFuncRef{loc, called->id, role}); IndexFuncRef(loc, Id<void>(called->id), SymbolKind::Func, role));
AddFuncRef(&called->callers, IndexFuncRef{loc, caller->id, role}); AddFuncRef(&called->callers,
IndexFuncRef(loc, Id<void>(caller->id), SymbolKind::Func, role));
} else { } else {
AddFuncRef(&called->callers, IndexFuncRef{loc, IndexFuncId(), role}); AddFuncRef(&called->callers,
IndexFuncRef(loc, Id<void>(), SymbolKind::Invalid, role));
} }
} }
@ -2049,7 +2051,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
if (ctor_usr) { if (ctor_usr) {
IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr)); IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr));
AddFuncRef(&ctor->callers, AddFuncRef(&ctor->callers,
IndexFuncRef{loc, IndexFuncId(), SymbolRole::Implicit}); IndexFuncRef(loc, Id<void>(), SymbolKind::Invalid,
SymbolRole::Implicit));
} }
} }
} }
@ -2338,12 +2341,10 @@ void Reflect(Reader& visitor, IndexFuncRef& value) {
RawId id = atol(str_value); RawId id = atol(str_value);
const char* loc_string = strchr(str_value, '@') + 1; const char* loc_string = strchr(str_value, '@') + 1;
value.id = IndexFuncId(id); value.lex_parent_id = Id<void>(id);
value.loc = Range(loc_string); value.range = Range(loc_string);
} else { } else {
Reflect(visitor, value.loc); Reflect(visitor, static_cast<Reference&>(value));
Reflect(visitor, value.id);
Reflect(visitor, value.role);
} }
} }
void Reflect(Writer& visitor, IndexFuncRef& value) { void Reflect(Writer& visitor, IndexFuncRef& value) {
@ -2353,17 +2354,15 @@ void Reflect(Writer& visitor, IndexFuncRef& value) {
s += "~"; s += "~";
// id.id is unsigned, special case -1 value // id.id is unsigned, special case -1 value
if (value.id.HasValue()) if (value.lex_parent_id.HasValue())
s += std::to_string(value.id.id); s += std::to_string(value.lex_parent_id.id);
else else
s += "-1"; s += "-1";
s += "@" + value.loc.ToString(); s += "@" + value.range.ToString();
visitor.String(s.c_str()); visitor.String(s.c_str());
} else { } else {
Reflect(visitor, value.loc); Reflect(visitor, static_cast<Reference&>(value));
Reflect(visitor, value.id);
Reflect(visitor, value.role);
} }
} }

View File

@ -95,20 +95,12 @@ struct Reference {
} }
}; };
struct IndexFuncRef { // NOTE: id can be -1 if the function call is not coming from a function.
// NOTE: id can be -1 if the function call is not coming from a function. struct IndexFuncRef : Reference {
Range loc; // Constructors are unnecessary in C++17 p0017
IndexFuncId id; IndexFuncRef() = default;
SymbolRole role; IndexFuncRef(Range range, Id<void> id, SymbolKind kind, SymbolRole role)
: Reference{range, id, kind, role} {}
std::tuple<IndexFuncId, Range, SymbolRole> ToTuple() const {
return std::make_tuple(id, loc, role);
}
bool operator==(const IndexFuncRef& o) { return ToTuple() == o.ToTuple(); }
bool operator!=(const IndexFuncRef& o) { return !(*this == o); }
bool operator<(const IndexFuncRef& o) const {
return ToTuple() < o.ToTuple();
}
}; };
void Reflect(Reader& visitor, IndexFuncRef& value); void Reflect(Reader& visitor, IndexFuncRef& value);

View File

@ -273,7 +273,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
// to the left/right). This is hacky but useful. e.g. // to the left/right). This is hacky but useful. e.g.
// textDocument/definition on the space/semicolon in `A a;` or `return // textDocument/definition on the space/semicolon in `A a;` or `return
// 42;` will take you to the constructor. // 42;` will take you to the constructor.
Range range = caller.loc; Range range = caller.range;
if (caller.role & SymbolRole::Implicit) { if (caller.role & SymbolRole::Implicit) {
if (range.start.column > 0) if (range.start.column > 0)
range.start.column--; range.start.column--;
@ -451,7 +451,10 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
return QueryVarId(cached_var_ids_.find(id)->second); return QueryVarId(cached_var_ids_.find(id)->second);
} }
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const { QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
return QueryFuncRef{ToQuery(ref.id), ToQuery(ref.loc, ref.role)}; if (ref.lex_parent_kind == SymbolKind::Func)
return QueryFuncRef{ToQuery(IndexFuncId(ref.lex_parent_id)),
ToQuery(ref.range, ref.role)};
return QueryFuncRef{QueryFuncId(), ToQuery(ref.range, ref.role)};
} }
Reference IdMap::ToQuery(IndexFunc::Declaration decl) const { Reference IdMap::ToQuery(IndexFunc::Declaration decl) const {
// TODO: expose more than just QueryLocation. // TODO: expose more than just QueryLocation.
@ -1028,8 +1031,8 @@ TEST_SUITE("query") {
previous.Resolve(previous.ToTypeId(HashUsr("usr1"))) previous.Resolve(previous.ToTypeId(HashUsr("usr1")))
->uses.push_back(Reference{Range(Position(1, 0))}); ->uses.push_back(Reference{Range(Position(1, 0))});
previous.Resolve(previous.ToFuncId(HashUsr("usr2"))) previous.Resolve(previous.ToFuncId(HashUsr("usr2")))
->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), ->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
previous.Resolve(previous.ToVarId(HashUsr("usr3"))) previous.Resolve(previous.ToVarId(HashUsr("usr3")))
->uses.push_back(Reference{Range(Position(3, 0))}); ->uses.push_back(Reference{Range(Position(3, 0))});
@ -1047,10 +1050,10 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->callers.push_back( pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id<void>(0),
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
cf->callers.push_back( cf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
IndexUpdate update = GetDelta(previous, current); IndexUpdate update = GetDelta(previous, current);
@ -1092,14 +1095,14 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr"))); IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr"))); IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->callers.push_back( pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id<void>(0),
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
pf->callers.push_back( pf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
cf->callers.push_back( cf->callers.push_back(IndexFuncRef(Range(Position(4, 0)), Id<void>(0),
IndexFuncRef{Range(Position(4, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
cf->callers.push_back( cf->callers.push_back(IndexFuncRef(Range(Position(5, 0)), Id<void>(0),
IndexFuncRef{Range(Position(5, 0)), IndexFuncId(0), SymbolRole::None}); SymbolKind::Func, SymbolRole::None));
QueryDatabase db; QueryDatabase db;
IdMap previous_map(&db, previous.id_cache); IdMap previous_map(&db, previous.id_cache);