diff --git a/src/indexer.h b/src/indexer.h index b9aac681..7ffc6bc7 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -84,6 +84,7 @@ struct Reference { SymbolKind lex_parent_kind; SymbolRole role; + bool HasValue() const { return lex_parent_id.HasValue(); } std::tuple, SymbolKind, SymbolRole> ToTuple() const { return std::make_tuple(range, lex_parent_id, lex_parent_kind, role); } diff --git a/src/messages/cquery_base.cc b/src/messages/cquery_base.cc index d380230f..933842d9 100644 --- a/src/messages/cquery_base.cc +++ b/src/messages/cquery_base.cc @@ -36,17 +36,15 @@ struct CqueryBaseHandler : BaseMessageHandler { for (const SymbolRef& ref : refs) { if (ref.idx.kind == SymbolKind::Type) { QueryType& type = db->types[ref.idx.idx]; - if (!type.def) - continue; - std::vector 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 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; } } diff --git a/src/messages/cquery_call_tree.cc b/src/messages/cquery_call_tree.cc index 7055ffb4..a7fc4a22 100644 --- a/src/messages/cquery_call_tree.cc +++ b/src/messages/cquery_call_tree.cc @@ -84,7 +84,7 @@ std::vector BuildExpandCallTree( auto handle_caller = [&](QueryFuncRef caller, Out_CqueryCallTree::CallType call_type) { optional call_location = - GetLsLocation(db, working_files, caller.loc); + GetLsLocation(db, working_files, caller); if (!call_location) return; @@ -107,7 +107,10 @@ std::vector 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 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); diff --git a/src/messages/cquery_callers.cc b/src/messages/cquery_callers.cc index a6ddda37..bc28c685 100644 --- a/src/messages/cquery_callers.cc +++ b/src/messages/cquery_callers.cc @@ -27,14 +27,12 @@ struct CqueryCallersHandler : BaseMessageHandler { FindSymbolsAtLocation(working_file, file, request->params.position)) { if (ref.idx.kind == SymbolKind::Func) { QueryFunc& func = db->funcs[ref.idx.idx]; - std::vector locations = - ToQueryLocation(db, func.callers); + std::vector 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); diff --git a/src/messages/cquery_derived.cc b/src/messages/cquery_derived.cc index 5019ab15..b914384e 100644 --- a/src/messages/cquery_derived.cc +++ b/src/messages/cquery_derived.cc @@ -36,15 +36,13 @@ struct CqueryDerivedHandler : BaseMessageHandler { for (const SymbolRef& ref : refs) { if (ref.idx.kind == SymbolKind::Type) { QueryType& type = db->types[ref.idx.idx]; - std::vector 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 locations = - ToQueryLocation(db, func.derived); - out.result = GetLsLocations(db, working_files, locations); + out.result = + GetLsLocations(db, working_files, ToReference(db, func.derived)); break; } } diff --git a/src/messages/cquery_vars.cc b/src/messages/cquery_vars.cc index c6521b85..ded4ed0d 100644 --- a/src/messages/cquery_vars.cc +++ b/src/messages/cquery_vars.cc @@ -38,9 +38,8 @@ struct CqueryVarsHandler : BaseMessageHandler { // fallthrough case SymbolKind::Type: { QueryType& type = db->types[id]; - std::vector locations = - ToQueryLocation(db, type.instances); - out.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, + ToReference(db, type.instances)); break; } } diff --git a/src/query.cc b/src/query.cc index 131be632..0f4b2391 100644 --- a/src/query.cc +++ b/src/query.cc @@ -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(primary_file); + break; + case SymbolKind::Func: + ret.lex_parent_id = Id(ToQuery(IndexFuncId(ref.lex_parent_id))); + break; + case SymbolKind::Type: + ret.lex_parent_id = Id(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))); } } diff --git a/src/query.h b/src/query.h index d584c383..94ce95f0 100644 --- a/src/query.h +++ b/src/query.h @@ -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 id, SymbolKind kind, SymbolRole role) + : Reference{range, id, kind, role} {} - bool HasValue() const { return id_.HasValue(); } - - std::tuple 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. diff --git a/src/query_utils.cc b/src/query_utils.cc index 7d79d274..cfdc5ab5 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -188,8 +188,7 @@ std::vector ToReference(QueryDatabase* db, std::vector ret; ret.reserve(refs.size()); for (auto& ref : refs) - ret.push_back(Reference{ref.loc.range, Id(ref.id_), SymbolKind::Func, - ref.loc.role}); + ret.push_back(ref); return ret; } @@ -199,7 +198,7 @@ std::vector ToQueryLocation( std::vector 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 ToQueryLocation( @@ -450,11 +449,11 @@ optional GetLsLocation(QueryDatabase* db, std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files, - const std::vector& locations) { + const std::vector& refs) { std::unordered_set unique_locations; - for (const QueryLocation& query_location : locations) { + for (Reference ref : refs) { optional location = - GetLsLocation(db, working_files, query_location); + GetLsLocation(db, working_files, ref); if (!location) continue; unique_locations.insert(*location); diff --git a/src/query_utils.h b/src/query_utils.h index 09a04c7d..41f58fcf 100644 --- a/src/query_utils.h +++ b/src/query_utils.h @@ -25,6 +25,20 @@ QueryFileId GetFileId(QueryDatabase* db, Reference ref); std::vector ToReference(QueryDatabase* db, const std::vector& refs); + +template +std::vector ToReference(QueryDatabase* db, + const std::vector>& ids) { + std::vector ret; + ret.reserve(ids.size()); + for (auto id : ids) { + optional loc = GetDefinitionSpellingOfSymbol(db, id); + if (loc) + ret.push_back(*loc); + } + return ret; +} + std::vector ToQueryLocation( QueryDatabase* db, const std::vector& refs); @@ -62,7 +76,7 @@ optional GetLsLocation(QueryDatabase* db, std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files, - const std::vector& locations); + const std::vector& refs); // Returns a symbol. The symbol will have *NOT* have a location assigned. optional GetSymbolInfo(QueryDatabase* db, WorkingFiles* working_files, diff --git a/wscript b/wscript index 382ea559..b3235a94 100644 --- a/wscript +++ b/wscript @@ -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')