struct QueryFuncRef : Reference {};

This commit is contained in:
Fangrui Song 2018-02-08 23:10:54 -08:00
parent 4bfb5a3586
commit 67e8132dbe
11 changed files with 74 additions and 59 deletions

View File

@ -84,6 +84,7 @@ struct Reference {
SymbolKind lex_parent_kind;
SymbolRole role;
bool HasValue() const { return lex_parent_id.HasValue(); }
std::tuple<Range, Id<void>, SymbolKind, SymbolRole> ToTuple() const {
return std::make_tuple(range, lex_parent_id, lex_parent_kind, role);
}

View File

@ -36,17 +36,15 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
for (const SymbolRef& ref : refs) {
if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx];
if (!type.def)
continue;
std::vector<QueryLocation> locations =
ToQueryLocation(db, type.def->parents);
out.result = GetLsLocations(db, working_files, locations);
if (type.def)
out.result = GetLsLocations(db, working_files,
ToReference(db, type.def->parents));
break;
} else if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
std::vector<QueryLocation> locations =
ToQueryLocation(db, func.def->base);
out.result = GetLsLocations(db, working_files, locations);
if (func.def)
out.result =
GetLsLocations(db, working_files, ToReference(db, func.def->base));
break;
}
}

View File

@ -84,7 +84,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
auto handle_caller = [&](QueryFuncRef caller,
Out_CqueryCallTree::CallType call_type) {
optional<lsLocation> call_location =
GetLsLocation(db, working_files, caller.loc);
GetLsLocation(db, working_files, caller);
if (!call_location)
return;
@ -107,7 +107,10 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
//}
if (caller.HasValue()) {
QueryFunc& call_func = db->funcs[caller.id_.id];
QueryFuncId func_id = caller.FuncId();
if (!func_id.HasValue())
return;
QueryFunc& call_func = db->funcs[func_id.id];
if (!call_func.def)
return;
@ -142,7 +145,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
for (QueryFuncRef caller : base_callers) {
// Do not show calls to the base function coming from this function.
if (caller.id_ == root)
if (caller.FuncId() == root)
continue;
handle_caller(caller, Out_CqueryCallTree::CallType::Base);

View File

@ -27,14 +27,12 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
std::vector<QueryLocation> locations =
ToQueryLocation(db, func.callers);
std::vector<Reference> uses = ToReference(db, func.callers);
for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func))
locations.push_back(func_ref.loc);
uses.push_back(func_ref);
for (QueryFuncRef func_ref : GetCallersForAllDerivedFunctions(db, func))
locations.push_back(func_ref.loc);
out.result = GetLsLocations(db, working_files, locations);
uses.push_back(func_ref);
out.result = GetLsLocations(db, working_files, uses);
}
}
QueueManager::WriteStdout(IpcId::CqueryCallers, out);

View File

@ -36,15 +36,13 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
for (const SymbolRef& ref : refs) {
if (ref.idx.kind == SymbolKind::Type) {
QueryType& type = db->types[ref.idx.idx];
std::vector<QueryLocation> locations =
ToQueryLocation(db, type.derived);
out.result = GetLsLocations(db, working_files, locations);
out.result =
GetLsLocations(db, working_files, ToReference(db, type.derived));
break;
} else if (ref.idx.kind == SymbolKind::Func) {
QueryFunc& func = db->funcs[ref.idx.idx];
std::vector<QueryLocation> locations =
ToQueryLocation(db, func.derived);
out.result = GetLsLocations(db, working_files, locations);
out.result =
GetLsLocations(db, working_files, ToReference(db, func.derived));
break;
}
}

View File

@ -38,9 +38,8 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
// fallthrough
case SymbolKind::Type: {
QueryType& type = db->types[id];
std::vector<QueryLocation> locations =
ToQueryLocation(db, type.instances);
out.result = GetLsLocations(db, working_files, locations);
out.result = GetLsLocations(db, working_files,
ToReference(db, type.instances));
break;
}
}

View File

@ -451,10 +451,21 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
return QueryVarId(cached_var_ids_.find(id)->second);
}
QueryFuncRef IdMap::ToQuery(IndexFuncRef ref) const {
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)};
QueryFuncRef ret(ref.range, ref.lex_parent_id, ref.lex_parent_kind, ref.role);
switch (ref.lex_parent_kind) {
default:
break;
case SymbolKind::File:
ret.lex_parent_id = Id<void>(primary_file);
break;
case SymbolKind::Func:
ret.lex_parent_id = Id<void>(ToQuery(IndexFuncId(ref.lex_parent_id)));
break;
case SymbolKind::Type:
ret.lex_parent_id = Id<void>(ToQuery(IndexTypeId(ref.lex_parent_id)));
break;
}
return ret;
}
Reference IdMap::ToQuery(IndexFunc::Declaration decl) const {
// TODO: expose more than just QueryLocation.
@ -1061,10 +1072,10 @@ TEST_SUITE("query") {
REQUIRE(update.funcs_callers.size() == 1);
REQUIRE(update.funcs_callers[0].id == QueryFuncId(0));
REQUIRE(update.funcs_callers[0].to_remove.size() == 1);
REQUIRE(update.funcs_callers[0].to_remove[0].loc.range ==
REQUIRE(update.funcs_callers[0].to_remove[0].range ==
Range(Position(1, 0)));
REQUIRE(update.funcs_callers[0].to_add.size() == 1);
REQUIRE(update.funcs_callers[0].to_add[0].loc.range ==
REQUIRE(update.funcs_callers[0].to_add[0].range ==
Range(Position(2, 0)));
}
@ -1116,12 +1127,12 @@ TEST_SUITE("query") {
db.ApplyIndexUpdate(&import_update);
REQUIRE(db.funcs[0].callers.size() == 2);
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(1, 0)));
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(2, 0)));
REQUIRE(db.funcs[0].callers[0].range == Range(Position(1, 0)));
REQUIRE(db.funcs[0].callers[1].range == Range(Position(2, 0)));
db.ApplyIndexUpdate(&delta_update);
REQUIRE(db.funcs[0].callers.size() == 2);
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(4, 0)));
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(5, 0)));
REQUIRE(db.funcs[0].callers[0].range == Range(Position(4, 0)));
REQUIRE(db.funcs[0].callers[1].range == Range(Position(5, 0)));
}
}

