mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 03:55:49 +00:00
struct QueryFuncRef : Reference {};
This commit is contained in:
parent
4bfb5a3586
commit
67e8132dbe
@ -84,6 +84,7 @@ struct Reference {
|
|||||||
SymbolKind lex_parent_kind;
|
SymbolKind lex_parent_kind;
|
||||||
SymbolRole role;
|
SymbolRole role;
|
||||||
|
|
||||||
|
bool HasValue() const { return lex_parent_id.HasValue(); }
|
||||||
std::tuple<Range, Id<void>, SymbolKind, SymbolRole> ToTuple() const {
|
std::tuple<Range, Id<void>, SymbolKind, SymbolRole> ToTuple() const {
|
||||||
return std::make_tuple(range, lex_parent_id, lex_parent_kind, role);
|
return std::make_tuple(range, lex_parent_id, lex_parent_kind, role);
|
||||||
}
|
}
|
||||||
|
@ -36,17 +36,15 @@ struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
|||||||
for (const SymbolRef& ref : refs) {
|
for (const SymbolRef& ref : refs) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (ref.idx.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->types[ref.idx.idx];
|
QueryType& type = db->types[ref.idx.idx];
|
||||||
if (!type.def)
|
if (type.def)
|
||||||
continue;
|
out.result = GetLsLocations(db, working_files,
|
||||||
std::vector<QueryLocation> locations =
|
ToReference(db, type.def->parents));
|
||||||
ToQueryLocation(db, type.def->parents);
|
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
|
||||||
break;
|
break;
|
||||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
} else if (ref.idx.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = db->funcs[ref.idx.idx];
|
||||||
std::vector<QueryLocation> locations =
|
if (func.def)
|
||||||
ToQueryLocation(db, func.def->base);
|
out.result =
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
GetLsLocations(db, working_files, ToReference(db, func.def->base));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|||||||
auto handle_caller = [&](QueryFuncRef caller,
|
auto handle_caller = [&](QueryFuncRef caller,
|
||||||
Out_CqueryCallTree::CallType call_type) {
|
Out_CqueryCallTree::CallType call_type) {
|
||||||
optional<lsLocation> call_location =
|
optional<lsLocation> call_location =
|
||||||
GetLsLocation(db, working_files, caller.loc);
|
GetLsLocation(db, working_files, caller);
|
||||||
if (!call_location)
|
if (!call_location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -107,7 +107,10 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
if (caller.HasValue()) {
|
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)
|
if (!call_func.def)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -142,7 +145,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
||||||
for (QueryFuncRef caller : base_callers) {
|
for (QueryFuncRef caller : base_callers) {
|
||||||
// Do not show calls to the base function coming from this function.
|
// Do not show calls to the base function coming from this function.
|
||||||
if (caller.id_ == root)
|
if (caller.FuncId() == root)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
||||||
|
@ -27,14 +27,12 @@ struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
|||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (ref.idx.kind == SymbolKind::Func) {
|
if (ref.idx.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = db->funcs[ref.idx.idx];
|
||||||
std::vector<QueryLocation> locations =
|
std::vector<Reference> uses = ToReference(db, func.callers);
|
||||||
ToQueryLocation(db, func.callers);
|
|
||||||
for (QueryFuncRef func_ref : GetCallersForAllBaseFunctions(db, func))
|
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))
|
for (QueryFuncRef func_ref : GetCallersForAllDerivedFunctions(db, func))
|
||||||
locations.push_back(func_ref.loc);
|
uses.push_back(func_ref);
|
||||||
|
out.result = GetLsLocations(db, working_files, uses);
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QueueManager::WriteStdout(IpcId::CqueryCallers, out);
|
QueueManager::WriteStdout(IpcId::CqueryCallers, out);
|
||||||
|
@ -36,15 +36,13 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
|||||||
for (const SymbolRef& ref : refs) {
|
for (const SymbolRef& ref : refs) {
|
||||||
if (ref.idx.kind == SymbolKind::Type) {
|
if (ref.idx.kind == SymbolKind::Type) {
|
||||||
QueryType& type = db->types[ref.idx.idx];
|
QueryType& type = db->types[ref.idx.idx];
|
||||||
std::vector<QueryLocation> locations =
|
out.result =
|
||||||
ToQueryLocation(db, type.derived);
|
GetLsLocations(db, working_files, ToReference(db, type.derived));
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
|
||||||
break;
|
break;
|
||||||
} else if (ref.idx.kind == SymbolKind::Func) {
|
} else if (ref.idx.kind == SymbolKind::Func) {
|
||||||
QueryFunc& func = db->funcs[ref.idx.idx];
|
QueryFunc& func = db->funcs[ref.idx.idx];
|
||||||
std::vector<QueryLocation> locations =
|
out.result =
|
||||||
ToQueryLocation(db, func.derived);
|
GetLsLocations(db, working_files, ToReference(db, func.derived));
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,8 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
|||||||
// fallthrough
|
// fallthrough
|
||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[id];
|
QueryType& type = db->types[id];
|
||||||
std::vector<QueryLocation> locations =
|
out.result = GetLsLocations(db, working_files,
|
||||||
ToQueryLocation(db, type.instances);
|
ToReference(db, type.instances));
|
||||||
out.result = GetLsLocations(db, working_files, locations);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
src/query.cc
31
src/query.cc
@ -451,10 +451,21 @@ 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 {
|
||||||
if (ref.lex_parent_kind == SymbolKind::Func)
|
QueryFuncRef ret(ref.range, ref.lex_parent_id, ref.lex_parent_kind, ref.role);
|
||||||
return QueryFuncRef{ToQuery(IndexFuncId(ref.lex_parent_id)),
|
switch (ref.lex_parent_kind) {
|
||||||
ToQuery(ref.range, ref.role)};
|
default:
|
||||||
return QueryFuncRef{QueryFuncId(), ToQuery(ref.range, ref.role)};
|
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 {
|
Reference IdMap::ToQuery(IndexFunc::Declaration decl) const {
|
||||||
// TODO: expose more than just QueryLocation.
|
// TODO: expose more than just QueryLocation.
|
||||||
@ -1061,10 +1072,10 @@ TEST_SUITE("query") {
|
|||||||
REQUIRE(update.funcs_callers.size() == 1);
|
REQUIRE(update.funcs_callers.size() == 1);
|
||||||
REQUIRE(update.funcs_callers[0].id == QueryFuncId(0));
|
REQUIRE(update.funcs_callers[0].id == QueryFuncId(0));
|
||||||
REQUIRE(update.funcs_callers[0].to_remove.size() == 1);
|
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)));
|
Range(Position(1, 0)));
|
||||||
REQUIRE(update.funcs_callers[0].to_add.size() == 1);
|
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)));
|
Range(Position(2, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,12 +1127,12 @@ TEST_SUITE("query") {
|
|||||||
|
|
||||||
db.ApplyIndexUpdate(&import_update);
|
db.ApplyIndexUpdate(&import_update);
|
||||||
REQUIRE(db.funcs[0].callers.size() == 2);
|
REQUIRE(db.funcs[0].callers.size() == 2);
|
||||||
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(1, 0)));
|
REQUIRE(db.funcs[0].callers[0].range == Range(Position(1, 0)));
|
||||||
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(2, 0)));
|
REQUIRE(db.funcs[0].callers[1].range == Range(Position(2, 0)));
|
||||||
|
|
||||||
db.ApplyIndexUpdate(&delta_update);
|
db.ApplyIndexUpdate(&delta_update);
|
||||||
REQUIRE(db.funcs[0].callers.size() == 2);
|
REQUIRE(db.funcs[0].callers.size() == 2);
|
||||||
REQUIRE(db.funcs[0].callers[0].loc.range == Range(Position(4, 0)));
|
REQUIRE(db.funcs[0].callers[0].range == Range(Position(4, 0)));
|
||||||
REQUIRE(db.funcs[0].callers[1].loc.range == Range(Position(5, 0)));
|
REQUIRE(db.funcs[0].callers[1].range == Range(Position(5, 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/query.h
24
src/query.h
@ -101,25 +101,17 @@ struct SymbolRef {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(SymbolRef, idx, loc);
|
MAKE_REFLECT_STRUCT(SymbolRef, idx, loc);
|
||||||
|
|
||||||
struct QueryFuncRef {
|
struct QueryFuncRef : Reference {
|
||||||
// NOTE: id_ can be -1 if the function call is not coming from a function.
|
QueryFuncRef() = default;
|
||||||
QueryFuncId id_;
|
QueryFuncRef(Range range, Id<void> id, SymbolKind kind, SymbolRole role)
|
||||||
QueryLocation loc;
|
: Reference{range, id, kind, role} {}
|
||||||
|
|
||||||
bool HasValue() const { return id_.HasValue(); }
|
QueryFuncId FuncId() const {
|
||||||
|
if (lex_parent_kind == SymbolKind::Func)
|
||||||
std::tuple<QueryFuncId, QueryLocation> ToTuple() const {
|
return QueryFuncId(lex_parent_id);
|
||||||
return std::make_tuple(id_, loc);
|
return QueryFuncId();
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc);
|
|
||||||
|
|
||||||
// There are two sources of reindex updates: the (single) definition of a
|
// 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.
|
// symbol has changed, or one of many users of the symbol has changed.
|
||||||
|
@ -188,8 +188,7 @@ std::vector<Reference> ToReference(QueryDatabase* db,
|
|||||||
std::vector<Reference> ret;
|
std::vector<Reference> ret;
|
||||||
ret.reserve(refs.size());
|
ret.reserve(refs.size());
|
||||||
for (auto& ref : refs)
|
for (auto& ref : refs)
|
||||||
ret.push_back(Reference{ref.loc.range, Id<void>(ref.id_), SymbolKind::Func,
|
ret.push_back(ref);
|
||||||
ref.loc.role});
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +198,7 @@ std::vector<QueryLocation> ToQueryLocation(
|
|||||||
std::vector<QueryLocation> locs;
|
std::vector<QueryLocation> locs;
|
||||||
locs.reserve(refs.size());
|
locs.reserve(refs.size());
|
||||||
for (const QueryFuncRef& ref : refs)
|
for (const QueryFuncRef& ref : refs)
|
||||||
locs.push_back(ref.loc);
|
locs.push_back(QueryLocation{ref.range, GetFileId(db, ref), ref.role});
|
||||||
return locs;
|
return locs;
|
||||||
}
|
}
|
||||||
std::vector<QueryLocation> ToQueryLocation(
|
std::vector<QueryLocation> ToQueryLocation(
|
||||||
@ -450,11 +449,11 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
|||||||
std::vector<lsLocation> GetLsLocations(
|
std::vector<lsLocation> GetLsLocations(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const std::vector<QueryLocation>& locations) {
|
const std::vector<Reference>& refs) {
|
||||||
std::unordered_set<lsLocation> unique_locations;
|
std::unordered_set<lsLocation> unique_locations;
|
||||||
for (const QueryLocation& query_location : locations) {
|
for (Reference ref : refs) {
|
||||||
optional<lsLocation> location =
|
optional<lsLocation> location =
|
||||||
GetLsLocation(db, working_files, query_location);
|
GetLsLocation(db, working_files, ref);
|
||||||
if (!location)
|
if (!location)
|
||||||
continue;
|
continue;
|
||||||
unique_locations.insert(*location);
|
unique_locations.insert(*location);
|
||||||
|
@ -25,6 +25,20 @@ QueryFileId GetFileId(QueryDatabase* db, Reference ref);
|
|||||||
|
|
||||||
std::vector<Reference> ToReference(QueryDatabase* db,
|
std::vector<Reference> ToReference(QueryDatabase* db,
|
||||||
const std::vector<QueryFuncRef>& refs);
|
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(
|
std::vector<QueryLocation> ToQueryLocation(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
const std::vector<QueryFuncRef>& refs);
|
const std::vector<QueryFuncRef>& refs);
|
||||||
@ -62,7 +76,7 @@ optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
|||||||
std::vector<lsLocation> GetLsLocations(
|
std::vector<lsLocation> GetLsLocations(
|
||||||
QueryDatabase* db,
|
QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
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.
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||||
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
|
2
wscript
2
wscript
@ -166,6 +166,8 @@ def configure(ctx):
|
|||||||
cxxflags = ctx.env.CXXFLAGS
|
cxxflags = ctx.env.CXXFLAGS
|
||||||
else:
|
else:
|
||||||
cxxflags = ['-g', '-Wall', '-Wno-sign-compare', '-Werror']
|
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):
|
if all(not x.startswith('-std=') for x in ctx.env.CXXFLAGS):
|
||||||
cxxflags.append('-std=c++11')
|
cxxflags.append('-std=c++11')
|
||||||
|
Loading…
Reference in New Issue
Block a user