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);
AddFuncRef(&caller->def.callees,
IndexFuncRef{loc, called->id, role});
AddFuncRef(&called->callers, IndexFuncRef{loc, caller->id, role});
IndexFuncRef(loc, Id<void>(called->id), SymbolKind::Func, role));
AddFuncRef(&called->callers,
IndexFuncRef(loc, Id<void>(caller->id), SymbolKind::Func, role));
} 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) {
IndexFunc* ctor = db->Resolve(db->ToFuncId(*ctor_usr));
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);
const char* loc_string = strchr(str_value, '@') + 1;
value.id = IndexFuncId(id);
value.loc = Range(loc_string);
value.lex_parent_id = Id<void>(id);
value.range = Range(loc_string);
} else {
Reflect(visitor, value.loc);
Reflect(visitor, value.id);
Reflect(visitor, value.role);
Reflect(visitor, static_cast<Reference&>(value));
}
}
void Reflect(Writer& visitor, IndexFuncRef& value) {
@ -2353,17 +2354,15 @@ void Reflect(Writer& visitor, IndexFuncRef& value) {
s += "~";
// id.id is unsigned, special case -1 value
if (value.id.HasValue())
s += std::to_string(value.id.id);
if (value.lex_parent_id.HasValue())
s += std::to_string(value.lex_parent_id.id);
else
s += "-1";
s += "@" + value.loc.ToString();
s += "@" + value.range.ToString();
visitor.String(s.c_str());
} else {
Reflect(visitor, value.loc);
Reflect(visitor, value.id);
Reflect(visitor, value.role);
Reflect(visitor, static_cast<Reference&>(value));
}
}

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.
Range loc;
IndexFuncId id;
SymbolRole 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();
}
// NOTE: id can be -1 if the function call is not coming from a function.
struct IndexFuncRef : Reference {
// Constructors are unnecessary in C++17 p0017
IndexFuncRef() = default;
IndexFuncRef(Range range, Id<void> id, SymbolKind kind, SymbolRole role)
: Reference{range, id, kind, role} {}
};
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.
// textDocument/definition on the space/semicolon in `A a;` or `return
// 42;` will take you to the constructor.
Range range = caller.loc;
Range range = caller.range;
if (caller.role & SymbolRole::Implicit) {
if (range.start.column > 0)
range.start.column--;
@ -451,7 +451,10 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
return QueryVarId(cached_var_ids_.find(id)->second);
}
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 {
// TODO: expose more than just QueryLocation.
@ -1028,8 +1031,8 @@ TEST_SUITE("query") {
previous.Resolve(previous.ToTypeId(HashUsr("usr1")))
->uses.push_back(Reference{Range(Position(1, 0))});
previous.Resolve(previous.ToFuncId(HashUsr("usr2")))
->callers.push_back(IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0),
SymbolRole::None});
->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
previous.Resolve(previous.ToVarId(HashUsr("usr3")))
->uses.push_back(Reference{Range(Position(3, 0))});
@ -1047,10 +1050,10 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->callers.push_back(
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None});
cf->callers.push_back(
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None});
pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
cf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
IndexUpdate update = GetDelta(previous, current);
@ -1092,14 +1095,14 @@ TEST_SUITE("query") {
IndexFunc* pf = previous.Resolve(previous.ToFuncId(HashUsr("usr")));
IndexFunc* cf = current.Resolve(current.ToFuncId(HashUsr("usr")));
pf->callers.push_back(
IndexFuncRef{Range(Position(1, 0)), IndexFuncId(0), SymbolRole::None});
pf->callers.push_back(
IndexFuncRef{Range(Position(2, 0)), IndexFuncId(0), SymbolRole::None});
cf->callers.push_back(
IndexFuncRef{Range(Position(4, 0)), IndexFuncId(0), SymbolRole::None});
cf->callers.push_back(
IndexFuncRef{Range(Position(5, 0)), IndexFuncId(0), SymbolRole::None});
pf->callers.push_back(IndexFuncRef(Range(Position(1, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
pf->callers.push_back(IndexFuncRef(Range(Position(2, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
cf->callers.push_back(IndexFuncRef(Range(Position(4, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
cf->callers.push_back(IndexFuncRef(Range(Position(5, 0)), Id<void>(0),
SymbolKind::Func, SymbolRole::None));
QueryDatabase db;
IdMap previous_map(&db, previous.id_cache);