View File

@ -101,25 +101,17 @@ struct SymbolRef {
};
MAKE_REFLECT_STRUCT(SymbolRef, idx, loc);
struct QueryFuncRef {
// NOTE: id_ can be -1 if the function call is not coming from a function.
QueryFuncId id_;
QueryLocation loc;
struct QueryFuncRef : Reference {
QueryFuncRef() = default;
QueryFuncRef(Range range, Id<void> id, SymbolKind kind, SymbolRole role)
: Reference{range, id, kind, role} {}
bool HasValue() const { return id_.HasValue(); }
std::tuple<QueryFuncId, QueryLocation> ToTuple() const {
return std::make_tuple(id_, loc);
}
bool operator==(const QueryFuncRef& o) const {
return ToTuple() == o.ToTuple();
}
bool operator!=(const QueryFuncRef& o) const { return !(*this == o); }
bool operator<(const QueryFuncRef& o) const {
return ToTuple() < o.ToTuple();
QueryFuncId FuncId() const {
if (lex_parent_kind == SymbolKind::Func)
return QueryFuncId(lex_parent_id);
return QueryFuncId();
}
};
MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc);
// There are two sources of reindex updates: the (single) definition of a
// symbol has changed, or one of many users of the symbol has changed.

View File

@ -188,8 +188,7 @@ std::vector<Reference> ToReference(QueryDatabase* db,
std::vector<Reference> ret;
ret.reserve(refs.size());
for (auto& ref : refs)
ret.push_back(Reference{ref.loc.range, Id<void>(ref.id_), SymbolKind::Func,
ref.loc.role});
ret.push_back(ref);
return ret;
}
@ -199,7 +198,7 @@ std::vector<QueryLocation> ToQueryLocation(
std::vector<QueryLocation> locs;
locs.reserve(refs.size());
for (const QueryFuncRef& ref : refs)
locs.push_back(ref.loc);
locs.push_back(QueryLocation{ref.range, GetFileId(db, ref), ref.role});
return locs;
}
std::vector<QueryLocation> ToQueryLocation(
@ -450,11 +449,11 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
std::vector<lsLocation> GetLsLocations(
QueryDatabase* db,
WorkingFiles* working_files,
const std::vector<QueryLocation>& locations) {
const std::vector<Reference>& refs) {
std::unordered_set<lsLocation> unique_locations;
for (const QueryLocation& query_location : locations) {
for (Reference ref : refs) {
optional<lsLocation> location =
GetLsLocation(db, working_files, query_location);
GetLsLocation(db, working_files, ref);
if (!location)
continue;
unique_locations.insert(*location);

View File

@ -25,6 +25,20 @@ QueryFileId GetFileId(QueryDatabase* db, Reference ref);
std::vector<Reference> ToReference(QueryDatabase* db,
const std::vector<QueryFuncRef>& refs);
template <typename Q>
std::vector<Reference> ToReference(QueryDatabase* db,
const std::vector<Id<Q>>& ids) {
std::vector<Reference> ret;
ret.reserve(ids.size());
for (auto id : ids) {
optional<QueryLocation> loc = GetDefinitionSpellingOfSymbol(db, id);
if (loc)
ret.push_back(*loc);
}
return ret;
}
std::vector<QueryLocation> ToQueryLocation(
QueryDatabase* db,
const std::vector<QueryFuncRef>& refs);
@ -62,7 +76,7 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
std::vector<lsLocation> GetLsLocations(
QueryDatabase* db,
WorkingFiles* working_files,
const std::vector<QueryLocation>& locations);
const std::vector<Reference>& refs);
// Returns a symbol. The symbol will have *NOT* have a location assigned.
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
WorkingFiles* working_files,

View File

@ -166,6 +166,8 @@ def configure(ctx):
cxxflags = ctx.env.CXXFLAGS
else:
cxxflags = ['-g', '-Wall', '-Wno-sign-compare', '-Werror']
if 'g++' in ctx.env.CXX_NAME:
cxxflags.append('-Wno-return-type')
if all(not x.startswith('-std=') for x in ctx.env.CXXFLAGS):
cxxflags.append('-std=c++11')